* [PATCH 1/2] powerpc/dma/raidengine: add raidengine device @ 2012-11-21 9:01 b29237 2012-11-21 9:01 ` [PATCH 2/2] powerpc/dma/raidengine: enable Freescale RaidEngine device b29237 2012-11-25 13:21 ` [PATCH 1/2] powerpc/dma/raidengine: add raidengine device Kumar Gala 0 siblings, 2 replies; 4+ messages in thread From: b29237 @ 2012-11-21 9:01 UTC (permalink / raw) To: dan.j.williams, vinod.koul, linuxppc-dev, linux-kernel Cc: Harninder Rai, Xuelin Shi, Naveen Burmi, iws From: Xuelin Shi <b29237@freescale.com> The RaidEngine is a new Freescale hardware that used for parity computation offloading in RAID5/6. This patch adds the device node in device tree and related binding documentation. Signed-off-by: Harninder Rai <harninder.rai@freescale.com> Signed-off-by: Naveen Burmi <naveenburmi@freescale.com> Signed-off-by: Xuelin Shi <b29237@freescale.com> --- .../devicetree/bindings/powerpc/fsl/raideng.txt | 81 +++++++++++++++++++ arch/powerpc/boot/dts/fsl/p5020si-post.dtsi | 1 + arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi | 6 ++ arch/powerpc/boot/dts/fsl/qoriq-raid1.0-0.dtsi | 85 ++++++++++++++++++++ 4 files changed, 173 insertions(+) create mode 100644 Documentation/devicetree/bindings/powerpc/fsl/raideng.txt create mode 100644 arch/powerpc/boot/dts/fsl/qoriq-raid1.0-0.dtsi diff --git a/Documentation/devicetree/bindings/powerpc/fsl/raideng.txt b/Documentation/devicetree/bindings/powerpc/fsl/raideng.txt new file mode 100644 index 0000000..4ad29b9 --- /dev/null +++ b/Documentation/devicetree/bindings/powerpc/fsl/raideng.txt @@ -0,0 +1,81 @@ +* Freescale 85xx RAID Engine nodes + +RAID Engine nodes are defined to describe on-chip RAID accelerators. Each RAID +Engine should have a separate node. + +Supported chips: +P5020, P5040 + +Required properties: + +- compatible: Should contain "fsl,raideng-v1.0" as the value + This identifies RAID Engine block. 1 in 1.0 represents + major number whereas 0 represents minor number. The + version matches the hardware IP version. +- reg: offset and length of the register set for the device +- ranges: standard ranges property specifying the translation + between child address space and parent address space + +Example: + /* P5020 */ + raideng: raideng@320000 { + compatible = "fsl,raideng-v1.0"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x320000 0x10000>; + ranges = <0 0x320000 0x10000>; + }; + + +There must be a sub-node for each job queue present in RAID Engine +This node must be a sub-node of the main RAID Engine node + +- compatible: Should contain "fsl,raideng-v1.0-job-queue" as the value + This identifies the job queue interface +- reg: offset and length of the register set for job queue +- ranges: standard ranges property specifying the translation + between child address space and parent address space + +Example: + /* P5020 */ + raideng_jq0@1000 { + compatible = "fsl,raideng-v1.0-job-queue"; + reg = <0x1000 0x1000>; + ranges = <0x0 0x1000 0x1000>; + }; + + +There must be a sub-node for each job ring present in RAID Engine +This node must be a sub-node of job queue node + +- compatible: Must contain "fsl,raideng-v1.0-job-ring" as the value + This identifies job ring. Should contain either + "fsl,raideng-v1.0-hp-ring" or "fsl,raideng-v1.0-lp-ring" + depending upon whether ring has high or low priority +- reg: offset and length of the register set for job ring +- interrupts: interrupt mapping for job ring IRQ + +Optional property: + +- fsl,liodn: Specifies the LIODN to be used for Job Ring. This + property is normally set by firmware. Value + is of 12-bits which is the LIODN number for this JR. + This property is used by the IOMMU (PAMU) to distinquish + transactions from this JR and than be able to do address + translation & protection accordingly. + +Example: + /* P5020 */ + raideng_jq0@1000 { + compatible = "fsl,raideng-v1.0-job-queue"; + reg = <0x1000 0x1000>; + ranges = <0x0 0x1000 0x1000>; + + raideng_jr0: jr@0 { + compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-hp-ring"; + reg = <0x0 0x400>; + interrupts = <139 2 0 0>; + interrupt-parent = <&mpic>; + fsl,liodn = <0x41>; + }; + }; diff --git a/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi b/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi index 64b6abe..5d7205b 100644 --- a/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi +++ b/arch/powerpc/boot/dts/fsl/p5020si-post.dtsi @@ -354,4 +354,5 @@ /include/ "qoriq-sata2-0.dtsi" /include/ "qoriq-sata2-1.dtsi" /include/ "qoriq-sec4.2-0.dtsi" +/include/ "qoriq-raid1.0-0.dtsi" }; diff --git a/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi b/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi index 0a198b0..8df47fc 100644 --- a/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi +++ b/arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi @@ -73,6 +73,12 @@ rtic_c = &rtic_c; rtic_d = &rtic_d; sec_mon = &sec_mon; + + raideng = &raideng; + raideng_jr0 = &raideng_jr0; + raideng_jr1 = &raideng_jr1; + raideng_jr2 = &raideng_jr2; + raideng_jr3 = &raideng_jr3; }; cpus { diff --git a/arch/powerpc/boot/dts/fsl/qoriq-raid1.0-0.dtsi b/arch/powerpc/boot/dts/fsl/qoriq-raid1.0-0.dtsi new file mode 100644 index 0000000..8d2e8aa --- /dev/null +++ b/arch/powerpc/boot/dts/fsl/qoriq-raid1.0-0.dtsi @@ -0,0 +1,85 @@ +/* + * QorIQ RAID 1.0 device tree stub [ controller @ offset 0x320000 ] + * + * Copyright 2012 Freescale Semiconductor Inc. + * + * 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 Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + */ + +raideng: raideng@320000 { + compatible = "fsl,raideng-v1.0"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x320000 0x10000>; + ranges = <0 0x320000 0x10000>; + + raideng_jq0@1000 { + compatible = "fsl,raideng-v1.0-job-queue"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x1000 0x1000>; + ranges = <0x0 0x1000 0x1000>; + + raideng_jr0: jr@0 { + compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-hp-ring"; + reg = <0x0 0x400>; + interrupts = <139 2 0 0>; + interrupt-parent = <&mpic>; + }; + + raideng_jr1: jr@400 { + compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-lp-ring"; + reg = <0x400 0x400>; + interrupts = <140 2 0 0>; + interrupt-parent = <&mpic>; + }; + }; + + raideng_jq1@2000 { + compatible = "fsl,raideng-v1.0-job-queue"; + #address-cells = <1>; + #size-cells = <1>; + reg = <0x2000 0x1000>; + ranges = <0x0 0x2000 0x1000>; + + raideng_jr2: jr@0 { + compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-hp-ring"; + reg = <0x0 0x400>; + interrupts = <141 2 0 0>; + interrupt-parent = <&mpic>; + }; + + raideng_jr3: jr@400 { + compatible = "fsl,raideng-v1.0-job-ring", "fsl,raideng-v1.0-lp-ring"; + reg = <0x400 0x400>; + interrupts = <142 2 0 0>; + interrupt-parent = <&mpic>; + }; + }; +}; -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] powerpc/dma/raidengine: enable Freescale RaidEngine device 2012-11-21 9:01 [PATCH 1/2] powerpc/dma/raidengine: add raidengine device b29237 @ 2012-11-21 9:01 ` b29237 2013-04-10 5:07 ` Shi Xuelin-B29237 2012-11-25 13:21 ` [PATCH 1/2] powerpc/dma/raidengine: add raidengine device Kumar Gala 1 sibling, 1 reply; 4+ messages in thread From: b29237 @ 2012-11-21 9:01 UTC (permalink / raw) To: dan.j.williams, vinod.koul, linuxppc-dev, linux-kernel Cc: Harninder Rai, Xuelin Shi, Naveen Burmi, iws From: Xuelin Shi <b29237@freescale.com> The RaidEngine is a new FSL hardware that used as hardware acceration for RAID5/6. This patch enables the RaidEngine functionality and provides hardware offloading capability for memcpy, xor and raid6 pq computation. It works under dmaengine control with async_layer interface. Signed-off-by: Harninder Rai <harninder.rai@freescale.com> Signed-off-by: Naveen Burmi <naveenburmi@freescale.com> Signed-off-by: Xuelin Shi <b29237@freescale.com> --- drivers/dma/Kconfig | 14 + drivers/dma/Makefile | 1 + drivers/dma/fsl_raid.c | 990 ++++++++++++++++++++++++++++++++++++++++++++++++ drivers/dma/fsl_raid.h | 317 ++++++++++++++++ 4 files changed, 1322 insertions(+) create mode 100644 drivers/dma/fsl_raid.c create mode 100644 drivers/dma/fsl_raid.h diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index d4c1218..aa37279 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -320,6 +320,20 @@ config MMP_PDMA help Support the MMP PDMA engine for PXA and MMP platfrom. +config FSL_RAID + tristate "Freescale RAID Engine Device Driver" + depends on FSL_SOC && !FSL_DMA + select DMA_ENGINE + select ASYNC_TX_ENABLE_CHANNEL_SWITCH + select ASYNC_MEMCPY + select ASYNC_XOR + select ASYNC_PQ + ---help--- + Enable support for Freescale RAID Engine. RAID Engine is + available on some QorIQ SoCs (like P5020). It has + the capability to offload RAID5/RAID6 operations from CPU. + RAID5 is XOR and memcpy. RAID6 is P/Q and memcpy + config DMA_ENGINE bool diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 7428fea..29b65eb 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -9,6 +9,7 @@ obj-$(CONFIG_DMATEST) += dmatest.o obj-$(CONFIG_INTEL_IOATDMA) += ioat/ obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o obj-$(CONFIG_FSL_DMA) += fsldma.o +obj-$(CONFIG_FSL_RAID) += fsl_raid.o obj-$(CONFIG_MPC512X_DMA) += mpc512x_dma.o obj-$(CONFIG_MV_XOR) += mv_xor.o obj-$(CONFIG_DW_DMAC) += dw_dmac.o diff --git a/drivers/dma/fsl_raid.c b/drivers/dma/fsl_raid.c new file mode 100644 index 0000000..ec19817 --- /dev/null +++ b/drivers/dma/fsl_raid.c @@ -0,0 +1,990 @@ +/* + * drivers/dma/fsl_raid.c + * + * Freescale RAID Engine device driver + * + * Author: + * Harninder Rai <harninder.rai@freescale.com> + * Naveen Burmi <naveenburmi@freescale.com> + * + * Copyright (c) 2010-2012 Freescale Semiconductor, Inc. + * + * 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 Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + * + * Theory of operation: + * + * General capabilities: + * RAID Engine (RE) block is capable of offloading XOR, memcpy and P/Q + * calculations required in RAID5 and RAID6 operations. RE driver + * registers with Linux's ASYNC layer as dma driver. RE hardware + * maintains strict ordering of the requests through chained + * command queueing. + * + * Data flow: + * Software RAID layer of Linux (MD layer) maintains RAID partitions, + * strips, stripes etc. It sends requests to the underlying AYSNC layer + * which further passes it to RE driver. ASYNC layer decides which request + * goes to which job ring of RE hardware. For every request processed by + * RAID Engine, driver gets an interrupt unless coalescing is set. The + * per job ring interrupt handler checks the status register for errors, + * clears the interrupt and schedules a tasklet. Main request processing + * is done in tasklet. A software shadow copy of the HW ring is kept to + * maintain virtual to physical translation. Based on the internal indexes + * maintained, the tasklet picks the descriptor address from shadow copy, + * updates the corresponding cookie, updates the outbound ring job removed + * register in RE hardware and eventually calls the callback function. This + * callback function gets passed as part of request from MD layer. + */ + +#include <linux/interrupt.h> +#include <linux/module.h> +#include <linux/of_platform.h> +#include <linux/dma-mapping.h> +#include <linux/dmapool.h> +#include <linux/dmaengine.h> +#include <linux/io.h> +#include <linux/spinlock.h> +#include <linux/slab.h> + +#include "fsl_raid.h" + +#define MAX_XOR_SRCS 16 +#define MAX_PQ_SRCS 16 +#define MAX_INITIAL_DESCS 256 +#define FRAME_FORMAT 0x1 +#define MAX_DATA_LENGTH (1024*1024) + +#define to_fsl_re_dma_desc(tx) container_of(tx, \ + struct fsl_re_dma_async_tx_desc, async_tx) + +/* Add descriptors into per jr software queue - submit_q */ +static dma_cookie_t re_jr_tx_submit(struct dma_async_tx_descriptor *tx) +{ + struct fsl_re_dma_async_tx_desc *desc = NULL; + struct re_jr *jr = NULL; + dma_cookie_t cookie; + + desc = container_of(tx, struct fsl_re_dma_async_tx_desc, async_tx); + jr = container_of(tx->chan, struct re_jr, chan); + + spin_lock_bh(&jr->inb_lock); + + jr->timer.data = (unsigned long)tx->chan; + cookie = jr->chan.cookie + 1; + if (cookie < 0) + cookie = 1; + + desc->async_tx.cookie = cookie; + jr->chan.cookie = desc->async_tx.cookie; + jr->pend_count++; + + if (!timer_pending(&jr->timer)) + add_timer(&jr->timer); + + spin_unlock_bh(&jr->inb_lock); + + return cookie; +} + +static void re_jr_unmap_dest_src(struct fsl_re_dma_async_tx_desc *desc) +{ + int i, j; + struct cmpnd_frame *cf; + dma_addr_t dest1 = 0, dest2 = 0, src; + struct device *dev; + enum dma_ctrl_flags flags; + enum dma_data_direction dir; + + BUG_ON(!desc); + cf = desc->cf_addr; + dest1 = cf[1].address; + j = 2; + if (desc->dest_cnt == 2) { + dest2 = cf[2].address; + j = 3; + } + dev = desc->jr->chan.device->dev; + flags = desc->async_tx.flags; + if (!(flags & DMA_COMPL_SKIP_DEST_UNMAP)) { + if (desc->cdb_opcode == RE_MOVE_OPCODE) + dir = DMA_FROM_DEVICE; + else + dir = DMA_BIDIRECTIONAL; + + dma_unmap_page(dev, dest1, desc->dma_len, dir); + + if (dest2) + dma_unmap_page(dev, dest2, desc->dma_len, dir); + } + + if (!(flags & DMA_COMPL_SKIP_SRC_UNMAP)) { + dir = DMA_TO_DEVICE; + for (i = j; i < desc->src_cnt+j; i++) { + src = cf[i].address; + if (src == dest1 || src == dest2) + continue; + dma_unmap_page(dev, src, desc->dma_len, dir); + } + } +} + +static void re_jr_desc_done(struct fsl_re_dma_async_tx_desc *desc) +{ + struct re_jr *dma_jr = desc->jr; + dma_async_tx_callback callback; + void *callback_param; + + callback = desc->async_tx.callback; + callback_param = desc->async_tx.callback_param; + + dma_run_dependencies(&desc->async_tx); + + if (dma_jr->completed_cookie < desc->async_tx.cookie) { + dma_jr->completed_cookie = desc->async_tx.cookie; + if (dma_jr->completed_cookie == DMA_MAX_COOKIE) + dma_jr->completed_cookie = DMA_MIN_COOKIE; + } + + re_jr_unmap_dest_src(desc); + + if (callback) + callback(callback_param); + +} + +/* + * Get the virtual address of software desc from virt_addr. + * Storing the address of software desc like this makes the + * order of alogorithm as O(1) + */ +static void re_jr_dequeue(unsigned long data) +{ + struct device *dev; + struct re_jr *jr; + struct fsl_re_dma_async_tx_desc *desc; + unsigned int count; + struct fsl_re_dma_async_tx_desc *ack_desc = NULL, *_ack_desc = NULL; + + dev = (struct device *)data; + jr = dev_get_drvdata(dev); + + while ((count = + RE_JR_OUB_SLOT_FULL(in_be32(&jr->jrregs->oubring_slot_full)))) { + while (count--) { + spin_lock_bh(&jr->oub_lock); + jr->oub_count &= RING_SIZE - 1; + desc = &jr->descs[jr->oub_count++]; + + /* One job processed */ + out_be32(&jr->jrregs->oubring_job_rmvd, + RE_JR_OUB_JOB_REMOVE(1)); + spin_unlock_bh(&jr->oub_lock); + + spin_lock_bh(&jr->desc_lock); + list_add_tail(&desc->node, &jr->ack_q); + re_jr_desc_done(desc); + spin_unlock_bh(&jr->desc_lock); + } + } + + /* To save memory, parse the ack_q and free up descs */ + list_for_each_entry_safe(ack_desc, _ack_desc, &jr->ack_q, node) { + if (async_tx_test_ack(&ack_desc->async_tx)) { + spin_lock_bh(&jr->desc_lock); + list_del(&ack_desc->node); + ack_desc->state = RE_DESC_EMPTY; + ack_desc->async_tx.flags = 0; + spin_unlock_bh(&jr->desc_lock); + } + } +} + +/* Per Job Ring interrupt handler */ +static irqreturn_t re_jr_interrupt(int irq, void *data) +{ + struct device *dev = data; + struct re_jr *jr = dev_get_drvdata(dev); + u32 irqstate, status; + + irqstate = in_be32(&jr->jrregs->jr_interrupt_status); + if (!irqstate) + return IRQ_NONE; + + /* + * There's no way in upper layer (read MD layer) to recover from + * error conditions except restart everything. In long term we + * need to do something more than just crashing + */ + if (irqstate & RE_JR_ERROR) { + status = in_be32(&jr->jrregs->jr_status); + dev_err(dev, "%s: jr error irqstate: %x, status: %x\n", + __func__, irqstate, status); + + BUG(); + } + + /* Clear interrupt */ + out_be32(&jr->jrregs->jr_interrupt_status, RE_JR_CLEAR_INT); + + tasklet_schedule(&jr->irqtask); + + return IRQ_HANDLED; +} + +static enum dma_status re_jr_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, struct dma_tx_state *txstate) +{ + struct re_jr *jr = NULL; + dma_cookie_t last_used; + dma_cookie_t last_complete; + + jr = container_of(chan, struct re_jr, chan); + last_used = chan->cookie; + smp_mb(); + last_complete = jr->completed_cookie; + + dma_set_tx_state(txstate, last_complete, last_used, 0); + + return dma_async_is_complete(cookie, last_complete, last_used); +} + + +/* Copy descriptor from per jr software queue into hardware job ring */ +void re_jr_issue_pending(struct dma_chan *chan) +{ + struct re_jr *jr = NULL; + int avail = 0; + + jr = container_of(chan, struct re_jr, chan); + if (timer_pending(&jr->timer)) + del_timer_sync(&jr->timer); + + spin_lock_bh(&jr->inb_lock); + + avail = RE_JR_INB_SLOT_AVAIL(in_be32(&jr->jrregs->inbring_slot_avail)); + + if (!(avail && jr->pend_count)) + goto out_unlock; + + if (avail > jr->pend_count) + avail = jr->pend_count; + + jr->pend_count -= avail; + jr->inb_count = (jr->inb_count + avail) & (RING_SIZE - 1); + + /* add jobs into job ring */ + out_be32(&jr->jrregs->inbring_add_job, RE_JR_INB_JOB_ADD(avail)); + +out_unlock: + spin_unlock_bh(&jr->inb_lock); +} + +/* Per Job Ring timer handler */ +static void raide_timer_handler(unsigned long data) +{ + struct dma_chan *chan = NULL; + chan = (struct dma_chan *)data; + + re_jr_issue_pending(chan); + + return; +} + +inline void fill_cfd_frame(struct cmpnd_frame *cf, u8 index, + size_t length, dma_addr_t addr, bool final) +{ + cf[index].final = final; + cf[index].length = length; + cf[index].address = addr; +} + +static struct fsl_re_dma_async_tx_desc *re_jr_init_desc(struct re_jr *jr, + struct fsl_re_dma_async_tx_desc *desc, void *cf, dma_addr_t paddr) +{ + desc->jr = jr; + desc->async_tx.tx_submit = re_jr_tx_submit; + dma_async_tx_descriptor_init(&desc->async_tx, &jr->chan); + INIT_LIST_HEAD(&desc->node); + + desc->hwdesc->format = FRAME_FORMAT; + desc->hwdesc->address = paddr; + desc->cf_addr = cf; + + desc->cdb_addr = (void *)(cf + RE_CF_DESC_SIZE); + desc->cdb_paddr = paddr + RE_CF_DESC_SIZE; + + return desc; +} + +static struct fsl_re_dma_async_tx_desc *re_jr_alloc_desc(struct re_jr *jr, + unsigned long flags) +{ + struct fsl_re_dma_async_tx_desc *desc; + + spin_lock_bh(&jr->inb_lock); + + jr->inb_count &= RING_SIZE - 1; + desc = &jr->descs[jr->inb_count]; + + if (desc->state != RE_DESC_EMPTY) { + spin_unlock_bh(&jr->inb_lock); + re_jr_issue_pending(&jr->chan); + return NULL; + } + spin_unlock_bh(&jr->inb_lock); + + desc->state = RE_DESC_ALLOC; + desc->async_tx.flags = flags; + return desc; +} + +static struct dma_async_tx_descriptor *re_jr_prep_genq( + struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src, + unsigned int src_cnt, const unsigned char *scf, size_t len, + unsigned long flags) +{ + struct re_jr *jr = NULL; + struct fsl_re_dma_async_tx_desc *desc = NULL; + struct xor_cdb *xor = NULL; + struct cmpnd_frame *cf; + unsigned int i = 0; + unsigned int j = 0; + + if (len > MAX_DATA_LENGTH) { + pr_err("%s: Length greater than %d not supported\n", + __func__, MAX_DATA_LENGTH); + return NULL; + } + jr = container_of(chan, struct re_jr, chan); + desc = re_jr_alloc_desc(jr, flags); + if (!desc || desc < 0) + return NULL; + + desc->dma_len = len; + desc->dest_cnt = 1; + desc->src_cnt = src_cnt; + + desc->cdb_opcode = RE_XOR_OPCODE; + desc->cdb_len = sizeof(struct xor_cdb); + + /* Filling xor CDB */ + xor = desc->cdb_addr; + xor->opcode = RE_XOR_OPCODE; + xor->nrcs = (src_cnt - 1); + xor->blk_size = RE_BLOCK_SIZE; + xor->error_attrib = INTERRUPT_ON_ERROR; + xor->data_depend = DATA_DEPENDENCY; + + if (scf != NULL) { + /* compute q = src0*coef0^src1*coef1^..., * is GF(8) mult */ + for (i = 0; i < src_cnt; i++) + xor->gfm[i] = scf[i]; + } else { + /* compute P, that is XOR all srcs */ + for (i = 0; i < src_cnt; i++) + xor->gfm[i] = 1; + } + + /* Filling frame 0 of compound frame descriptor with CDB */ + cf = desc->cf_addr; + fill_cfd_frame(cf, 0, desc->cdb_len, desc->cdb_paddr, 0); + + /* Fill CFD's 1st frame with dest buffer */ + fill_cfd_frame(cf, 1, len, dest, 0); + + /* Fill CFD's rest of the frames with source buffers */ + for (i = 2, j = 0; j < src_cnt; i++, j++) + fill_cfd_frame(cf, i, len, src[j], 0); + + /* Setting the final bit in the last source buffer frame in CFD */ + cf[i - 1].final = 1; + + return &desc->async_tx; +} + +/* + * Prep function for P parity calculation.In RAID Engine terminology, + * XOR calculation is called GenQ calculation done through GenQ command + */ +static struct dma_async_tx_descriptor *re_jr_prep_dma_xor( + struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src, + unsigned int src_cnt, size_t len, unsigned long flags) +{ + /* NULL let genq take all coef as 1 */ + return re_jr_prep_genq(chan, dest, src, src_cnt, NULL, len, flags); +} + +/* + * Prep function for P/Q parity calculation.In RAID Engine terminology, + * P/Q calculation is called GenQQ done through GenQQ command + */ +static struct dma_async_tx_descriptor *re_jr_prep_pq( + struct dma_chan *chan, dma_addr_t *dest, dma_addr_t *src, + unsigned int src_cnt, const unsigned char *scf, size_t len, + unsigned long flags) +{ + struct re_jr *jr = NULL; + struct fsl_re_dma_async_tx_desc *desc = NULL; + struct pq_cdb *pq = NULL; + struct cmpnd_frame *cf; + u8 *p; + int gfmq_len, i, j; + + if (len > MAX_DATA_LENGTH) { + pr_err("%s: Length greater than %d not supported\n", + __func__, MAX_DATA_LENGTH); + return NULL; + } + + /* + * RE requires at least 2 sources, if given only one source, we pass the + * second source same as the first one. + * With only one source, generate P is meaningless, only care Q. + */ + if (src_cnt == 1) { + struct dma_async_tx_descriptor *tx = NULL; + dma_addr_t dma_src[2]; + unsigned char coef[2]; + dma_src[0] = *src; + coef[0] = *scf; + dma_src[1] = *src; + coef[1] = 0; + tx = re_jr_prep_genq(chan, dest[1], dma_src, 2, coef, len, + flags); + if (tx) { + desc = to_fsl_re_dma_desc(tx); + desc->src_cnt = 1; + } + return tx; + } + + /* + * During RAID6 array creation, Linux's MD layer gets P and Q + * calculated separately in two steps. But our RAID Engine has + * the capability to calculate both P and Q with a single command + * Hence to merge well with MD layer, we need to provide a hook + * here and call re_jq_prep_genq() function + */ + + if (flags & DMA_PREP_PQ_DISABLE_P) + return re_jr_prep_genq(chan, dest[1], src, src_cnt, + scf, len, flags); + + jr = container_of(chan, struct re_jr, chan); + desc = re_jr_alloc_desc(jr, flags); + if (!desc || desc < 0) + return NULL; + + desc->dma_len = len; + desc->dest_cnt = 2; + desc->src_cnt = src_cnt; + + desc->cdb_opcode = RE_PQ_OPCODE; + desc->cdb_len = sizeof(struct pq_cdb); + + /* Filling GenQQ CDB */ + pq = desc->cdb_addr; + pq->opcode = RE_PQ_OPCODE; + pq->blk_size = RE_BLOCK_SIZE; + pq->buffer_attrib = BUFFERABLE_OUTPUT; + pq->data_depend = DATA_DEPENDENCY; + pq->nrcs = (src_cnt - 1); + + p = pq->gfm_q1; + /* Init gfm_q1[] */ + for (i = 0; i < src_cnt; i++) + p[i] = 1; + + /* Align gfm[] to 32bit */ + gfmq_len = ((src_cnt+3)/4)*4; + + /* Init gfm_q2[] */ + p += gfmq_len; + for (i = 0; i < src_cnt; i++) + p[i] = scf[i]; + + /* Filling frame 0 of compound frame descriptor with CDB */ + cf = desc->cf_addr; + fill_cfd_frame(cf, 0, desc->cdb_len, desc->cdb_paddr, 0); + + /* Fill CFD's 1st & 2nd frame with dest buffers */ + for (i = 1, j = 0; i < 3; i++, j++) + fill_cfd_frame(cf, i, len, dest[j], 0); + + /* Fill CFD's rest of the frames with source buffers */ + for (i = 3, j = 0; j < src_cnt; i++, j++) + fill_cfd_frame(cf, i, len, src[j], 0); + + /* Setting the final bit in the last source buffer frame in CFD */ + cf[i - 1].final = 1; + + return &desc->async_tx; +} + +/* + * Prep function for memcpy. In RAID Engine, memcpy is done through MOVE + * command. Logic of this function will need to be modified once multipage + * support is added in Linux's MD/ASYNC Layer + */ +static struct dma_async_tx_descriptor *re_jr_prep_memcpy( + struct dma_chan *chan, dma_addr_t dest, dma_addr_t src, + size_t len, unsigned long flags) +{ + struct re_jr *jr = NULL; + struct fsl_re_dma_async_tx_desc *desc = NULL; + size_t length = 0; + struct cmpnd_frame *cf = NULL; + struct move_cdb *move = NULL; + + jr = container_of(chan, struct re_jr, chan); + + if (len > MAX_DATA_LENGTH) { + pr_err("%s: Length greater than %d not supported\n", + __func__, MAX_DATA_LENGTH); + return NULL; + } + + desc = re_jr_alloc_desc(jr, flags); + if (!desc || desc < 0) + return NULL; + + desc->dma_len = len; + desc->src_cnt = 1; + desc->dest_cnt = 1; + + desc->cdb_opcode = RE_MOVE_OPCODE; + desc->cdb_len = sizeof(struct move_cdb); + + /* Filling move CDB */ + move = desc->cdb_addr; + move->opcode = RE_MOVE_OPCODE; /* Unicast move */ + move->blk_size = RE_BLOCK_SIZE; + move->error_attrib = INTERRUPT_ON_ERROR; + move->data_depend = DATA_DEPENDENCY; + + /* Filling frame 0 of CFD with move CDB */ + cf = desc->cf_addr; + fill_cfd_frame(cf, 0, desc->cdb_len, desc->cdb_paddr, 0); + + length = min_t(size_t, len, MAX_DATA_LENGTH); + + /* Fill CFD's 1st frame with dest buffer */ + fill_cfd_frame(cf, 1, length, dest, 0); + + /* Fill CFD's 2nd frame with src buffer */ + fill_cfd_frame(cf, 2, length, src, 1); + + return &desc->async_tx; +} + +static int re_jr_alloc_chan_resources(struct dma_chan *chan) +{ + int i; + struct fsl_re_dma_async_tx_desc *desc; + struct re_jr *jr = container_of(chan, struct re_jr, chan); + void *cf = NULL; + dma_addr_t paddr; + + jr->descs = kzalloc(sizeof(*desc) * RING_SIZE, GFP_KERNEL); + if (!jr->descs) { + dev_err(jr->dev, "%s: No memory for sw descriptor ring\n", + __func__); + goto err_free; + } + + cf = dma_pool_alloc(jr->re_dev->desc_pool, GFP_ATOMIC, &paddr); + if (!cf) { + dev_err(jr->dev, "%s: No memory for dma descriptor ring\n", + __func__); + goto err_free; + } + memset(cf, 0, RE_CF_CDB_SIZE * RING_SIZE); + jr->cfs = cf; + jr->phys = paddr; + + for (i = 0; i < RING_SIZE; i++) { + u32 offset = i * RE_CF_CDB_SIZE; + desc = &jr->descs[i]; + desc->hwdesc = &jr->inb_ring_virt_addr[i]; + re_jr_init_desc(jr, desc, cf + offset, paddr + offset); + desc->state = RE_DESC_EMPTY; + } + return 0; + +err_free: + kfree(jr->descs); + return -ENOMEM; +} + +static void re_jr_free_chan_resources(struct dma_chan *chan) +{ + struct re_jr *jr = container_of(chan, struct re_jr, chan); + dma_pool_free(jr->re_dev->desc_pool, jr->cfs, jr->phys); + kfree(jr->descs); + return; +} + +int re_jr_probe(struct platform_device *ofdev, + struct device_node *np, u8 q, u32 *off) +{ + struct device *dev = NULL; + struct re_drv_private *repriv = NULL; + struct re_jr *jr = NULL; + struct dma_device *dma_dev = NULL; + u32 *ptr = NULL; + u32 status; + int ret = 0; + struct platform_device *jr_ofdev = NULL; + + dev = &ofdev->dev; + repriv = dev_get_drvdata(dev); + dma_dev = &repriv->dma_dev; + + jr = kzalloc(sizeof(struct re_jr), GFP_KERNEL); + if (!jr) { + dev_err(dev, "%s: No free memory for allocating JR struct\n", + __func__); + return -ENOMEM; + } + + jr_ofdev = of_platform_device_create(np, NULL, dev); + if (jr_ofdev == NULL) { + dev_err(dev, "%s: Not able to create ofdev for jr %d\n", + __func__, q); + ret = -EINVAL; + goto err_free; + } + dev_set_drvdata(&jr_ofdev->dev, jr); + + ptr = (u32 *)of_get_property(np, "reg", NULL); + if (!ptr) { + dev_err(dev, "%s: Reg property not found in JR number %d\n", + __func__, q); + ret = -ENODEV; + goto err_free; + } + + jr->jrregs = (struct jr_config_regs *)((u8 *)repriv->re_regs + + *off + *ptr); + + jr->irq = irq_of_parse_and_map(np, 0); + if (jr->irq == NO_IRQ) { + dev_err(dev, "%s: No IRQ defined for JR %d\n", __func__, q); + ret = -ENODEV; + goto err_free; + } + + tasklet_init(&jr->irqtask, re_jr_dequeue, + (unsigned long)&jr_ofdev->dev); + + ret = request_irq(jr->irq, re_jr_interrupt, 0, "re-jr", &jr_ofdev->dev); + if (ret) { + dev_err(dev, "%s: Unable to register JR interrupt for JR %d\n", + __func__, q); + ret = -EINVAL; + goto err_free; + } + + repriv->re_jrs[q] = jr; + jr->chan.device = dma_dev; + jr->chan.private = jr; + jr->dev = &jr_ofdev->dev; + jr->re_dev = repriv; + jr->pend_count = 0; + INIT_LIST_HEAD(&jr->ack_q); + spin_lock_init(&jr->desc_lock); + spin_lock_init(&jr->inb_lock); + spin_lock_init(&jr->oub_lock); + + init_timer(&jr->timer); + jr->timer.expires = jiffies + 10*HZ; + jr->timer.function = raide_timer_handler; + + list_add_tail(&jr->chan.device_node, &dma_dev->channels); + dma_dev->chancnt++; + + jr->inb_ring_virt_addr = dma_pool_alloc(jr->re_dev->hw_desc_pool, + GFP_ATOMIC, &jr->inb_phys_addr); + + if (!jr->inb_ring_virt_addr) { + dev_err(dev, "%s:No dma memory for inb_ring_virt_addr\n", + __func__); + ret = -ENOMEM; + goto err_free; + } + + jr->oub_ring_virt_addr = dma_pool_alloc(jr->re_dev->hw_desc_pool, + GFP_ATOMIC, &jr->oub_phys_addr); + + if (!jr->oub_ring_virt_addr) { + dev_err(dev, "%s:No dma memory for oub_ring_virt_addr\n", + __func__); + ret = -ENOMEM; + goto err_free; + } + + jr->inb_count = 0; + jr->pend_count = 0; + jr->oub_count = 0; + + status = in_be32(&jr->jrregs->jr_status); + + if (status & RE_JR_PAUSE) { + dev_info(dev, "%s: JR is in paused state...enable it\n", + __func__); + } else { + dev_err(dev, "%s: Error:- JR shud be in paused state\n", + __func__); + ret = -EINVAL; + goto pool_free; + } + + /* Program the Inbound/Outbound ring base addresses and size */ + out_be32(&jr->jrregs->inbring_base_h, + jr->inb_phys_addr & RE_JR_ADDRESS_BIT_MASK); + out_be32(&jr->jrregs->oubring_base_h, + jr->oub_phys_addr & RE_JR_ADDRESS_BIT_MASK); + out_be32(&jr->jrregs->inbring_base_l, + jr->inb_phys_addr >> RE_JR_ADDRESS_BIT_SHIFT); + out_be32(&jr->jrregs->oubring_base_l, + jr->oub_phys_addr >> RE_JR_ADDRESS_BIT_SHIFT); + out_be32(&jr->jrregs->inbring_size, RING_SIZE << RING_SIZE_SHIFT); + out_be32(&jr->jrregs->oubring_size, RING_SIZE << RING_SIZE_SHIFT); + + /* Read LIODN value from u-boot */ + status = in_be32(&jr->jrregs->jr_config_1) & RE_JR_REG_LIODN_MASK; + + /* Program the CFG reg */ + out_be32(&jr->jrregs->jr_config_1, + RE_JR_CFG1_CBSI | RE_JR_CFG1_CBS0 | status); + + /* Enable RE/JR */ + out_be32(&jr->jrregs->jr_command, RE_JR_ENABLE); + + return 0; + +pool_free: + dma_pool_free(jr->re_dev->hw_desc_pool, jr->inb_ring_virt_addr, + jr->inb_phys_addr); +err_free: + kfree(jr); + return ret; +} + +/* Probe function for RAID Engine */ +static int __devinit raide_probe(struct platform_device *ofdev) +{ + struct re_drv_private *repriv = NULL; + struct device *dev = NULL; + struct device_node *np = NULL; + struct device_node *child = NULL; + u32 *off = NULL; + u8 ridx = 0; + struct dma_device *dma_dev = NULL; + int ret = 0; + + dev_info(&ofdev->dev, "Freescale RAID Engine driver\n"); + + repriv = kzalloc(sizeof(struct re_drv_private), GFP_KERNEL); + if (!repriv) { + dev_err(dev, "%s: No memory for repriv\n", __func__); + return -ENOMEM; + } + + dev = &ofdev->dev; + dev_set_drvdata(dev, repriv); + + /* IOMAP the entire RAID Engine region */ + repriv->re_regs = of_iomap(ofdev->dev.of_node, 0); + if (repriv->re_regs == NULL) { + dev_err(dev, "%s: of_iomap failed\n", __func__); + kfree(repriv); + ret = -ENOMEM; + goto err_free_4; + } + + /* Print the RE version to make sure RE is alive */ + dev_info(dev, "Ver = %x\n", in_be32(&repriv->re_regs->re_version_id)); + + /* Program the RE mode */ + out_be32(&repriv->re_regs->global_config, RE_NON_DPAA_MODE); + dev_info(dev, "%s:RE mode is %x\n", __func__, + in_be32(&repriv->re_regs->global_config)); + + /* Program Galois Field polynomial */ + out_be32(&repriv->re_regs->galois_field_config, RE_GFM_POLY); + dev_info(dev, "%s:Galois Field Polynomial is %x\n", __func__, + in_be32(&repriv->re_regs->galois_field_config)); + + dma_dev = &repriv->dma_dev; + dma_dev->dev = dev; + INIT_LIST_HEAD(&dma_dev->channels); + dma_set_mask(dev, DMA_BIT_MASK(40)); + + dma_dev->device_alloc_chan_resources = re_jr_alloc_chan_resources; + dma_dev->device_tx_status = re_jr_tx_status; + dma_dev->device_issue_pending = re_jr_issue_pending; + + dma_dev->max_xor = MAX_XOR_SRCS; + dma_dev->device_prep_dma_xor = re_jr_prep_dma_xor; + dma_cap_set(DMA_XOR, dma_dev->cap_mask); + + dma_dev->max_pq = MAX_PQ_SRCS; + dma_dev->device_prep_dma_pq = re_jr_prep_pq; + dma_cap_set(DMA_PQ, dma_dev->cap_mask); + + dma_dev->device_prep_dma_memcpy = re_jr_prep_memcpy; + dma_cap_set(DMA_MEMCPY, dma_dev->cap_mask); + + dma_dev->device_free_chan_resources = re_jr_free_chan_resources; + + repriv->total_jrs = 0; + + repriv->desc_pool = dma_pool_create("re_dma_desc_pool", dev, + RE_CF_CDB_SIZE * RING_SIZE, + RE_CF_CDB_ALIGN, 0); + + if (!repriv->desc_pool) { + pr_err("%s:No memory for dma desc pool\n", __func__); + ret = -ENOMEM; + goto err_free_3; + } + + repriv->hw_desc_pool = dma_pool_create("re_hw_desc_pool", dev, + sizeof(struct jr_hw_desc) * RING_SIZE, + FRAME_DESC_ALIGNMENT, 0); + if (!repriv->hw_desc_pool) { + pr_err("%s:No memory for hw desc pool\n", __func__); + ret = -ENOMEM; + goto err_free_2; + } + + /* Parse Device tree to find out the total number of JQs present */ + for_each_compatible_node(np, NULL, "fsl,raideng-v1.0-job-queue") { + off = (u32 *)of_get_property(np, "reg", NULL); + if (!off) { + dev_err(dev, "%s: Reg property not found in JQ node\n", + __func__); + return -ENODEV; + } + + /* Find out the Job Rings present under each JQ */ + for_each_child_of_node(np, child) { + if (of_device_is_compatible(child, + "fsl,raideng-v1.0-job-ring")) { + re_jr_probe(ofdev, child, ridx++, off); + repriv->total_jrs++; + } + } + } + + dma_async_device_register(dma_dev); + return 0; + +err_free_2: + dma_pool_destroy(repriv->desc_pool); +err_free_3: + iounmap(repriv->re_regs); +err_free_4: + kfree(repriv); + + return ret; +} + +static void release_jr(struct re_jr *jr) +{ + /* Free the memory allocated from DMA pools and destroy them */ + dma_pool_free(jr->re_dev->hw_desc_pool, jr->inb_ring_virt_addr, + jr->inb_phys_addr); + kfree(jr); +} + +static int raide_remove(struct platform_device *ofdev) +{ + struct re_drv_private *repriv = NULL; + struct device *dev = NULL; + int i; + + dev = &ofdev->dev; + repriv = dev_get_drvdata(dev); + + /* Cleanup JR related memory areas */ + for (i = 0; i < repriv->total_jrs; i++) + release_jr(repriv->re_jrs[i]); + + dma_pool_destroy(repriv->hw_desc_pool); + dma_pool_destroy(repriv->desc_pool); + + /* Unregister the driver */ + dma_async_device_unregister(&repriv->dma_dev); + + /* Unmap the RAID Engine region */ + iounmap(repriv->re_regs); + + kfree(repriv); + + return 0; +} + +static struct of_device_id raide_ids[] = { + { .compatible = "fsl,raideng-v1.0", }, + {} +}; + +static struct platform_driver raide_driver = { + .driver = { + .name = "fsl-raideng", + .owner = THIS_MODULE, + .of_match_table = raide_ids, + }, + .probe = raide_probe, + .remove = raide_remove, +}; + +static __init int raide_init(void) +{ + int ret = 0; + + ret = platform_driver_register(&raide_driver); + if (ret) + pr_err("fsl-raid: Failed to register platform driver\n"); + + return ret; +} + +static void __exit raide_exit(void) +{ + platform_driver_unregister(&raide_driver); +} + +subsys_initcall(raide_init); +module_exit(raide_exit); + +MODULE_AUTHOR("Harninder Rai <harninder.rai@freescale.com>"); +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("Freescale RAID Engine Device Driver"); diff --git a/drivers/dma/fsl_raid.h b/drivers/dma/fsl_raid.h new file mode 100644 index 0000000..3cb8454 --- /dev/null +++ b/drivers/dma/fsl_raid.h @@ -0,0 +1,317 @@ +/* + * drivers/dma/fsl_raid.h + * + * Freescale RAID Engine device driver + * + * Author: + * Harninder Rai <harninder.rai@freescale.com> + * Naveen Burmi <naveenburmi@freescale.com> + * + * Copyright (c) 2010-2012 Freescale Semiconductor, Inc. + * + * 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 Freescale Semiconductor nor the + * names of its contributors may be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * ALTERNATIVELY, this software may be distributed under the terms of the + * GNU General Public License ("GPL") as published by the Free Software + * Foundation, either version 2 of that License or (at your option) any + * later version. + * + * THIS SOFTWARE IS PROVIDED BY Freescale Semiconductor ``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 Freescale Semiconductor 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. + * + */ + +#define RE_DPAA_MODE (1 << 30) +#define RE_NON_DPAA_MODE (1 << 31) +#define RE_GFM_POLY (0x1d000000) +#define RE_JR_INB_JOB_ADD(x) ((x) << 16) +#define RE_JR_OUB_JOB_REMOVE(x) ((x) << 16) +#define RE_JR_CFG1_CBSI 0x08000000 +#define RE_JR_CFG1_CBS0 0x00080000 +#define RE_JR_OUB_SLOT_FULL_SHIFT 8 +#define RE_JR_OUB_SLOT_FULL(x) ((x) >> RE_JR_OUB_SLOT_FULL_SHIFT) +#define RE_JR_INB_SLOT_AVAIL_SHIFT 8 +#define RE_JR_INB_SLOT_AVAIL(x) ((x) >> RE_JR_INB_SLOT_AVAIL_SHIFT) +#define RE_PQ_OPCODE 0x1B +#define RE_XOR_OPCODE 0x1A +#define RE_MOVE_OPCODE 0x8 +#define FRAME_DESC_ALIGNMENT 16 +#define RE_BLOCK_SIZE 0x3 /* 4096 bytes */ +#define CACHEABLE_INPUT_OUTPUT 0x0 +#define BUFFERABLE_OUTPUT 0x0 +#define INTERRUPT_ON_ERROR 0x1 +#define DATA_DEPENDENCY 0x1 +#define ENABLE_DPI 0x0 +#define RING_SIZE 0x1000 +#define RING_SIZE_SHIFT 8 +#define RE_JR_ADDRESS_BIT_SHIFT 4 +#define RE_JR_ADDRESS_BIT_MASK ((1 << RE_JR_ADDRESS_BIT_SHIFT) - 1) +#define RE_JR_ERROR 0x40000000 +#define RE_JR_INTERRUPT 0x80000000 +#define RE_JR_CLEAR_INT 0x80000000 +#define RE_JR_PAUSE 0x80000000 +#define RE_JR_ENABLE 0x80000000 + +#define RE_JR_REG_LIODN_MASK 0x00000fff +#define RE_CF_CDB_ALIGN 64 +/* + * the largest cf block is 19*sizeof(struct cmpnd_frame), which is 304 bytes. + * here 19 = 1(cdb)+2(dest)+16(src), align to 64bytes, that is 320 bytes. + * the largest cdb block: struct pq_cdb which is 180 bytes, adding to cf block + * 320+180=500, align to 64bytes, that is 512 bytes. + */ +#define RE_CF_DESC_SIZE 320 +#define RE_CF_CDB_SIZE 512 + +struct re_ctrl { + /* General Configuration Registers */ + __be32 global_config; /* Global Configuration Register */ + u8 rsvd1[4]; + __be32 galois_field_config; /* Galois Field Configuration Register */ + u8 rsvd2[4]; + __be32 jq_wrr_config; /* WRR Configuration register */ + u8 rsvd3[4]; + __be32 crc_config; /* CRC Configuration register */ + u8 rsvd4[228]; + __be32 system_reset; /* System Reset Register */ + u8 rsvd5[252]; + __be32 global_status; /* Global Status Register */ + u8 rsvd6[832]; + __be32 re_liodn_base; /* LIODN Base Register */ + u8 rsvd7[1712]; + __be32 re_version_id; /* Version ID register of RE */ + __be32 re_version_id_2; /* Version ID 2 register of RE */ + u8 rsvd8[512]; + __be32 host_config; /* Host I/F Configuration Register */ +}; + +struct jr_config_regs { + /* Registers for JR interface */ + __be32 jr_config_0; /* Job Queue Configuration 0 Register */ + __be32 jr_config_1; /* Job Queue Configuration 1 Register */ + __be32 jr_interrupt_status; /* Job Queue Interrupt Status Register */ + u8 rsvd1[4]; + __be32 jr_command; /* Job Queue Command Register */ + u8 rsvd2[4]; + __be32 jr_status; /* Job Queue Status Register */ + u8 rsvd3[228]; + + /* Input Ring */ + __be32 inbring_base_h; /* Inbound Ring Base Address Register - High */ + __be32 inbring_base_l; /* Inbound Ring Base Address Register - Low */ + __be32 inbring_size; /* Inbound Ring Size Register */ + u8 rsvd4[4]; + __be32 inbring_slot_avail; /* Inbound Ring Slot Available Register */ + u8 rsvd5[4]; + __be32 inbring_add_job; /* Inbound Ring Add Job Register */ + u8 rsvd6[4]; + __be32 inbring_cnsmr_indx; /* Inbound Ring Consumer Index Register */ + u8 rsvd7[220]; + + /* Output Ring */ + __be32 oubring_base_h; /* Outbound Ring Base Address Register - High */ + __be32 oubring_base_l; /* Outbound Ring Base Address Register - Low */ + __be32 oubring_size; /* Outbound Ring Size Register */ + u8 rsvd8[4]; + __be32 oubring_job_rmvd; /* Outbound Ring Job Removed Register */ + u8 rsvd9[4]; + __be32 oubring_slot_full; /* Outbound Ring Slot Full Register */ + u8 rsvd10[4]; + __be32 oubring_prdcr_indx; /* Outbound Ring Producer Index */ +}; + +/* + * Command Descriptor Block (CDB) for unicast move command. + * In RAID Engine terms, memcpy is done through move command + */ +struct move_cdb { + u32 opcode:5; + u32 rsvd1:11; + u32 blk_size:2; + u32 cache_attrib:2; + u32 buffer_attrib:1; + u32 error_attrib:1; + u32 rsvd2:6; + u32 data_depend:1; + u32 dpi:1; + u32 rsvd3:2; +} __packed; + +/* Data protection/integrity related fields */ +struct dpi_related { + u32 apps_mthd:2; + u32 ref_mthd:2; + u32 guard_mthd:2; + u32 dpi_attr:2; + u32 rsvd1:8; + u32 meta_tag:16; + u32 ref_tag:32; +} __packed; + +/* + * CDB for GenQ command. In RAID Engine terminology, XOR is + * done through this command + */ +struct xor_cdb { + u32 opcode:5; + u32 rsvd1:11; + u32 blk_size:2; + u32 cache_attrib:2; + u32 buffer_attrib:1; + u32 error_attrib:1; + u32 nrcs:4; + u32 rsvd2:2; + u32 data_depend:1; + u32 dpi:1; + u32 rsvd3:2; + u8 gfm[16]; + struct dpi_related dpi_dest_spec; + struct dpi_related dpi_src_spec[16]; +} __packed; + +/* CDB for no-op command */ +struct noop_cdb { + u32 opcode:5; + u32 rsvd1:23; + u32 dependency:1; + u32 rsvd2:3; +} __packed; + +/* + * CDB for GenQQ command. In RAID Engine terminology, P/Q is + * done through this command + */ +struct pq_cdb { + u32 opcode:5; + u32 rsvd1:1; + u32 excl_enable:2; + u32 excl_q1:4; + u32 excl_q2:4; + u32 blk_size:2; + u32 cache_attrib:2; + u32 buffer_attrib:1; + u32 error_attrib:1; + u32 nrcs:4; + u32 rsvd2:2; + u32 data_depend:1; + u32 dpi:1; + u32 rsvd3:2; + u8 gfm_q1[16]; + u8 gfm_q2[16]; + struct dpi_related dpi_dest_spec[2]; + struct dpi_related dpi_src_spec[16]; +} __packed; + +/* Compound frame */ +struct cmpnd_frame { + u64 rsvd1:24; + u64 address:40; + u32 extension:1; + u32 final:1; + u32 rsvd3:10; + u32 length:20; + u32 rsvd4:8; + u32 bpid:8; + u32 rsvd5:3; + u32 offset:13; +} __packed; + +/* Frame descriptor */ +struct jr_hw_desc { + u64 debug:2; + u64 liodn_off:6; + u64 bpid:8; + u64 eliodn_off:4; + u64 rsvd1:4; + u64 address:40; + u64 format:3; + u64 rsvd2:29; + u64 status:32; +} __packed; + +#define MAX_RE_JRS 4 + +/* Raid Engine device private data */ +struct re_drv_private { + u8 total_jrs; + struct dma_device dma_dev; + struct re_ctrl *re_regs; + struct re_jr *re_jrs[MAX_RE_JRS]; + struct dma_pool *desc_pool; + struct dma_pool *hw_desc_pool; +}; + +/* Per job ring data structure */ +struct re_jr { + dma_cookie_t completed_cookie; + spinlock_t desc_lock; + struct list_head ack_q; + struct device *dev; + struct re_drv_private *re_dev; + struct dma_chan chan; + struct jr_config_regs *jrregs; + int irq; + struct tasklet_struct irqtask; + + /* hw descriptor ring for inbound queue*/ + dma_addr_t inb_phys_addr; + struct jr_hw_desc *inb_ring_virt_addr; + u32 inb_count; + u32 pend_count; + spinlock_t inb_lock; + + /* hw descriptor ring for outbound queue */ + dma_addr_t oub_phys_addr; + struct jr_hw_desc *oub_ring_virt_addr; + u32 oub_count; + spinlock_t oub_lock; + + struct fsl_re_dma_async_tx_desc *descs; /* sw descriptor ring */ + void *cfs; /* dma descriptor ring */ + dma_addr_t phys; /* phys addr for dma descriptor ring */ + + struct timer_list timer; +}; + +enum desc_state { + RE_DESC_EMPTY, + RE_DESC_ALLOC, +}; + +/* Async transaction descriptor */ +struct fsl_re_dma_async_tx_desc { + struct dma_async_tx_descriptor async_tx; + struct list_head node; + struct list_head tx_list; + struct jr_hw_desc *hwdesc; + struct re_jr *jr; + + void *cf_addr; + int dma_len; + u8 dest_cnt; + u8 src_cnt; + + u16 cdb_opcode; + void *cdb_addr; + dma_addr_t cdb_paddr; + int cdb_len; + + enum desc_state state; +}; -- 1.7.9.5 ^ permalink raw reply related [flat|nested] 4+ messages in thread
* RE: [PATCH 2/2] powerpc/dma/raidengine: enable Freescale RaidEngine device 2012-11-21 9:01 ` [PATCH 2/2] powerpc/dma/raidengine: enable Freescale RaidEngine device b29237 @ 2013-04-10 5:07 ` Shi Xuelin-B29237 0 siblings, 0 replies; 4+ messages in thread From: Shi Xuelin-B29237 @ 2013-04-10 5:07 UTC (permalink / raw) To: dan.j.williams@gmail.com, vinod.koul@intel.com Cc: linuxppc-dev@lists.ozlabs.org, Burmi Naveen-B16502, Rai Harninder-B01044, linux-kernel@vger.kernel.org, iws@ovro.caltech.edu SGkgRGFuICYgdmlub2QsDQoNCkRvIHlvdSBoYXZlIGFueSBjb21tZW50cyBhYm91dCB0aGlzIHBh dGNoPw0KDQpUaGFua3MsDQpGb3JyZXN0DQoNCi0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQpG cm9tOiBTaGkgWHVlbGluLUIyOTIzNyANClNlbnQ6IDIwMTLE6jEx1MIyMcjVIDE3OjAxDQpUbzog ZGFuLmoud2lsbGlhbXNAZ21haWwuY29tOyB2aW5vZC5rb3VsQGludGVsLmNvbTsgbGludXhwcGMt ZGV2QGxpc3RzLm96bGFicy5vcmc7IGxpbnV4LWtlcm5lbEB2Z2VyLmtlcm5lbC5vcmcNCkNjOiBp d3NAb3Zyby5jYWx0ZWNoLmVkdTsgU2hpIFh1ZWxpbi1CMjkyMzc7IFJhaSBIYXJuaW5kZXItQjAx MDQ0OyBCdXJtaSBOYXZlZW4tQjE2NTAyDQpTdWJqZWN0OiBbUEFUQ0ggMi8yXSBwb3dlcnBjL2Rt YS9yYWlkZW5naW5lOiBlbmFibGUgRnJlZXNjYWxlIFJhaWRFbmdpbmUgZGV2aWNlDQoNCkZyb206 IFh1ZWxpbiBTaGkgPGIyOTIzN0BmcmVlc2NhbGUuY29tPg0KDQpUaGUgUmFpZEVuZ2luZSBpcyBh IG5ldyBGU0wgaGFyZHdhcmUgdGhhdCB1c2VkIGFzIGhhcmR3YXJlIGFjY2VyYXRpb24gZm9yIFJB SUQ1LzYuDQoNClRoaXMgcGF0Y2ggZW5hYmxlcyB0aGUgUmFpZEVuZ2luZSBmdW5jdGlvbmFsaXR5 IGFuZCBwcm92aWRlcyBoYXJkd2FyZSBvZmZsb2FkaW5nIGNhcGFiaWxpdHkgZm9yIG1lbWNweSwg eG9yIGFuZCByYWlkNiBwcSBjb21wdXRhdGlvbi4gSXQgd29ya3MgdW5kZXIgZG1hZW5naW5lIGNv bnRyb2wgd2l0aCBhc3luY19sYXllciBpbnRlcmZhY2UuDQoNClNpZ25lZC1vZmYtYnk6IEhhcm5p bmRlciBSYWkgPGhhcm5pbmRlci5yYWlAZnJlZXNjYWxlLmNvbT4NClNpZ25lZC1vZmYtYnk6IE5h dmVlbiBCdXJtaSA8bmF2ZWVuYnVybWlAZnJlZXNjYWxlLmNvbT4NClNpZ25lZC1vZmYtYnk6IFh1 ZWxpbiBTaGkgPGIyOTIzN0BmcmVlc2NhbGUuY29tPg0KLS0tDQogZHJpdmVycy9kbWEvS2NvbmZp ZyAgICB8ICAgMTQgKw0KIGRyaXZlcnMvZG1hL01ha2VmaWxlICAgfCAgICAxICsNCiBkcml2ZXJz L2RtYS9mc2xfcmFpZC5jIHwgIDk5MCArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysr KysrKysrKysrKysrKysNCiBkcml2ZXJzL2RtYS9mc2xfcmFpZC5oIHwgIDMxNyArKysrKysrKysr KysrKysrDQogNCBmaWxlcyBjaGFuZ2VkLCAxMzIyIGluc2VydGlvbnMoKykNCiBjcmVhdGUgbW9k ZSAxMDA2NDQgZHJpdmVycy9kbWEvZnNsX3JhaWQuYyAgY3JlYXRlIG1vZGUgMTAwNjQ0IGRyaXZl cnMvZG1hL2ZzbF9yYWlkLmgNCg0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvZG1hL0tjb25maWcgYi9k cml2ZXJzL2RtYS9LY29uZmlnIGluZGV4IGQ0YzEyMTguLmFhMzcyNzkgMTAwNjQ0DQotLS0gYS9k cml2ZXJzL2RtYS9LY29uZmlnDQorKysgYi9kcml2ZXJzL2RtYS9LY29uZmlnDQpAQCAtMzIwLDYg KzMyMCwyMCBAQCBjb25maWcgTU1QX1BETUENCiAJaGVscA0KIAkgIFN1cHBvcnQgdGhlIE1NUCBQ RE1BIGVuZ2luZSBmb3IgUFhBIGFuZCBNTVAgcGxhdGZyb20uDQogDQorY29uZmlnIEZTTF9SQUlE DQorICAgICAgICB0cmlzdGF0ZSAiRnJlZXNjYWxlIFJBSUQgRW5naW5lIERldmljZSBEcml2ZXIi DQorICAgICAgICBkZXBlbmRzIG9uIEZTTF9TT0MgJiYgIUZTTF9ETUENCisgICAgICAgIHNlbGVj dCBETUFfRU5HSU5FDQorICAgICAgICBzZWxlY3QgQVNZTkNfVFhfRU5BQkxFX0NIQU5ORUxfU1dJ VENIDQorICAgICAgICBzZWxlY3QgQVNZTkNfTUVNQ1BZDQorICAgICAgICBzZWxlY3QgQVNZTkNf WE9SDQorICAgICAgICBzZWxlY3QgQVNZTkNfUFENCisgICAgICAgIC0tLWhlbHAtLS0NCisgICAg ICAgICAgRW5hYmxlIHN1cHBvcnQgZm9yIEZyZWVzY2FsZSBSQUlEIEVuZ2luZS4gUkFJRCBFbmdp bmUgaXMNCisgICAgICAgICAgYXZhaWxhYmxlIG9uIHNvbWUgUW9ySVEgU29DcyAobGlrZSBQNTAy MCkuIEl0IGhhcw0KKyAgICAgICAgICB0aGUgY2FwYWJpbGl0eSB0byBvZmZsb2FkIFJBSUQ1L1JB SUQ2IG9wZXJhdGlvbnMgZnJvbSBDUFUuDQorICAgICAgICAgIFJBSUQ1IGlzIFhPUiBhbmQgbWVt Y3B5LiBSQUlENiBpcyBQL1EgYW5kIG1lbWNweQ0KKw0KIGNvbmZpZyBETUFfRU5HSU5FDQogCWJv b2wNCiANCmRpZmYgLS1naXQgYS9kcml2ZXJzL2RtYS9NYWtlZmlsZSBiL2RyaXZlcnMvZG1hL01h a2VmaWxlIGluZGV4IDc0MjhmZWEuLjI5YjY1ZWIgMTAwNjQ0DQotLS0gYS9kcml2ZXJzL2RtYS9N YWtlZmlsZQ0KKysrIGIvZHJpdmVycy9kbWEvTWFrZWZpbGUNCkBAIC05LDYgKzksNyBAQCBvYmot JChDT05GSUdfRE1BVEVTVCkgKz0gZG1hdGVzdC5vDQogb2JqLSQoQ09ORklHX0lOVEVMX0lPQVRE TUEpICs9IGlvYXQvDQogb2JqLSQoQ09ORklHX0lOVEVMX0lPUF9BRE1BKSArPSBpb3AtYWRtYS5v DQogb2JqLSQoQ09ORklHX0ZTTF9ETUEpICs9IGZzbGRtYS5vDQorb2JqLSQoQ09ORklHX0ZTTF9S QUlEKSArPSBmc2xfcmFpZC5vDQogb2JqLSQoQ09ORklHX01QQzUxMlhfRE1BKSArPSBtcGM1MTJ4 X2RtYS5vDQogb2JqLSQoQ09ORklHX01WX1hPUikgKz0gbXZfeG9yLm8NCiBvYmotJChDT05GSUdf RFdfRE1BQykgKz0gZHdfZG1hYy5vDQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9kbWEvZnNsX3JhaWQu YyBiL2RyaXZlcnMvZG1hL2ZzbF9yYWlkLmMgbmV3IGZpbGUgbW9kZSAxMDA2NDQgaW5kZXggMDAw MDAwMC4uZWMxOTgxNw0KLS0tIC9kZXYvbnVsbA0KKysrIGIvZHJpdmVycy9kbWEvZnNsX3JhaWQu Yw0KQEAgLTAsMCArMSw5OTAgQEANCisvKg0KKyAqIGRyaXZlcnMvZG1hL2ZzbF9yYWlkLmMNCisg Kg0KKyAqIEZyZWVzY2FsZSBSQUlEIEVuZ2luZSBkZXZpY2UgZHJpdmVyDQorICoNCisgKiBBdXRo b3I6DQorICoJSGFybmluZGVyIFJhaSA8aGFybmluZGVyLnJhaUBmcmVlc2NhbGUuY29tPg0KKyAq CU5hdmVlbiBCdXJtaSA8bmF2ZWVuYnVybWlAZnJlZXNjYWxlLmNvbT4NCisgKg0KKyAqIENvcHly aWdodCAoYykgMjAxMC0yMDEyIEZyZWVzY2FsZSBTZW1pY29uZHVjdG9yLCBJbmMuDQorICoNCisg KiBSZWRpc3RyaWJ1dGlvbiBhbmQgdXNlIGluIHNvdXJjZSBhbmQgYmluYXJ5IGZvcm1zLCB3aXRo IG9yIHdpdGhvdXQNCisgKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhh dCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDoNCisgKiAgICAgKiBSZWRpc3RyaWJ1 dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodA0KKyAq ICAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcg ZGlzY2xhaW1lci4NCisgKiAgICAgKiBSZWRpc3RyaWJ1dGlvbnMgaW4gYmluYXJ5IGZvcm0gbXVz dCByZXByb2R1Y2UgdGhlIGFib3ZlIGNvcHlyaWdodA0KKyAqICAgICAgIG5vdGljZSwgdGhpcyBs aXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUNCisg KiAgICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0 aCB0aGUgZGlzdHJpYnV0aW9uLg0KKyAqICAgICAqIE5laXRoZXIgdGhlIG5hbWUgb2YgRnJlZXNj YWxlIFNlbWljb25kdWN0b3Igbm9yIHRoZQ0KKyAqICAgICAgIG5hbWVzIG9mIGl0cyBjb250cmli dXRvcnMgbWF5IGJlIHVzZWQgdG8gZW5kb3JzZSBvciBwcm9tb3RlIHByb2R1Y3RzDQorICogICAg ICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0 dGVuIHBlcm1pc3Npb24uDQorICoNCisgKiBBTFRFUk5BVElWRUxZLCB0aGlzIHNvZnR3YXJlIG1h eSBiZSBkaXN0cmlidXRlZCB1bmRlciB0aGUgdGVybXMgb2YgDQordGhlDQorICogR05VIEdlbmVy YWwgUHVibGljIExpY2Vuc2UgKCJHUEwiKSBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdh cmUNCisgKiBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoYXQgTGljZW5zZSBvciAo YXQgeW91ciBvcHRpb24pIGFueQ0KKyAqIGxhdGVyIHZlcnNpb24uDQorICoNCisgKiBUSElTIFNP RlRXQVJFIElTIFBST1ZJREVEIEJZIEZyZWVzY2FsZSBTZW1pY29uZHVjdG9yIGBgQVMgSVMnJyBB TkQgDQorQU5ZDQorICogRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywg QlVUIE5PVCBMSU1JVEVEIFRPLCBUSEUgDQorSU1QTElFRA0KKyAqIFdBUlJBTlRJRVMgT0YgTUVS Q0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSANCitBUkUN CisgKiBESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBGcmVlc2NhbGUgU2VtaWNvbmR1Y3Rv ciBCRSBMSUFCTEUgRk9SIA0KK0FOWQ0KKyAqIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUws IFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCANCitEQU1BR0VTDQorICogKElO Q0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdP T0RTIE9SIA0KK1NFUlZJQ0VTOw0KKyAqIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBP UiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgDQorQ0FVU0VEIEFORA0KKyAqIE9OIEFO WSBUSEVPUlkgT0YgTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklM SVRZLCANCitPUiBUT1JUDQorICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkg QVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgDQorVVNFIE9GIFRISVMNCisgKiBTT0ZUV0FS RSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS4NCisg Kg0KKyAqIFRoZW9yeSBvZiBvcGVyYXRpb246DQorICoNCisgKiBHZW5lcmFsIGNhcGFiaWxpdGll czoNCisgKglSQUlEIEVuZ2luZSAoUkUpIGJsb2NrIGlzIGNhcGFibGUgb2Ygb2ZmbG9hZGluZyBY T1IsIG1lbWNweSBhbmQgUC9RDQorICoJY2FsY3VsYXRpb25zIHJlcXVpcmVkIGluIFJBSUQ1IGFu ZCBSQUlENiBvcGVyYXRpb25zLiBSRSBkcml2ZXINCisgKglyZWdpc3RlcnMgd2l0aCBMaW51eCdz IEFTWU5DIGxheWVyIGFzIGRtYSBkcml2ZXIuIFJFIGhhcmR3YXJlDQorICoJbWFpbnRhaW5zIHN0 cmljdCBvcmRlcmluZyBvZiB0aGUgcmVxdWVzdHMgdGhyb3VnaCBjaGFpbmVkDQorICoJY29tbWFu ZCBxdWV1ZWluZy4NCisgKg0KKyAqIERhdGEgZmxvdzoNCisgKglTb2Z0d2FyZSBSQUlEIGxheWVy IG9mIExpbnV4IChNRCBsYXllcikgbWFpbnRhaW5zIFJBSUQgcGFydGl0aW9ucywNCisgKglzdHJp cHMsIHN0cmlwZXMgZXRjLiBJdCBzZW5kcyByZXF1ZXN0cyB0byB0aGUgdW5kZXJseWluZyBBWVNO QyBsYXllcg0KKyAqCXdoaWNoIGZ1cnRoZXIgcGFzc2VzIGl0IHRvIFJFIGRyaXZlci4gQVNZTkMg bGF5ZXIgZGVjaWRlcyB3aGljaCByZXF1ZXN0DQorICoJZ29lcyB0byB3aGljaCBqb2IgcmluZyBv ZiBSRSBoYXJkd2FyZS4gRm9yIGV2ZXJ5IHJlcXVlc3QgcHJvY2Vzc2VkIGJ5DQorICoJUkFJRCBF bmdpbmUsIGRyaXZlciBnZXRzIGFuIGludGVycnVwdCB1bmxlc3MgY29hbGVzY2luZyBpcyBzZXQu IFRoZQ0KKyAqCXBlciBqb2IgcmluZyBpbnRlcnJ1cHQgaGFuZGxlciBjaGVja3MgdGhlIHN0YXR1 cyByZWdpc3RlciBmb3IgZXJyb3JzLA0KKyAqCWNsZWFycyB0aGUgaW50ZXJydXB0IGFuZCBzY2hl ZHVsZXMgYSB0YXNrbGV0LiBNYWluIHJlcXVlc3QgcHJvY2Vzc2luZw0KKyAqCWlzIGRvbmUgaW4g dGFza2xldC4gQSBzb2Z0d2FyZSBzaGFkb3cgY29weSBvZiB0aGUgSFcgcmluZyBpcyBrZXB0IHRv DQorICoJbWFpbnRhaW4gdmlydHVhbCB0byBwaHlzaWNhbCB0cmFuc2xhdGlvbi4gQmFzZWQgb24g dGhlIGludGVybmFsIGluZGV4ZXMNCisgKgltYWludGFpbmVkLCB0aGUgdGFza2xldCBwaWNrcyB0 aGUgZGVzY3JpcHRvciBhZGRyZXNzIGZyb20gc2hhZG93IGNvcHksDQorICoJdXBkYXRlcyB0aGUg Y29ycmVzcG9uZGluZyBjb29raWUsIHVwZGF0ZXMgdGhlIG91dGJvdW5kIHJpbmcgam9iIHJlbW92 ZWQNCisgKglyZWdpc3RlciBpbiBSRSBoYXJkd2FyZSBhbmQgZXZlbnR1YWxseSBjYWxscyB0aGUg Y2FsbGJhY2sgZnVuY3Rpb24uIFRoaXMNCisgKgljYWxsYmFjayBmdW5jdGlvbiBnZXRzIHBhc3Nl ZCBhcyBwYXJ0IG9mIHJlcXVlc3QgZnJvbSBNRCBsYXllci4NCisgKi8NCisNCisjaW5jbHVkZSA8 bGludXgvaW50ZXJydXB0Lmg+DQorI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPg0KKyNpbmNsdWRl IDxsaW51eC9vZl9wbGF0Zm9ybS5oPg0KKyNpbmNsdWRlIDxsaW51eC9kbWEtbWFwcGluZy5oPg0K KyNpbmNsdWRlIDxsaW51eC9kbWFwb29sLmg+DQorI2luY2x1ZGUgPGxpbnV4L2RtYWVuZ2luZS5o Pg0KKyNpbmNsdWRlIDxsaW51eC9pby5oPg0KKyNpbmNsdWRlIDxsaW51eC9zcGlubG9jay5oPg0K KyNpbmNsdWRlIDxsaW51eC9zbGFiLmg+DQorDQorI2luY2x1ZGUgImZzbF9yYWlkLmgiDQorDQor I2RlZmluZSBNQVhfWE9SX1NSQ1MJCTE2DQorI2RlZmluZSBNQVhfUFFfU1JDUwkJMTYNCisjZGVm aW5lIE1BWF9JTklUSUFMX0RFU0NTCTI1Ng0KKyNkZWZpbmUgRlJBTUVfRk9STUFUCQkweDENCisj ZGVmaW5lIE1BWF9EQVRBX0xFTkdUSAkJKDEwMjQqMTAyNCkNCisNCisjZGVmaW5lIHRvX2ZzbF9y ZV9kbWFfZGVzYyh0eCkgY29udGFpbmVyX29mKHR4LCBcDQorCQlzdHJ1Y3QgZnNsX3JlX2RtYV9h c3luY190eF9kZXNjLCBhc3luY190eCkNCisNCisvKiBBZGQgZGVzY3JpcHRvcnMgaW50byBwZXIg anIgc29mdHdhcmUgcXVldWUgLSBzdWJtaXRfcSAqLyBzdGF0aWMgDQorZG1hX2Nvb2tpZV90IHJl X2pyX3R4X3N1Ym1pdChzdHJ1Y3QgZG1hX2FzeW5jX3R4X2Rlc2NyaXB0b3IgKnR4KSB7DQorCXN0 cnVjdCBmc2xfcmVfZG1hX2FzeW5jX3R4X2Rlc2MgKmRlc2MgPSBOVUxMOw0KKwlzdHJ1Y3QgcmVf anIgKmpyID0gTlVMTDsNCisJZG1hX2Nvb2tpZV90IGNvb2tpZTsNCisNCisJZGVzYyA9IGNvbnRh aW5lcl9vZih0eCwgc3RydWN0IGZzbF9yZV9kbWFfYXN5bmNfdHhfZGVzYywgYXN5bmNfdHgpOw0K KwlqciA9IGNvbnRhaW5lcl9vZih0eC0+Y2hhbiwgc3RydWN0IHJlX2pyLCBjaGFuKTsNCisNCisJ c3Bpbl9sb2NrX2JoKCZqci0+aW5iX2xvY2spOw0KKw0KKwlqci0+dGltZXIuZGF0YSA9ICh1bnNp Z25lZCBsb25nKXR4LT5jaGFuOw0KKwljb29raWUgPSBqci0+Y2hhbi5jb29raWUgKyAxOw0KKwlp ZiAoY29va2llIDwgMCkNCisJCWNvb2tpZSA9IDE7DQorDQorCWRlc2MtPmFzeW5jX3R4LmNvb2tp ZSA9IGNvb2tpZTsNCisJanItPmNoYW4uY29va2llID0gZGVzYy0+YXN5bmNfdHguY29va2llOw0K Kwlqci0+cGVuZF9jb3VudCsrOw0KKw0KKwlpZiAoIXRpbWVyX3BlbmRpbmcoJmpyLT50aW1lcikp DQorCQlhZGRfdGltZXIoJmpyLT50aW1lcik7DQorDQorCXNwaW5fdW5sb2NrX2JoKCZqci0+aW5i X2xvY2spOw0KKw0KKwlyZXR1cm4gY29va2llOw0KK30NCisNCitzdGF0aWMgdm9pZCByZV9qcl91 bm1hcF9kZXN0X3NyYyhzdHJ1Y3QgZnNsX3JlX2RtYV9hc3luY190eF9kZXNjICpkZXNjKSANCit7 DQorCWludCBpLCBqOw0KKwlzdHJ1Y3QgY21wbmRfZnJhbWUgKmNmOw0KKwlkbWFfYWRkcl90IGRl c3QxID0gMCwgZGVzdDIgPSAwLCBzcmM7DQorCXN0cnVjdCBkZXZpY2UgKmRldjsNCisJZW51bSBk bWFfY3RybF9mbGFncyBmbGFnczsNCisJZW51bSBkbWFfZGF0YV9kaXJlY3Rpb24gZGlyOw0KKw0K KwlCVUdfT04oIWRlc2MpOw0KKwljZiA9IGRlc2MtPmNmX2FkZHI7DQorCWRlc3QxID0gY2ZbMV0u YWRkcmVzczsNCisJaiA9IDI7DQorCWlmIChkZXNjLT5kZXN0X2NudCA9PSAyKSB7DQorCQlkZXN0 MiA9IGNmWzJdLmFkZHJlc3M7DQorCQlqID0gMzsNCisJfQ0KKwlkZXYgPSBkZXNjLT5qci0+Y2hh bi5kZXZpY2UtPmRldjsNCisJZmxhZ3MgPSBkZXNjLT5hc3luY190eC5mbGFnczsNCisJaWYgKCEo ZmxhZ3MgJiBETUFfQ09NUExfU0tJUF9ERVNUX1VOTUFQKSkgew0KKwkJaWYgKGRlc2MtPmNkYl9v cGNvZGUgPT0gUkVfTU9WRV9PUENPREUpDQorCQkJZGlyID0gRE1BX0ZST01fREVWSUNFOw0KKwkJ ZWxzZQ0KKwkJCWRpciA9IERNQV9CSURJUkVDVElPTkFMOw0KKw0KKwkJZG1hX3VubWFwX3BhZ2Uo ZGV2LCBkZXN0MSwgZGVzYy0+ZG1hX2xlbiwgZGlyKTsNCisNCisJCWlmIChkZXN0MikNCisJCQlk bWFfdW5tYXBfcGFnZShkZXYsIGRlc3QyLCBkZXNjLT5kbWFfbGVuLCBkaXIpOw0KKwl9DQorDQor CWlmICghKGZsYWdzICYgRE1BX0NPTVBMX1NLSVBfU1JDX1VOTUFQKSkgew0KKwkJZGlyID0gRE1B X1RPX0RFVklDRTsNCisJCWZvciAoaSA9IGo7IGkgPCBkZXNjLT5zcmNfY250K2o7IGkrKykgew0K KwkJCXNyYyA9IGNmW2ldLmFkZHJlc3M7DQorCQkJaWYgKHNyYyA9PSBkZXN0MSB8fCBzcmMgPT0g ZGVzdDIpDQorCQkJCWNvbnRpbnVlOw0KKwkJCWRtYV91bm1hcF9wYWdlKGRldiwgc3JjLCBkZXNj LT5kbWFfbGVuLCBkaXIpOw0KKwkJfQ0KKwl9DQorfQ0KKw0KK3N0YXRpYyB2b2lkIHJlX2pyX2Rl c2NfZG9uZShzdHJ1Y3QgZnNsX3JlX2RtYV9hc3luY190eF9kZXNjICpkZXNjKSB7DQorCXN0cnVj dCByZV9qciAqZG1hX2pyID0gZGVzYy0+anI7DQorCWRtYV9hc3luY190eF9jYWxsYmFjayBjYWxs YmFjazsNCisJdm9pZCAqY2FsbGJhY2tfcGFyYW07DQorDQorCWNhbGxiYWNrID0gZGVzYy0+YXN5 bmNfdHguY2FsbGJhY2s7DQorCWNhbGxiYWNrX3BhcmFtID0gZGVzYy0+YXN5bmNfdHguY2FsbGJh Y2tfcGFyYW07DQorDQorCWRtYV9ydW5fZGVwZW5kZW5jaWVzKCZkZXNjLT5hc3luY190eCk7DQor DQorCWlmIChkbWFfanItPmNvbXBsZXRlZF9jb29raWUgPCBkZXNjLT5hc3luY190eC5jb29raWUp IHsNCisJCWRtYV9qci0+Y29tcGxldGVkX2Nvb2tpZSA9IGRlc2MtPmFzeW5jX3R4LmNvb2tpZTsN CisJCWlmIChkbWFfanItPmNvbXBsZXRlZF9jb29raWUgPT0gRE1BX01BWF9DT09LSUUpDQorCQkJ ZG1hX2pyLT5jb21wbGV0ZWRfY29va2llID0gRE1BX01JTl9DT09LSUU7DQorCX0NCisNCisJcmVf anJfdW5tYXBfZGVzdF9zcmMoZGVzYyk7DQorDQorCWlmIChjYWxsYmFjaykNCisJCWNhbGxiYWNr KGNhbGxiYWNrX3BhcmFtKTsNCisNCit9DQorDQorLyoNCisgKiBHZXQgdGhlIHZpcnR1YWwgYWRk cmVzcyBvZiBzb2Z0d2FyZSBkZXNjIGZyb20gdmlydF9hZGRyLg0KKyAqIFN0b3JpbmcgdGhlIGFk ZHJlc3Mgb2Ygc29mdHdhcmUgZGVzYyBsaWtlIHRoaXMgbWFrZXMgdGhlDQorICogb3JkZXIgb2Yg YWxvZ29yaXRobSBhcyBPKDEpDQorICovDQorc3RhdGljIHZvaWQgcmVfanJfZGVxdWV1ZSh1bnNp Z25lZCBsb25nIGRhdGEpIHsNCisJc3RydWN0IGRldmljZSAqZGV2Ow0KKwlzdHJ1Y3QgcmVfanIg KmpyOw0KKwlzdHJ1Y3QgZnNsX3JlX2RtYV9hc3luY190eF9kZXNjICpkZXNjOw0KKwl1bnNpZ25l ZCBpbnQgY291bnQ7DQorCXN0cnVjdCBmc2xfcmVfZG1hX2FzeW5jX3R4X2Rlc2MgKmFja19kZXNj ID0gTlVMTCwgKl9hY2tfZGVzYyA9IE5VTEw7DQorDQorCWRldiA9IChzdHJ1Y3QgZGV2aWNlICop ZGF0YTsNCisJanIgPSBkZXZfZ2V0X2RydmRhdGEoZGV2KTsNCisNCisJd2hpbGUgKChjb3VudCA9 DQorCQlSRV9KUl9PVUJfU0xPVF9GVUxMKGluX2JlMzIoJmpyLT5qcnJlZ3MtPm91YnJpbmdfc2xv dF9mdWxsKSkpKSB7DQorCQl3aGlsZSAoY291bnQtLSkgew0KKwkJCXNwaW5fbG9ja19iaCgmanIt Pm91Yl9sb2NrKTsNCisJCQlqci0+b3ViX2NvdW50ICY9IFJJTkdfU0laRSAtIDE7DQorCQkJZGVz YyA9ICZqci0+ZGVzY3NbanItPm91Yl9jb3VudCsrXTsNCisNCisJCQkvKiBPbmUgam9iIHByb2Nl c3NlZCAqLw0KKwkJCW91dF9iZTMyKCZqci0+anJyZWdzLT5vdWJyaW5nX2pvYl9ybXZkLA0KKwkJ CQlSRV9KUl9PVUJfSk9CX1JFTU9WRSgxKSk7DQorCQkJc3Bpbl91bmxvY2tfYmgoJmpyLT5vdWJf bG9jayk7DQorDQorCQkJc3Bpbl9sb2NrX2JoKCZqci0+ZGVzY19sb2NrKTsNCisJCQlsaXN0X2Fk ZF90YWlsKCZkZXNjLT5ub2RlLCAmanItPmFja19xKTsNCisJCQlyZV9qcl9kZXNjX2RvbmUoZGVz Yyk7DQorCQkJc3Bpbl91bmxvY2tfYmgoJmpyLT5kZXNjX2xvY2spOw0KKwkJfQ0KKwl9DQorDQor CS8qIFRvIHNhdmUgbWVtb3J5LCBwYXJzZSB0aGUgYWNrX3EgYW5kIGZyZWUgdXAgZGVzY3MgKi8N CisJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlKGFja19kZXNjLCBfYWNrX2Rlc2MsICZqci0+YWNr X3EsIG5vZGUpIHsNCisJCWlmIChhc3luY190eF90ZXN0X2FjaygmYWNrX2Rlc2MtPmFzeW5jX3R4 KSkgew0KKwkJCXNwaW5fbG9ja19iaCgmanItPmRlc2NfbG9jayk7DQorCQkJbGlzdF9kZWwoJmFj a19kZXNjLT5ub2RlKTsNCisJCQlhY2tfZGVzYy0+c3RhdGUgPSBSRV9ERVNDX0VNUFRZOw0KKwkJ CWFja19kZXNjLT5hc3luY190eC5mbGFncyA9IDA7DQorCQkJc3Bpbl91bmxvY2tfYmgoJmpyLT5k ZXNjX2xvY2spOw0KKwkJfQ0KKwl9DQorfQ0KKw0KKy8qIFBlciBKb2IgUmluZyBpbnRlcnJ1cHQg aGFuZGxlciAqLw0KK3N0YXRpYyBpcnFyZXR1cm5fdCByZV9qcl9pbnRlcnJ1cHQoaW50IGlycSwg dm9pZCAqZGF0YSkgew0KKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSBkYXRhOw0KKwlzdHJ1Y3QgcmVf anIgKmpyID0gZGV2X2dldF9kcnZkYXRhKGRldik7DQorCXUzMiBpcnFzdGF0ZSwgc3RhdHVzOw0K Kw0KKwlpcnFzdGF0ZSA9IGluX2JlMzIoJmpyLT5qcnJlZ3MtPmpyX2ludGVycnVwdF9zdGF0dXMp Ow0KKwlpZiAoIWlycXN0YXRlKQ0KKwkJcmV0dXJuIElSUV9OT05FOw0KKw0KKwkvKg0KKwkgKiBU aGVyZSdzIG5vIHdheSBpbiB1cHBlciBsYXllciAocmVhZCBNRCBsYXllcikgdG8gcmVjb3ZlciBm cm9tDQorCSAqIGVycm9yIGNvbmRpdGlvbnMgZXhjZXB0IHJlc3RhcnQgZXZlcnl0aGluZy4gSW4g bG9uZyB0ZXJtIHdlDQorCSAqIG5lZWQgdG8gZG8gc29tZXRoaW5nIG1vcmUgdGhhbiBqdXN0IGNy YXNoaW5nDQorCSAqLw0KKwlpZiAoaXJxc3RhdGUgJiBSRV9KUl9FUlJPUikgew0KKwkJc3RhdHVz ID0gaW5fYmUzMigmanItPmpycmVncy0+anJfc3RhdHVzKTsNCisJCWRldl9lcnIoZGV2LCAiJXM6 IGpyIGVycm9yIGlycXN0YXRlOiAleCwgc3RhdHVzOiAleFxuIiwNCisJCQkJCV9fZnVuY19fLCBp cnFzdGF0ZSwgc3RhdHVzKTsNCisNCisJCUJVRygpOw0KKwl9DQorDQorCS8qIENsZWFyIGludGVy cnVwdCAqLw0KKwlvdXRfYmUzMigmanItPmpycmVncy0+anJfaW50ZXJydXB0X3N0YXR1cywgUkVf SlJfQ0xFQVJfSU5UKTsNCisNCisJdGFza2xldF9zY2hlZHVsZSgmanItPmlycXRhc2spOw0KKw0K KwlyZXR1cm4gSVJRX0hBTkRMRUQ7DQorfQ0KKw0KK3N0YXRpYyBlbnVtIGRtYV9zdGF0dXMgcmVf anJfdHhfc3RhdHVzKHN0cnVjdCBkbWFfY2hhbiAqY2hhbiwNCisJCWRtYV9jb29raWVfdCBjb29r aWUsIHN0cnVjdCBkbWFfdHhfc3RhdGUgKnR4c3RhdGUpIHsNCisJc3RydWN0IHJlX2pyICpqciA9 IE5VTEw7DQorCWRtYV9jb29raWVfdCBsYXN0X3VzZWQ7DQorCWRtYV9jb29raWVfdCBsYXN0X2Nv bXBsZXRlOw0KKw0KKwlqciA9IGNvbnRhaW5lcl9vZihjaGFuLCBzdHJ1Y3QgcmVfanIsIGNoYW4p Ow0KKwlsYXN0X3VzZWQgPSBjaGFuLT5jb29raWU7DQorCXNtcF9tYigpOw0KKwlsYXN0X2NvbXBs ZXRlID0ganItPmNvbXBsZXRlZF9jb29raWU7DQorDQorCWRtYV9zZXRfdHhfc3RhdGUodHhzdGF0 ZSwgbGFzdF9jb21wbGV0ZSwgbGFzdF91c2VkLCAwKTsNCisNCisJcmV0dXJuIGRtYV9hc3luY19p c19jb21wbGV0ZShjb29raWUsIGxhc3RfY29tcGxldGUsIGxhc3RfdXNlZCk7IH0NCisNCisNCisv KiBDb3B5IGRlc2NyaXB0b3IgZnJvbSBwZXIganIgc29mdHdhcmUgcXVldWUgaW50byBoYXJkd2Fy ZSBqb2IgcmluZyAqLyANCit2b2lkIHJlX2pyX2lzc3VlX3BlbmRpbmcoc3RydWN0IGRtYV9jaGFu ICpjaGFuKSB7DQorCXN0cnVjdCByZV9qciAqanIgPSBOVUxMOw0KKwlpbnQgYXZhaWwgPSAwOw0K Kw0KKwlqciA9IGNvbnRhaW5lcl9vZihjaGFuLCBzdHJ1Y3QgcmVfanIsIGNoYW4pOw0KKwlpZiAo dGltZXJfcGVuZGluZygmanItPnRpbWVyKSkNCisJCWRlbF90aW1lcl9zeW5jKCZqci0+dGltZXIp Ow0KKw0KKwlzcGluX2xvY2tfYmgoJmpyLT5pbmJfbG9jayk7DQorDQorCWF2YWlsID0gDQorUkVf SlJfSU5CX1NMT1RfQVZBSUwoaW5fYmUzMigmanItPmpycmVncy0+aW5icmluZ19zbG90X2F2YWls KSk7DQorDQorCWlmICghKGF2YWlsICYmIGpyLT5wZW5kX2NvdW50KSkNCisJCWdvdG8gb3V0X3Vu bG9jazsNCisNCisJaWYgKGF2YWlsID4ganItPnBlbmRfY291bnQpDQorCQlhdmFpbCA9IGpyLT5w ZW5kX2NvdW50Ow0KKw0KKwlqci0+cGVuZF9jb3VudCAtPSBhdmFpbDsNCisJanItPmluYl9jb3Vu dCA9IChqci0+aW5iX2NvdW50ICsgYXZhaWwpICYgKFJJTkdfU0laRSAtIDEpOw0KKw0KKwkvKiBh ZGQgam9icyBpbnRvIGpvYiByaW5nICovDQorCW91dF9iZTMyKCZqci0+anJyZWdzLT5pbmJyaW5n X2FkZF9qb2IsIFJFX0pSX0lOQl9KT0JfQUREKGF2YWlsKSk7DQorDQorb3V0X3VubG9jazoNCisJ c3Bpbl91bmxvY2tfYmgoJmpyLT5pbmJfbG9jayk7DQorfQ0KKw0KKy8qIFBlciBKb2IgUmluZyB0 aW1lciBoYW5kbGVyICovDQorc3RhdGljIHZvaWQgcmFpZGVfdGltZXJfaGFuZGxlcih1bnNpZ25l ZCBsb25nIGRhdGEpIHsNCisJc3RydWN0IGRtYV9jaGFuICpjaGFuID0gTlVMTDsNCisJY2hhbiA9 IChzdHJ1Y3QgZG1hX2NoYW4gKilkYXRhOw0KKw0KKwlyZV9qcl9pc3N1ZV9wZW5kaW5nKGNoYW4p Ow0KKw0KKwlyZXR1cm47DQorfQ0KKw0KK2lubGluZSB2b2lkIGZpbGxfY2ZkX2ZyYW1lKHN0cnVj dCBjbXBuZF9mcmFtZSAqY2YsIHU4IGluZGV4LA0KKwkJc2l6ZV90IGxlbmd0aCwgZG1hX2FkZHJf dCBhZGRyLCBib29sIGZpbmFsKSB7DQorCWNmW2luZGV4XS5maW5hbCA9IGZpbmFsOw0KKwljZltp bmRleF0ubGVuZ3RoID0gbGVuZ3RoOw0KKwljZltpbmRleF0uYWRkcmVzcyA9IGFkZHI7DQorfQ0K Kw0KK3N0YXRpYyBzdHJ1Y3QgZnNsX3JlX2RtYV9hc3luY190eF9kZXNjICpyZV9qcl9pbml0X2Rl c2Moc3RydWN0IHJlX2pyICpqciwNCisJc3RydWN0IGZzbF9yZV9kbWFfYXN5bmNfdHhfZGVzYyAq ZGVzYywgdm9pZCAqY2YsIGRtYV9hZGRyX3QgcGFkZHIpIHsNCisJZGVzYy0+anIgPSBqcjsNCisJ ZGVzYy0+YXN5bmNfdHgudHhfc3VibWl0ID0gcmVfanJfdHhfc3VibWl0Ow0KKwlkbWFfYXN5bmNf dHhfZGVzY3JpcHRvcl9pbml0KCZkZXNjLT5hc3luY190eCwgJmpyLT5jaGFuKTsNCisJSU5JVF9M SVNUX0hFQUQoJmRlc2MtPm5vZGUpOw0KKw0KKwlkZXNjLT5od2Rlc2MtPmZvcm1hdCA9IEZSQU1F X0ZPUk1BVDsNCisJZGVzYy0+aHdkZXNjLT5hZGRyZXNzID0gcGFkZHI7DQorCWRlc2MtPmNmX2Fk ZHIgPSBjZjsNCisNCisJZGVzYy0+Y2RiX2FkZHIgPSAodm9pZCAqKShjZiArIFJFX0NGX0RFU0Nf U0laRSk7DQorCWRlc2MtPmNkYl9wYWRkciA9IHBhZGRyICsgUkVfQ0ZfREVTQ19TSVpFOw0KKw0K KwlyZXR1cm4gZGVzYzsNCit9DQorDQorc3RhdGljIHN0cnVjdCBmc2xfcmVfZG1hX2FzeW5jX3R4 X2Rlc2MgKnJlX2pyX2FsbG9jX2Rlc2Moc3RydWN0IHJlX2pyICpqciwNCisJCXVuc2lnbmVkIGxv bmcgZmxhZ3MpDQorew0KKwlzdHJ1Y3QgZnNsX3JlX2RtYV9hc3luY190eF9kZXNjICpkZXNjOw0K Kw0KKwlzcGluX2xvY2tfYmgoJmpyLT5pbmJfbG9jayk7DQorDQorCWpyLT5pbmJfY291bnQgJj0g UklOR19TSVpFIC0gMTsNCisJZGVzYyA9ICZqci0+ZGVzY3NbanItPmluYl9jb3VudF07DQorDQor CWlmIChkZXNjLT5zdGF0ZSAhPSBSRV9ERVNDX0VNUFRZKSB7DQorCQlzcGluX3VubG9ja19iaCgm anItPmluYl9sb2NrKTsNCisJCXJlX2pyX2lzc3VlX3BlbmRpbmcoJmpyLT5jaGFuKTsNCisJCXJl dHVybiBOVUxMOw0KKwl9DQorCXNwaW5fdW5sb2NrX2JoKCZqci0+aW5iX2xvY2spOw0KKw0KKwlk ZXNjLT5zdGF0ZSA9IFJFX0RFU0NfQUxMT0M7DQorCWRlc2MtPmFzeW5jX3R4LmZsYWdzID0gZmxh Z3M7DQorCXJldHVybiBkZXNjOw0KK30NCisNCitzdGF0aWMgc3RydWN0IGRtYV9hc3luY190eF9k ZXNjcmlwdG9yICpyZV9qcl9wcmVwX2dlbnEoDQorCQlzdHJ1Y3QgZG1hX2NoYW4gKmNoYW4sIGRt YV9hZGRyX3QgZGVzdCwgZG1hX2FkZHJfdCAqc3JjLA0KKwkJdW5zaWduZWQgaW50IHNyY19jbnQs IGNvbnN0IHVuc2lnbmVkIGNoYXIgKnNjZiwgc2l6ZV90IGxlbiwNCisJCXVuc2lnbmVkIGxvbmcg ZmxhZ3MpDQorew0KKwlzdHJ1Y3QgcmVfanIgKmpyID0gTlVMTDsNCisJc3RydWN0IGZzbF9yZV9k bWFfYXN5bmNfdHhfZGVzYyAqZGVzYyA9IE5VTEw7DQorCXN0cnVjdCB4b3JfY2RiICp4b3IgPSBO VUxMOw0KKwlzdHJ1Y3QgY21wbmRfZnJhbWUgKmNmOw0KKwl1bnNpZ25lZCBpbnQgaSA9IDA7DQor CXVuc2lnbmVkIGludCBqID0gMDsNCisNCisJaWYgKGxlbiA+IE1BWF9EQVRBX0xFTkdUSCkgew0K KwkJcHJfZXJyKCIlczogTGVuZ3RoIGdyZWF0ZXIgdGhhbiAlZCBub3Qgc3VwcG9ydGVkXG4iLA0K KwkJCQlfX2Z1bmNfXywgTUFYX0RBVEFfTEVOR1RIKTsNCisJCXJldHVybiBOVUxMOw0KKwl9DQor CWpyID0gY29udGFpbmVyX29mKGNoYW4sIHN0cnVjdCByZV9qciwgY2hhbik7DQorCWRlc2MgPSBy ZV9qcl9hbGxvY19kZXNjKGpyLCBmbGFncyk7DQorCWlmICghZGVzYyB8fCBkZXNjIDwgMCkNCisJ CXJldHVybiBOVUxMOw0KKw0KKwlkZXNjLT5kbWFfbGVuID0gbGVuOw0KKwlkZXNjLT5kZXN0X2Nu dCA9IDE7DQorCWRlc2MtPnNyY19jbnQgPSBzcmNfY250Ow0KKw0KKwlkZXNjLT5jZGJfb3Bjb2Rl ID0gUkVfWE9SX09QQ09ERTsNCisJZGVzYy0+Y2RiX2xlbiA9IHNpemVvZihzdHJ1Y3QgeG9yX2Nk Yik7DQorDQorCS8qIEZpbGxpbmcgeG9yIENEQiAqLw0KKwl4b3IgPSBkZXNjLT5jZGJfYWRkcjsN CisJeG9yLT5vcGNvZGUgPSBSRV9YT1JfT1BDT0RFOw0KKwl4b3ItPm5yY3MgPSAoc3JjX2NudCAt IDEpOw0KKwl4b3ItPmJsa19zaXplID0gUkVfQkxPQ0tfU0laRTsNCisJeG9yLT5lcnJvcl9hdHRy aWIgPSBJTlRFUlJVUFRfT05fRVJST1I7DQorCXhvci0+ZGF0YV9kZXBlbmQgPSBEQVRBX0RFUEVO REVOQ1k7DQorDQorCWlmIChzY2YgIT0gTlVMTCkgew0KKwkJLyogY29tcHV0ZSBxID0gc3JjMCpj b2VmMF5zcmMxKmNvZWYxXi4uLiwgKiBpcyBHRig4KSBtdWx0ICovDQorCQlmb3IgKGkgPSAwOyBp IDwgc3JjX2NudDsgaSsrKQ0KKwkJCXhvci0+Z2ZtW2ldID0gc2NmW2ldOw0KKwl9IGVsc2Ugew0K KwkJLyogY29tcHV0ZSBQLCB0aGF0IGlzIFhPUiBhbGwgc3JjcyAqLw0KKwkJZm9yIChpID0gMDsg aSA8IHNyY19jbnQ7IGkrKykNCisJCQl4b3ItPmdmbVtpXSA9IDE7DQorCX0NCisNCisJLyogRmls bGluZyBmcmFtZSAwIG9mIGNvbXBvdW5kIGZyYW1lIGRlc2NyaXB0b3Igd2l0aCBDREIgKi8NCisJ Y2YgPSBkZXNjLT5jZl9hZGRyOw0KKwlmaWxsX2NmZF9mcmFtZShjZiwgMCwgZGVzYy0+Y2RiX2xl biwgZGVzYy0+Y2RiX3BhZGRyLCAwKTsNCisNCisJLyogRmlsbCBDRkQncyAxc3QgZnJhbWUgd2l0 aCBkZXN0IGJ1ZmZlciAqLw0KKwlmaWxsX2NmZF9mcmFtZShjZiwgMSwgbGVuLCBkZXN0LCAwKTsN CisNCisJLyogRmlsbCBDRkQncyByZXN0IG9mIHRoZSBmcmFtZXMgd2l0aCBzb3VyY2UgYnVmZmVy cyAqLw0KKwlmb3IgKGkgPSAyLCBqID0gMDsgaiA8IHNyY19jbnQ7IGkrKywgaisrKQ0KKwkJZmls bF9jZmRfZnJhbWUoY2YsIGksIGxlbiwgc3JjW2pdLCAwKTsNCisNCisJLyogU2V0dGluZyB0aGUg ZmluYWwgYml0IGluIHRoZSBsYXN0IHNvdXJjZSBidWZmZXIgZnJhbWUgaW4gQ0ZEICovDQorCWNm W2kgLSAxXS5maW5hbCA9IDE7DQorDQorCXJldHVybiAmZGVzYy0+YXN5bmNfdHg7DQorfQ0KKw0K Ky8qDQorICogUHJlcCBmdW5jdGlvbiBmb3IgUCBwYXJpdHkgY2FsY3VsYXRpb24uSW4gUkFJRCBF bmdpbmUgdGVybWlub2xvZ3ksDQorICogWE9SIGNhbGN1bGF0aW9uIGlzIGNhbGxlZCBHZW5RIGNh bGN1bGF0aW9uIGRvbmUgdGhyb3VnaCBHZW5RIGNvbW1hbmQgIA0KKyovIHN0YXRpYyBzdHJ1Y3Qg ZG1hX2FzeW5jX3R4X2Rlc2NyaXB0b3IgKnJlX2pyX3ByZXBfZG1hX3hvcigNCisJCXN0cnVjdCBk bWFfY2hhbiAqY2hhbiwgZG1hX2FkZHJfdCBkZXN0LCBkbWFfYWRkcl90ICpzcmMsDQorCQl1bnNp Z25lZCBpbnQgc3JjX2NudCwgc2l6ZV90IGxlbiwgdW5zaWduZWQgbG9uZyBmbGFncykgew0KKwkv KiBOVUxMIGxldCBnZW5xIHRha2UgYWxsIGNvZWYgYXMgMSAqLw0KKwlyZXR1cm4gcmVfanJfcHJl cF9nZW5xKGNoYW4sIGRlc3QsIHNyYywgc3JjX2NudCwgTlVMTCwgbGVuLCBmbGFncyk7IH0NCisN CisvKg0KKyAqIFByZXAgZnVuY3Rpb24gZm9yIFAvUSBwYXJpdHkgY2FsY3VsYXRpb24uSW4gUkFJ RCBFbmdpbmUgdGVybWlub2xvZ3ksDQorICogUC9RIGNhbGN1bGF0aW9uIGlzIGNhbGxlZCBHZW5R USBkb25lIHRocm91Z2ggR2VuUVEgY29tbWFuZCAgKi8gDQorc3RhdGljIHN0cnVjdCBkbWFfYXN5 bmNfdHhfZGVzY3JpcHRvciAqcmVfanJfcHJlcF9wcSgNCisJCXN0cnVjdCBkbWFfY2hhbiAqY2hh biwgZG1hX2FkZHJfdCAqZGVzdCwgZG1hX2FkZHJfdCAqc3JjLA0KKwkJdW5zaWduZWQgaW50IHNy Y19jbnQsIGNvbnN0IHVuc2lnbmVkIGNoYXIgKnNjZiwgc2l6ZV90IGxlbiwNCisJCXVuc2lnbmVk IGxvbmcgZmxhZ3MpDQorew0KKwlzdHJ1Y3QgcmVfanIgKmpyID0gTlVMTDsNCisJc3RydWN0IGZz bF9yZV9kbWFfYXN5bmNfdHhfZGVzYyAqZGVzYyA9IE5VTEw7DQorCXN0cnVjdCBwcV9jZGIgKnBx ID0gTlVMTDsNCisJc3RydWN0IGNtcG5kX2ZyYW1lICpjZjsNCisJdTggKnA7DQorCWludCBnZm1x X2xlbiwgaSwgajsNCisNCisJaWYgKGxlbiA+IE1BWF9EQVRBX0xFTkdUSCkgew0KKwkJcHJfZXJy KCIlczogTGVuZ3RoIGdyZWF0ZXIgdGhhbiAlZCBub3Qgc3VwcG9ydGVkXG4iLA0KKwkJCQlfX2Z1 bmNfXywgTUFYX0RBVEFfTEVOR1RIKTsNCisJCXJldHVybiBOVUxMOw0KKwl9DQorDQorCS8qDQor CSAqIFJFIHJlcXVpcmVzIGF0IGxlYXN0IDIgc291cmNlcywgaWYgZ2l2ZW4gb25seSBvbmUgc291 cmNlLCB3ZSBwYXNzIHRoZQ0KKwkgKiBzZWNvbmQgc291cmNlIHNhbWUgYXMgdGhlIGZpcnN0IG9u ZS4NCisJICogV2l0aCBvbmx5IG9uZSBzb3VyY2UsIGdlbmVyYXRlIFAgaXMgbWVhbmluZ2xlc3Ms IG9ubHkgY2FyZSBRLg0KKwkgKi8NCisJaWYgKHNyY19jbnQgPT0gMSkgew0KKwkJc3RydWN0IGRt YV9hc3luY190eF9kZXNjcmlwdG9yICp0eCA9IE5VTEw7DQorCQlkbWFfYWRkcl90IGRtYV9zcmNb Ml07DQorCQl1bnNpZ25lZCBjaGFyIGNvZWZbMl07DQorCQlkbWFfc3JjWzBdID0gKnNyYzsNCisJ CWNvZWZbMF0gPSAqc2NmOw0KKwkJZG1hX3NyY1sxXSA9ICpzcmM7DQorCQljb2VmWzFdID0gMDsN CisJCXR4ID0gcmVfanJfcHJlcF9nZW5xKGNoYW4sIGRlc3RbMV0sIGRtYV9zcmMsIDIsIGNvZWYs IGxlbiwNCisJCQkJZmxhZ3MpOw0KKwkJaWYgKHR4KSB7DQorCQkJZGVzYyA9IHRvX2ZzbF9yZV9k bWFfZGVzYyh0eCk7DQorCQkJZGVzYy0+c3JjX2NudCA9IDE7DQorCQl9DQorCQlyZXR1cm4gdHg7 DQorCX0NCisNCisJLyoNCisJICogRHVyaW5nIFJBSUQ2IGFycmF5IGNyZWF0aW9uLCBMaW51eCdz IE1EIGxheWVyIGdldHMgUCBhbmQgUQ0KKwkgKiBjYWxjdWxhdGVkIHNlcGFyYXRlbHkgaW4gdHdv IHN0ZXBzLiBCdXQgb3VyIFJBSUQgRW5naW5lIGhhcw0KKwkgKiB0aGUgY2FwYWJpbGl0eSB0byBj YWxjdWxhdGUgYm90aCBQIGFuZCBRIHdpdGggYSBzaW5nbGUgY29tbWFuZA0KKwkgKiBIZW5jZSB0 byBtZXJnZSB3ZWxsIHdpdGggTUQgbGF5ZXIsIHdlIG5lZWQgdG8gcHJvdmlkZSBhIGhvb2sNCisJ ICogaGVyZSBhbmQgY2FsbCByZV9qcV9wcmVwX2dlbnEoKSBmdW5jdGlvbg0KKwkgKi8NCisNCisJ aWYgKGZsYWdzICYgRE1BX1BSRVBfUFFfRElTQUJMRV9QKQ0KKwkJcmV0dXJuIHJlX2pyX3ByZXBf Z2VucShjaGFuLCBkZXN0WzFdLCBzcmMsIHNyY19jbnQsDQorCQkJCXNjZiwgbGVuLCBmbGFncyk7 DQorDQorCWpyID0gY29udGFpbmVyX29mKGNoYW4sIHN0cnVjdCByZV9qciwgY2hhbik7DQorCWRl c2MgPSByZV9qcl9hbGxvY19kZXNjKGpyLCBmbGFncyk7DQorCWlmICghZGVzYyB8fCBkZXNjIDwg MCkNCisJCXJldHVybiBOVUxMOw0KKw0KKwlkZXNjLT5kbWFfbGVuID0gbGVuOw0KKwlkZXNjLT5k ZXN0X2NudCA9IDI7DQorCWRlc2MtPnNyY19jbnQgPSBzcmNfY250Ow0KKw0KKwlkZXNjLT5jZGJf b3Bjb2RlID0gUkVfUFFfT1BDT0RFOw0KKwlkZXNjLT5jZGJfbGVuID0gc2l6ZW9mKHN0cnVjdCBw cV9jZGIpOw0KKw0KKwkvKiBGaWxsaW5nIEdlblFRIENEQiAqLw0KKwlwcSA9IGRlc2MtPmNkYl9h ZGRyOw0KKwlwcS0+b3Bjb2RlID0gUkVfUFFfT1BDT0RFOw0KKwlwcS0+YmxrX3NpemUgPSBSRV9C TE9DS19TSVpFOw0KKwlwcS0+YnVmZmVyX2F0dHJpYiA9IEJVRkZFUkFCTEVfT1VUUFVUOw0KKwlw cS0+ZGF0YV9kZXBlbmQgPSBEQVRBX0RFUEVOREVOQ1k7DQorCXBxLT5ucmNzID0gKHNyY19jbnQg LSAxKTsNCisNCisJcCA9IHBxLT5nZm1fcTE7DQorCS8qIEluaXQgZ2ZtX3ExW10gKi8NCisJZm9y IChpID0gMDsgaSA8IHNyY19jbnQ7IGkrKykNCisJCXBbaV0gPSAxOw0KKw0KKwkvKiBBbGlnbiBn Zm1bXSB0byAzMmJpdCAqLw0KKwlnZm1xX2xlbiA9ICgoc3JjX2NudCszKS80KSo0Ow0KKw0KKwkv KiBJbml0IGdmbV9xMltdICovDQorCXAgKz0gZ2ZtcV9sZW47DQorCWZvciAoaSA9IDA7IGkgPCBz cmNfY250OyBpKyspDQorCQlwW2ldID0gc2NmW2ldOw0KKw0KKwkvKiBGaWxsaW5nIGZyYW1lIDAg b2YgY29tcG91bmQgZnJhbWUgZGVzY3JpcHRvciB3aXRoIENEQiAqLw0KKwljZiA9IGRlc2MtPmNm X2FkZHI7DQorCWZpbGxfY2ZkX2ZyYW1lKGNmLCAwLCBkZXNjLT5jZGJfbGVuLCBkZXNjLT5jZGJf cGFkZHIsIDApOw0KKw0KKwkvKiBGaWxsIENGRCdzIDFzdCAmIDJuZCBmcmFtZSB3aXRoIGRlc3Qg YnVmZmVycyAqLw0KKwlmb3IgKGkgPSAxLCBqID0gMDsgaSA8IDM7IGkrKywgaisrKQ0KKwkJZmls bF9jZmRfZnJhbWUoY2YsIGksIGxlbiwgZGVzdFtqXSwgMCk7DQorDQorCS8qIEZpbGwgQ0ZEJ3Mg cmVzdCBvZiB0aGUgZnJhbWVzIHdpdGggc291cmNlIGJ1ZmZlcnMgKi8NCisJZm9yIChpID0gMywg aiA9IDA7IGogPCBzcmNfY250OyBpKyssIGorKykNCisJCWZpbGxfY2ZkX2ZyYW1lKGNmLCBpLCBs ZW4sIHNyY1tqXSwgMCk7DQorDQorCS8qIFNldHRpbmcgdGhlIGZpbmFsIGJpdCBpbiB0aGUgbGFz dCBzb3VyY2UgYnVmZmVyIGZyYW1lIGluIENGRCAqLw0KKwljZltpIC0gMV0uZmluYWwgPSAxOw0K Kw0KKwlyZXR1cm4gJmRlc2MtPmFzeW5jX3R4Ow0KK30NCisNCisvKg0KKyAqIFByZXAgZnVuY3Rp b24gZm9yIG1lbWNweS4gSW4gUkFJRCBFbmdpbmUsIG1lbWNweSBpcyBkb25lIHRocm91Z2ggDQor TU9WRQ0KKyAqIGNvbW1hbmQuIExvZ2ljIG9mIHRoaXMgZnVuY3Rpb24gd2lsbCBuZWVkIHRvIGJl IG1vZGlmaWVkIG9uY2UgDQorbXVsdGlwYWdlDQorICogc3VwcG9ydCBpcyBhZGRlZCBpbiBMaW51 eCdzIE1EL0FTWU5DIExheWVyICAqLyBzdGF0aWMgc3RydWN0IA0KK2RtYV9hc3luY190eF9kZXNj cmlwdG9yICpyZV9qcl9wcmVwX21lbWNweSgNCisJCXN0cnVjdCBkbWFfY2hhbiAqY2hhbiwgZG1h X2FkZHJfdCBkZXN0LCBkbWFfYWRkcl90IHNyYywNCisJCXNpemVfdCBsZW4sIHVuc2lnbmVkIGxv bmcgZmxhZ3MpDQorew0KKwlzdHJ1Y3QgcmVfanIgKmpyID0gTlVMTDsNCisJc3RydWN0IGZzbF9y ZV9kbWFfYXN5bmNfdHhfZGVzYyAqZGVzYyA9IE5VTEw7DQorCXNpemVfdCBsZW5ndGggPSAwOw0K KwlzdHJ1Y3QgY21wbmRfZnJhbWUgKmNmID0gTlVMTDsNCisJc3RydWN0IG1vdmVfY2RiICptb3Zl ID0gTlVMTDsNCisNCisJanIgPSBjb250YWluZXJfb2YoY2hhbiwgc3RydWN0IHJlX2pyLCBjaGFu KTsNCisNCisJaWYgKGxlbiA+IE1BWF9EQVRBX0xFTkdUSCkgew0KKwkJcHJfZXJyKCIlczogTGVu Z3RoIGdyZWF0ZXIgdGhhbiAlZCBub3Qgc3VwcG9ydGVkXG4iLA0KKwkJCQlfX2Z1bmNfXywgTUFY X0RBVEFfTEVOR1RIKTsNCisJCXJldHVybiBOVUxMOw0KKwl9DQorDQorCWRlc2MgPSByZV9qcl9h bGxvY19kZXNjKGpyLCBmbGFncyk7DQorCWlmICghZGVzYyB8fCBkZXNjIDwgMCkNCisJCXJldHVy biBOVUxMOw0KKw0KKwlkZXNjLT5kbWFfbGVuID0gbGVuOw0KKwlkZXNjLT5zcmNfY250ID0gMTsN CisJZGVzYy0+ZGVzdF9jbnQgPSAxOw0KKw0KKwlkZXNjLT5jZGJfb3Bjb2RlID0gUkVfTU9WRV9P UENPREU7DQorCWRlc2MtPmNkYl9sZW4gPSBzaXplb2Yoc3RydWN0IG1vdmVfY2RiKTsNCisNCisJ LyogRmlsbGluZyBtb3ZlIENEQiAqLw0KKwltb3ZlID0gZGVzYy0+Y2RiX2FkZHI7DQorCW1vdmUt Pm9wY29kZSA9IFJFX01PVkVfT1BDT0RFOyAvKiBVbmljYXN0IG1vdmUgKi8NCisJbW92ZS0+Ymxr X3NpemUgPSBSRV9CTE9DS19TSVpFOw0KKwltb3ZlLT5lcnJvcl9hdHRyaWIgPSBJTlRFUlJVUFRf T05fRVJST1I7DQorCW1vdmUtPmRhdGFfZGVwZW5kID0gREFUQV9ERVBFTkRFTkNZOw0KKw0KKwkv KiBGaWxsaW5nIGZyYW1lIDAgb2YgQ0ZEIHdpdGggbW92ZSBDREIgKi8NCisJY2YgPSBkZXNjLT5j Zl9hZGRyOw0KKwlmaWxsX2NmZF9mcmFtZShjZiwgMCwgZGVzYy0+Y2RiX2xlbiwgZGVzYy0+Y2Ri X3BhZGRyLCAwKTsNCisNCisJbGVuZ3RoID0gbWluX3Qoc2l6ZV90LCBsZW4sIE1BWF9EQVRBX0xF TkdUSCk7DQorDQorCS8qIEZpbGwgQ0ZEJ3MgMXN0IGZyYW1lIHdpdGggZGVzdCBidWZmZXIgKi8N CisJZmlsbF9jZmRfZnJhbWUoY2YsIDEsIGxlbmd0aCwgZGVzdCwgMCk7DQorDQorCS8qIEZpbGwg Q0ZEJ3MgMm5kIGZyYW1lIHdpdGggc3JjIGJ1ZmZlciAqLw0KKwlmaWxsX2NmZF9mcmFtZShjZiwg MiwgbGVuZ3RoLCBzcmMsIDEpOw0KKw0KKwlyZXR1cm4gJmRlc2MtPmFzeW5jX3R4Ow0KK30NCisN CitzdGF0aWMgaW50IHJlX2pyX2FsbG9jX2NoYW5fcmVzb3VyY2VzKHN0cnVjdCBkbWFfY2hhbiAq Y2hhbikgew0KKwlpbnQgaTsNCisJc3RydWN0IGZzbF9yZV9kbWFfYXN5bmNfdHhfZGVzYyAqZGVz YzsNCisJc3RydWN0IHJlX2pyICpqciA9IGNvbnRhaW5lcl9vZihjaGFuLCBzdHJ1Y3QgcmVfanIs IGNoYW4pOw0KKwl2b2lkICpjZiA9IE5VTEw7DQorCWRtYV9hZGRyX3QgcGFkZHI7DQorDQorCWpy LT5kZXNjcyA9IGt6YWxsb2Moc2l6ZW9mKCpkZXNjKSAqIFJJTkdfU0laRSwgR0ZQX0tFUk5FTCk7 DQorCWlmICghanItPmRlc2NzKSB7DQorCQlkZXZfZXJyKGpyLT5kZXYsICIlczogTm8gbWVtb3J5 IGZvciBzdyBkZXNjcmlwdG9yIHJpbmdcbiIsDQorCQkJX19mdW5jX18pOw0KKwkJZ290byBlcnJf ZnJlZTsNCisJfQ0KKw0KKwljZiA9IGRtYV9wb29sX2FsbG9jKGpyLT5yZV9kZXYtPmRlc2NfcG9v bCwgR0ZQX0FUT01JQywgJnBhZGRyKTsNCisJaWYgKCFjZikgew0KKwkJZGV2X2Vycihqci0+ZGV2 LCAiJXM6IE5vIG1lbW9yeSBmb3IgZG1hIGRlc2NyaXB0b3IgcmluZ1xuIiwNCisJCQlfX2Z1bmNf Xyk7DQorCQlnb3RvIGVycl9mcmVlOw0KKwl9DQorCW1lbXNldChjZiwgMCwgUkVfQ0ZfQ0RCX1NJ WkUgKiBSSU5HX1NJWkUpOw0KKwlqci0+Y2ZzID0gY2Y7DQorCWpyLT5waHlzID0gcGFkZHI7DQor DQorCWZvciAoaSA9IDA7IGkgPCBSSU5HX1NJWkU7IGkrKykgew0KKwkJdTMyIG9mZnNldCA9IGkg KiBSRV9DRl9DREJfU0laRTsNCisJCWRlc2MgPSAmanItPmRlc2NzW2ldOw0KKwkJZGVzYy0+aHdk ZXNjID0gJmpyLT5pbmJfcmluZ192aXJ0X2FkZHJbaV07DQorCQlyZV9qcl9pbml0X2Rlc2MoanIs IGRlc2MsIGNmICsgb2Zmc2V0LCBwYWRkciArIG9mZnNldCk7DQorCQlkZXNjLT5zdGF0ZSA9IFJF X0RFU0NfRU1QVFk7DQorCX0NCisJcmV0dXJuIDA7DQorDQorZXJyX2ZyZWU6DQorCWtmcmVlKGpy LT5kZXNjcyk7DQorCXJldHVybiAtRU5PTUVNOw0KK30NCisNCitzdGF0aWMgdm9pZCByZV9qcl9m cmVlX2NoYW5fcmVzb3VyY2VzKHN0cnVjdCBkbWFfY2hhbiAqY2hhbikgew0KKwlzdHJ1Y3QgcmVf anIgKmpyID0gY29udGFpbmVyX29mKGNoYW4sIHN0cnVjdCByZV9qciwgY2hhbik7DQorCWRtYV9w b29sX2ZyZWUoanItPnJlX2Rldi0+ZGVzY19wb29sLCBqci0+Y2ZzLCBqci0+cGh5cyk7DQorCWtm cmVlKGpyLT5kZXNjcyk7DQorCXJldHVybjsNCit9DQorDQoraW50IHJlX2pyX3Byb2JlKHN0cnVj dCBwbGF0Zm9ybV9kZXZpY2UgKm9mZGV2LA0KKwkJc3RydWN0IGRldmljZV9ub2RlICpucCwgdTgg cSwgdTMyICpvZmYpIHsNCisJc3RydWN0IGRldmljZSAqZGV2ID0gTlVMTDsNCisJc3RydWN0IHJl X2Rydl9wcml2YXRlICpyZXByaXYgPSBOVUxMOw0KKwlzdHJ1Y3QgcmVfanIgKmpyID0gTlVMTDsN CisJc3RydWN0IGRtYV9kZXZpY2UgKmRtYV9kZXYgPSBOVUxMOw0KKwl1MzIgKnB0ciA9IE5VTEw7 DQorCXUzMiBzdGF0dXM7DQorCWludCByZXQgPSAwOw0KKwlzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNl ICpqcl9vZmRldiA9IE5VTEw7DQorDQorCWRldiA9ICZvZmRldi0+ZGV2Ow0KKwlyZXByaXYgPSBk ZXZfZ2V0X2RydmRhdGEoZGV2KTsNCisJZG1hX2RldiA9ICZyZXByaXYtPmRtYV9kZXY7DQorDQor CWpyID0ga3phbGxvYyhzaXplb2Yoc3RydWN0IHJlX2pyKSwgR0ZQX0tFUk5FTCk7DQorCWlmICgh anIpIHsNCisJCWRldl9lcnIoZGV2LCAiJXM6IE5vIGZyZWUgbWVtb3J5IGZvciBhbGxvY2F0aW5n IEpSIHN0cnVjdFxuIiwNCisJCQlfX2Z1bmNfXyk7DQorCQlyZXR1cm4gLUVOT01FTTsNCisJfQ0K Kw0KKwlqcl9vZmRldiA9IG9mX3BsYXRmb3JtX2RldmljZV9jcmVhdGUobnAsIE5VTEwsIGRldik7 DQorCWlmIChqcl9vZmRldiA9PSBOVUxMKSB7DQorCQlkZXZfZXJyKGRldiwgIiVzOiBOb3QgYWJs ZSB0byBjcmVhdGUgb2ZkZXYgZm9yIGpyICVkXG4iLA0KKwkJCV9fZnVuY19fLCBxKTsNCisJCXJl dCA9IC1FSU5WQUw7DQorCQlnb3RvIGVycl9mcmVlOw0KKwl9DQorCWRldl9zZXRfZHJ2ZGF0YSgm anJfb2ZkZXYtPmRldiwganIpOw0KKw0KKwlwdHIgPSAodTMyICopb2ZfZ2V0X3Byb3BlcnR5KG5w LCAicmVnIiwgTlVMTCk7DQorCWlmICghcHRyKSB7DQorCQlkZXZfZXJyKGRldiwgIiVzOiBSZWcg cHJvcGVydHkgbm90IGZvdW5kIGluIEpSIG51bWJlciAlZFxuIiwNCisJCQlfX2Z1bmNfXywgcSk7 DQorCQlyZXQgPSAtRU5PREVWOw0KKwkJZ290byBlcnJfZnJlZTsNCisJfQ0KKw0KKwlqci0+anJy ZWdzID0gKHN0cnVjdCBqcl9jb25maWdfcmVncyAqKSgodTggKilyZXByaXYtPnJlX3JlZ3MgKw0K KwkJCSpvZmYgKyAqcHRyKTsNCisNCisJanItPmlycSA9IGlycV9vZl9wYXJzZV9hbmRfbWFwKG5w LCAwKTsNCisJaWYgKGpyLT5pcnEgPT0gTk9fSVJRKSB7DQorCQlkZXZfZXJyKGRldiwgIiVzOiBO byBJUlEgZGVmaW5lZCBmb3IgSlIgJWRcbiIsIF9fZnVuY19fLCBxKTsNCisJCXJldCA9IC1FTk9E RVY7DQorCQlnb3RvIGVycl9mcmVlOw0KKwl9DQorDQorCXRhc2tsZXRfaW5pdCgmanItPmlycXRh c2ssIHJlX2pyX2RlcXVldWUsDQorCQkJKHVuc2lnbmVkIGxvbmcpJmpyX29mZGV2LT5kZXYpOw0K Kw0KKwlyZXQgPSByZXF1ZXN0X2lycShqci0+aXJxLCByZV9qcl9pbnRlcnJ1cHQsIDAsICJyZS1q ciIsICZqcl9vZmRldi0+ZGV2KTsNCisJaWYgKHJldCkgew0KKwkJZGV2X2VycihkZXYsICIlczog VW5hYmxlIHRvIHJlZ2lzdGVyIEpSIGludGVycnVwdCBmb3IgSlIgJWRcbiIsDQorCQkJX19mdW5j X18sIHEpOw0KKwkJcmV0ID0gLUVJTlZBTDsNCisJCWdvdG8gZXJyX2ZyZWU7DQorCX0NCisNCisJ cmVwcml2LT5yZV9qcnNbcV0gPSBqcjsNCisJanItPmNoYW4uZGV2aWNlID0gZG1hX2RldjsNCisJ anItPmNoYW4ucHJpdmF0ZSA9IGpyOw0KKwlqci0+ZGV2ID0gJmpyX29mZGV2LT5kZXY7DQorCWpy LT5yZV9kZXYgPSByZXByaXY7DQorCWpyLT5wZW5kX2NvdW50ID0gMDsNCisJSU5JVF9MSVNUX0hF QUQoJmpyLT5hY2tfcSk7DQorCXNwaW5fbG9ja19pbml0KCZqci0+ZGVzY19sb2NrKTsNCisJc3Bp bl9sb2NrX2luaXQoJmpyLT5pbmJfbG9jayk7DQorCXNwaW5fbG9ja19pbml0KCZqci0+b3ViX2xv Y2spOw0KKw0KKwlpbml0X3RpbWVyKCZqci0+dGltZXIpOw0KKwlqci0+dGltZXIuZXhwaXJlcyA9 IGppZmZpZXMgKyAxMCpIWjsNCisJanItPnRpbWVyLmZ1bmN0aW9uID0gcmFpZGVfdGltZXJfaGFu ZGxlcjsNCisNCisJbGlzdF9hZGRfdGFpbCgmanItPmNoYW4uZGV2aWNlX25vZGUsICZkbWFfZGV2 LT5jaGFubmVscyk7DQorCWRtYV9kZXYtPmNoYW5jbnQrKzsNCisNCisJanItPmluYl9yaW5nX3Zp cnRfYWRkciA9IGRtYV9wb29sX2FsbG9jKGpyLT5yZV9kZXYtPmh3X2Rlc2NfcG9vbCwNCisJCUdG UF9BVE9NSUMsICZqci0+aW5iX3BoeXNfYWRkcik7DQorDQorCWlmICghanItPmluYl9yaW5nX3Zp cnRfYWRkcikgew0KKwkJZGV2X2VycihkZXYsICIlczpObyBkbWEgbWVtb3J5IGZvciBpbmJfcmlu Z192aXJ0X2FkZHJcbiIsDQorCQkJX19mdW5jX18pOw0KKwkJcmV0ID0gLUVOT01FTTsNCisJCWdv dG8gZXJyX2ZyZWU7DQorCX0NCisNCisJanItPm91Yl9yaW5nX3ZpcnRfYWRkciA9IGRtYV9wb29s X2FsbG9jKGpyLT5yZV9kZXYtPmh3X2Rlc2NfcG9vbCwNCisJCUdGUF9BVE9NSUMsICZqci0+b3Vi X3BoeXNfYWRkcik7DQorDQorCWlmICghanItPm91Yl9yaW5nX3ZpcnRfYWRkcikgew0KKwkJZGV2 X2VycihkZXYsICIlczpObyBkbWEgbWVtb3J5IGZvciBvdWJfcmluZ192aXJ0X2FkZHJcbiIsDQor CQkJX19mdW5jX18pOw0KKwkJcmV0ID0gLUVOT01FTTsNCisJCWdvdG8gZXJyX2ZyZWU7DQorCX0N CisNCisJanItPmluYl9jb3VudCA9IDA7DQorCWpyLT5wZW5kX2NvdW50ID0gMDsNCisJanItPm91 Yl9jb3VudCA9IDA7DQorDQorCXN0YXR1cyA9IGluX2JlMzIoJmpyLT5qcnJlZ3MtPmpyX3N0YXR1 cyk7DQorDQorCWlmIChzdGF0dXMgJiBSRV9KUl9QQVVTRSkgew0KKwkJZGV2X2luZm8oZGV2LCAi JXM6IEpSIGlzIGluIHBhdXNlZCBzdGF0ZS4uLmVuYWJsZSBpdFxuIiwNCisJCQlfX2Z1bmNfXyk7 DQorCX0gZWxzZSB7DQorCQlkZXZfZXJyKGRldiwgIiVzOiBFcnJvcjotIEpSIHNodWQgYmUgaW4g cGF1c2VkIHN0YXRlXG4iLA0KKwkJCV9fZnVuY19fKTsNCisJCXJldCA9IC1FSU5WQUw7DQorCQln b3RvIHBvb2xfZnJlZTsNCisJfQ0KKw0KKwkvKiBQcm9ncmFtIHRoZSBJbmJvdW5kL091dGJvdW5k IHJpbmcgYmFzZSBhZGRyZXNzZXMgYW5kIHNpemUgKi8NCisJb3V0X2JlMzIoJmpyLT5qcnJlZ3Mt PmluYnJpbmdfYmFzZV9oLA0KKwkJCWpyLT5pbmJfcGh5c19hZGRyICYgUkVfSlJfQUREUkVTU19C SVRfTUFTSyk7DQorCW91dF9iZTMyKCZqci0+anJyZWdzLT5vdWJyaW5nX2Jhc2VfaCwNCisJCQlq ci0+b3ViX3BoeXNfYWRkciAmIFJFX0pSX0FERFJFU1NfQklUX01BU0spOw0KKwlvdXRfYmUzMigm anItPmpycmVncy0+aW5icmluZ19iYXNlX2wsDQorCQkJanItPmluYl9waHlzX2FkZHIgPj4gUkVf SlJfQUREUkVTU19CSVRfU0hJRlQpOw0KKwlvdXRfYmUzMigmanItPmpycmVncy0+b3VicmluZ19i YXNlX2wsDQorCQkJanItPm91Yl9waHlzX2FkZHIgPj4gUkVfSlJfQUREUkVTU19CSVRfU0hJRlQp Ow0KKwlvdXRfYmUzMigmanItPmpycmVncy0+aW5icmluZ19zaXplLCBSSU5HX1NJWkUgPDwgUklO R19TSVpFX1NISUZUKTsNCisJb3V0X2JlMzIoJmpyLT5qcnJlZ3MtPm91YnJpbmdfc2l6ZSwgUklO R19TSVpFIDw8IFJJTkdfU0laRV9TSElGVCk7DQorDQorCS8qIFJlYWQgTElPRE4gdmFsdWUgZnJv bSB1LWJvb3QgKi8NCisJc3RhdHVzID0gaW5fYmUzMigmanItPmpycmVncy0+anJfY29uZmlnXzEp ICYgUkVfSlJfUkVHX0xJT0ROX01BU0s7DQorDQorCS8qIFByb2dyYW0gdGhlIENGRyByZWcgKi8N CisJb3V0X2JlMzIoJmpyLT5qcnJlZ3MtPmpyX2NvbmZpZ18xLA0KKwkJCVJFX0pSX0NGRzFfQ0JT SSB8IFJFX0pSX0NGRzFfQ0JTMCB8IHN0YXR1cyk7DQorDQorCS8qIEVuYWJsZSBSRS9KUiAqLw0K KwlvdXRfYmUzMigmanItPmpycmVncy0+anJfY29tbWFuZCwgUkVfSlJfRU5BQkxFKTsNCisNCisJ cmV0dXJuIDA7DQorDQorcG9vbF9mcmVlOg0KKwlkbWFfcG9vbF9mcmVlKGpyLT5yZV9kZXYtPmh3 X2Rlc2NfcG9vbCwganItPmluYl9yaW5nX3ZpcnRfYWRkciwNCisJCQlqci0+aW5iX3BoeXNfYWRk cik7DQorZXJyX2ZyZWU6DQorCWtmcmVlKGpyKTsNCisJcmV0dXJuIHJldDsNCit9DQorDQorLyog UHJvYmUgZnVuY3Rpb24gZm9yIFJBSUQgRW5naW5lICovDQorc3RhdGljIGludCBfX2RldmluaXQg cmFpZGVfcHJvYmUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqb2ZkZXYpIHsNCisJc3RydWN0IHJl X2Rydl9wcml2YXRlICpyZXByaXYgPSBOVUxMOw0KKwlzdHJ1Y3QgZGV2aWNlICpkZXYgPSBOVUxM Ow0KKwlzdHJ1Y3QgZGV2aWNlX25vZGUgKm5wID0gTlVMTDsNCisJc3RydWN0IGRldmljZV9ub2Rl ICpjaGlsZCA9IE5VTEw7DQorCXUzMiAqb2ZmID0gTlVMTDsNCisJdTggcmlkeCA9IDA7DQorCXN0 cnVjdCBkbWFfZGV2aWNlICpkbWFfZGV2ID0gTlVMTDsNCisJaW50IHJldCA9IDA7DQorDQorCWRl dl9pbmZvKCZvZmRldi0+ZGV2LCAiRnJlZXNjYWxlIFJBSUQgRW5naW5lIGRyaXZlclxuIik7DQor DQorCXJlcHJpdiA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCByZV9kcnZfcHJpdmF0ZSksIEdGUF9L RVJORUwpOw0KKwlpZiAoIXJlcHJpdikgew0KKwkJZGV2X2VycihkZXYsICIlczogTm8gbWVtb3J5 IGZvciByZXByaXZcbiIsIF9fZnVuY19fKTsNCisJCXJldHVybiAtRU5PTUVNOw0KKwl9DQorDQor CWRldiA9ICZvZmRldi0+ZGV2Ow0KKwlkZXZfc2V0X2RydmRhdGEoZGV2LCByZXByaXYpOw0KKw0K KwkvKiBJT01BUCB0aGUgZW50aXJlIFJBSUQgRW5naW5lIHJlZ2lvbiAqLw0KKwlyZXByaXYtPnJl X3JlZ3MgPSBvZl9pb21hcChvZmRldi0+ZGV2Lm9mX25vZGUsIDApOw0KKwlpZiAocmVwcml2LT5y ZV9yZWdzID09IE5VTEwpIHsNCisJCWRldl9lcnIoZGV2LCAiJXM6IG9mX2lvbWFwIGZhaWxlZFxu IiwgX19mdW5jX18pOw0KKwkJa2ZyZWUocmVwcml2KTsNCisJCXJldCA9IC1FTk9NRU07DQorCQln b3RvIGVycl9mcmVlXzQ7DQorCX0NCisNCisJLyogUHJpbnQgdGhlIFJFIHZlcnNpb24gdG8gbWFr ZSBzdXJlIFJFIGlzIGFsaXZlICovDQorCWRldl9pbmZvKGRldiwgIlZlciA9ICV4XG4iLCBpbl9i ZTMyKCZyZXByaXYtPnJlX3JlZ3MtPnJlX3ZlcnNpb25faWQpKTsNCisNCisJLyogUHJvZ3JhbSB0 aGUgUkUgbW9kZSAqLw0KKwlvdXRfYmUzMigmcmVwcml2LT5yZV9yZWdzLT5nbG9iYWxfY29uZmln LCBSRV9OT05fRFBBQV9NT0RFKTsNCisJZGV2X2luZm8oZGV2LCAiJXM6UkUgbW9kZSBpcyAleFxu IiwgX19mdW5jX18sDQorCQkJaW5fYmUzMigmcmVwcml2LT5yZV9yZWdzLT5nbG9iYWxfY29uZmln KSk7DQorDQorCS8qIFByb2dyYW0gR2Fsb2lzIEZpZWxkIHBvbHlub21pYWwgKi8NCisJb3V0X2Jl MzIoJnJlcHJpdi0+cmVfcmVncy0+Z2Fsb2lzX2ZpZWxkX2NvbmZpZywgUkVfR0ZNX1BPTFkpOw0K KwlkZXZfaW5mbyhkZXYsICIlczpHYWxvaXMgRmllbGQgUG9seW5vbWlhbCBpcyAleFxuIiwgX19m dW5jX18sDQorCQkJaW5fYmUzMigmcmVwcml2LT5yZV9yZWdzLT5nYWxvaXNfZmllbGRfY29uZmln KSk7DQorDQorCWRtYV9kZXYgPSAmcmVwcml2LT5kbWFfZGV2Ow0KKwlkbWFfZGV2LT5kZXYgPSBk ZXY7DQorCUlOSVRfTElTVF9IRUFEKCZkbWFfZGV2LT5jaGFubmVscyk7DQorCWRtYV9zZXRfbWFz ayhkZXYsIERNQV9CSVRfTUFTSyg0MCkpOw0KKw0KKwlkbWFfZGV2LT5kZXZpY2VfYWxsb2NfY2hh bl9yZXNvdXJjZXMgPSByZV9qcl9hbGxvY19jaGFuX3Jlc291cmNlczsNCisJZG1hX2Rldi0+ZGV2 aWNlX3R4X3N0YXR1cyA9IHJlX2pyX3R4X3N0YXR1czsNCisJZG1hX2Rldi0+ZGV2aWNlX2lzc3Vl X3BlbmRpbmcgPSByZV9qcl9pc3N1ZV9wZW5kaW5nOw0KKw0KKwlkbWFfZGV2LT5tYXhfeG9yID0g TUFYX1hPUl9TUkNTOw0KKwlkbWFfZGV2LT5kZXZpY2VfcHJlcF9kbWFfeG9yID0gcmVfanJfcHJl cF9kbWFfeG9yOw0KKwlkbWFfY2FwX3NldChETUFfWE9SLCBkbWFfZGV2LT5jYXBfbWFzayk7DQor DQorCWRtYV9kZXYtPm1heF9wcSA9IE1BWF9QUV9TUkNTOw0KKwlkbWFfZGV2LT5kZXZpY2VfcHJl cF9kbWFfcHEgPSByZV9qcl9wcmVwX3BxOw0KKwlkbWFfY2FwX3NldChETUFfUFEsIGRtYV9kZXYt PmNhcF9tYXNrKTsNCisNCisJZG1hX2Rldi0+ZGV2aWNlX3ByZXBfZG1hX21lbWNweSA9IHJlX2py X3ByZXBfbWVtY3B5Ow0KKwlkbWFfY2FwX3NldChETUFfTUVNQ1BZLCBkbWFfZGV2LT5jYXBfbWFz ayk7DQorDQorCWRtYV9kZXYtPmRldmljZV9mcmVlX2NoYW5fcmVzb3VyY2VzID0gcmVfanJfZnJl ZV9jaGFuX3Jlc291cmNlczsNCisNCisJcmVwcml2LT50b3RhbF9qcnMgPSAwOw0KKw0KKwlyZXBy aXYtPmRlc2NfcG9vbCA9IGRtYV9wb29sX2NyZWF0ZSgicmVfZG1hX2Rlc2NfcG9vbCIsIGRldiwN CisJCQkJCVJFX0NGX0NEQl9TSVpFICogUklOR19TSVpFLA0KKwkJCQkJUkVfQ0ZfQ0RCX0FMSUdO LCAwKTsNCisNCisJaWYgKCFyZXByaXYtPmRlc2NfcG9vbCkgew0KKwkJcHJfZXJyKCIlczpObyBt ZW1vcnkgZm9yIGRtYSBkZXNjIHBvb2xcbiIsIF9fZnVuY19fKTsNCisJCXJldCA9IC1FTk9NRU07 DQorCQlnb3RvIGVycl9mcmVlXzM7DQorCX0NCisNCisJcmVwcml2LT5od19kZXNjX3Bvb2wgPSBk bWFfcG9vbF9jcmVhdGUoInJlX2h3X2Rlc2NfcG9vbCIsIGRldiwNCisJCQkJc2l6ZW9mKHN0cnVj dCBqcl9od19kZXNjKSAqIFJJTkdfU0laRSwNCisJCQkJRlJBTUVfREVTQ19BTElHTk1FTlQsIDAp Ow0KKwlpZiAoIXJlcHJpdi0+aHdfZGVzY19wb29sKSB7DQorCQlwcl9lcnIoIiVzOk5vIG1lbW9y eSBmb3IgaHcgZGVzYyBwb29sXG4iLCBfX2Z1bmNfXyk7DQorCQlyZXQgPSAtRU5PTUVNOw0KKwkJ Z290byBlcnJfZnJlZV8yOw0KKwl9DQorDQorCS8qIFBhcnNlIERldmljZSB0cmVlIHRvIGZpbmQg b3V0IHRoZSB0b3RhbCBudW1iZXIgb2YgSlFzIHByZXNlbnQgKi8NCisJZm9yX2VhY2hfY29tcGF0 aWJsZV9ub2RlKG5wLCBOVUxMLCAiZnNsLHJhaWRlbmctdjEuMC1qb2ItcXVldWUiKSB7DQorCQlv ZmYgPSAodTMyICopb2ZfZ2V0X3Byb3BlcnR5KG5wLCAicmVnIiwgTlVMTCk7DQorCQlpZiAoIW9m Zikgew0KKwkJCWRldl9lcnIoZGV2LCAiJXM6IFJlZyBwcm9wZXJ0eSBub3QgZm91bmQgaW4gSlEg bm9kZVxuIiwNCisJCQkJX19mdW5jX18pOw0KKwkJCXJldHVybiAtRU5PREVWOw0KKwkJfQ0KKw0K KwkJLyogRmluZCBvdXQgdGhlIEpvYiBSaW5ncyBwcmVzZW50IHVuZGVyIGVhY2ggSlEgKi8NCisJ CWZvcl9lYWNoX2NoaWxkX29mX25vZGUobnAsIGNoaWxkKSB7DQorCQkJaWYgKG9mX2RldmljZV9p c19jb21wYXRpYmxlKGNoaWxkLA0KKwkJCQkiZnNsLHJhaWRlbmctdjEuMC1qb2ItcmluZyIpKSB7 DQorCQkJCXJlX2pyX3Byb2JlKG9mZGV2LCBjaGlsZCwgcmlkeCsrLCBvZmYpOw0KKwkJCQlyZXBy aXYtPnRvdGFsX2pycysrOw0KKwkJCX0NCisJCX0NCisJfQ0KKw0KKwlkbWFfYXN5bmNfZGV2aWNl X3JlZ2lzdGVyKGRtYV9kZXYpOw0KKwlyZXR1cm4gMDsNCisNCitlcnJfZnJlZV8yOg0KKwlkbWFf cG9vbF9kZXN0cm95KHJlcHJpdi0+ZGVzY19wb29sKTsNCitlcnJfZnJlZV8zOg0KKwlpb3VubWFw KHJlcHJpdi0+cmVfcmVncyk7DQorZXJyX2ZyZWVfNDoNCisJa2ZyZWUocmVwcml2KTsNCisNCisJ cmV0dXJuIHJldDsNCit9DQorDQorc3RhdGljIHZvaWQgcmVsZWFzZV9qcihzdHJ1Y3QgcmVfanIg KmpyKSB7DQorCS8qIEZyZWUgdGhlIG1lbW9yeSBhbGxvY2F0ZWQgZnJvbSBETUEgcG9vbHMgYW5k IGRlc3Ryb3kgdGhlbSAqLw0KKwlkbWFfcG9vbF9mcmVlKGpyLT5yZV9kZXYtPmh3X2Rlc2NfcG9v bCwganItPmluYl9yaW5nX3ZpcnRfYWRkciwNCisJCWpyLT5pbmJfcGh5c19hZGRyKTsNCisJa2Zy ZWUoanIpOw0KK30NCisNCitzdGF0aWMgaW50IHJhaWRlX3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1f ZGV2aWNlICpvZmRldikgew0KKwlzdHJ1Y3QgcmVfZHJ2X3ByaXZhdGUgKnJlcHJpdiA9IE5VTEw7 DQorCXN0cnVjdCBkZXZpY2UgKmRldiA9IE5VTEw7DQorCWludCBpOw0KKw0KKwlkZXYgPSAmb2Zk ZXYtPmRldjsNCisJcmVwcml2ID0gZGV2X2dldF9kcnZkYXRhKGRldik7DQorDQorCS8qIENsZWFu dXAgSlIgcmVsYXRlZCBtZW1vcnkgYXJlYXMgKi8NCisJZm9yIChpID0gMDsgaSA8IHJlcHJpdi0+ dG90YWxfanJzOyBpKyspDQorCQlyZWxlYXNlX2pyKHJlcHJpdi0+cmVfanJzW2ldKTsNCisNCisJ ZG1hX3Bvb2xfZGVzdHJveShyZXByaXYtPmh3X2Rlc2NfcG9vbCk7DQorCWRtYV9wb29sX2Rlc3Ry b3kocmVwcml2LT5kZXNjX3Bvb2wpOw0KKw0KKwkvKiBVbnJlZ2lzdGVyIHRoZSBkcml2ZXIgKi8N CisJZG1hX2FzeW5jX2RldmljZV91bnJlZ2lzdGVyKCZyZXByaXYtPmRtYV9kZXYpOw0KKw0KKwkv KiBVbm1hcCB0aGUgUkFJRCBFbmdpbmUgcmVnaW9uICovDQorCWlvdW5tYXAocmVwcml2LT5yZV9y ZWdzKTsNCisNCisJa2ZyZWUocmVwcml2KTsNCisNCisJcmV0dXJuIDA7DQorfQ0KKw0KK3N0YXRp YyBzdHJ1Y3Qgb2ZfZGV2aWNlX2lkIHJhaWRlX2lkc1tdID0gew0KKwl7IC5jb21wYXRpYmxlID0g ImZzbCxyYWlkZW5nLXYxLjAiLCB9LA0KKwl7fQ0KK307DQorDQorc3RhdGljIHN0cnVjdCBwbGF0 Zm9ybV9kcml2ZXIgcmFpZGVfZHJpdmVyID0gew0KKwkuZHJpdmVyID0gew0KKwkJLm5hbWUgPSAi ZnNsLXJhaWRlbmciLA0KKwkJLm93bmVyID0gVEhJU19NT0RVTEUsDQorCQkub2ZfbWF0Y2hfdGFi bGUgPSByYWlkZV9pZHMsDQorCX0sDQorCS5wcm9iZSA9IHJhaWRlX3Byb2JlLA0KKwkucmVtb3Zl ID0gcmFpZGVfcmVtb3ZlLA0KK307DQorDQorc3RhdGljIF9faW5pdCBpbnQgcmFpZGVfaW5pdCh2 b2lkKQ0KK3sNCisJaW50IHJldCA9IDA7DQorDQorCXJldCA9IHBsYXRmb3JtX2RyaXZlcl9yZWdp c3RlcigmcmFpZGVfZHJpdmVyKTsNCisJaWYgKHJldCkNCisJCXByX2VycigiZnNsLXJhaWQ6IEZh aWxlZCB0byByZWdpc3RlciBwbGF0Zm9ybSBkcml2ZXJcbiIpOw0KKw0KKwlyZXR1cm4gcmV0Ow0K K30NCisNCitzdGF0aWMgdm9pZCBfX2V4aXQgcmFpZGVfZXhpdCh2b2lkKQ0KK3sNCisJcGxhdGZv cm1fZHJpdmVyX3VucmVnaXN0ZXIoJnJhaWRlX2RyaXZlcik7DQorfQ0KKw0KK3N1YnN5c19pbml0 Y2FsbChyYWlkZV9pbml0KTsNCittb2R1bGVfZXhpdChyYWlkZV9leGl0KTsNCisNCitNT0RVTEVf QVVUSE9SKCJIYXJuaW5kZXIgUmFpIDxoYXJuaW5kZXIucmFpQGZyZWVzY2FsZS5jb20+Iik7IA0K K01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsgTU9EVUxFX0RFU0NSSVBUSU9OKCJGcmVlc2NhbGUg UkFJRCBFbmdpbmUgDQorRGV2aWNlIERyaXZlciIpOw0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvZG1h L2ZzbF9yYWlkLmggYi9kcml2ZXJzL2RtYS9mc2xfcmFpZC5oIG5ldyBmaWxlIG1vZGUgMTAwNjQ0 IGluZGV4IDAwMDAwMDAuLjNjYjg0NTQNCi0tLSAvZGV2L251bGwNCisrKyBiL2RyaXZlcnMvZG1h L2ZzbF9yYWlkLmgNCkBAIC0wLDAgKzEsMzE3IEBADQorLyoNCisgKiBkcml2ZXJzL2RtYS9mc2xf cmFpZC5oDQorICoNCisgKiBGcmVlc2NhbGUgUkFJRCBFbmdpbmUgZGV2aWNlIGRyaXZlcg0KKyAq DQorICogQXV0aG9yOg0KKyAqCUhhcm5pbmRlciBSYWkgPGhhcm5pbmRlci5yYWlAZnJlZXNjYWxl LmNvbT4NCisgKglOYXZlZW4gQnVybWkgPG5hdmVlbmJ1cm1pQGZyZWVzY2FsZS5jb20+DQorICoN CisgKiBDb3B5cmlnaHQgKGMpIDIwMTAtMjAxMiBGcmVlc2NhbGUgU2VtaWNvbmR1Y3RvciwgSW5j Lg0KKyAqDQorICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBm b3Jtcywgd2l0aCBvciB3aXRob3V0DQorICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHBy b3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6DQorICogICAgICog UmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5 cmlnaHQNCisgKiAgICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUg Zm9sbG93aW5nIGRpc2NsYWltZXIuDQorICogICAgICogUmVkaXN0cmlidXRpb25zIGluIGJpbmFy eSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQNCisgKiAgICAgICBub3Rp Y2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIg aW4gdGhlDQorICogICAgICAgZG9jdW1lbnRhdGlvbiBhbmQvb3Igb3RoZXIgbWF0ZXJpYWxzIHBy b3ZpZGVkIHdpdGggdGhlIGRpc3RyaWJ1dGlvbi4NCisgKiAgICAgKiBOZWl0aGVyIHRoZSBuYW1l IG9mIEZyZWVzY2FsZSBTZW1pY29uZHVjdG9yIG5vciB0aGUNCisgKiAgICAgICBuYW1lcyBvZiBp dHMgY29udHJpYnV0b3JzIG1heSBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0 cw0KKyAqICAgICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMg cHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLg0KKyAqDQorICogQUxURVJOQVRJVkVMWSwgdGhpcyBz b2Z0d2FyZSBtYXkgYmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mIA0KK3RoZQ0KKyAq IEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlICgiR1BMIikgYXMgcHVibGlzaGVkIGJ5IHRoZSBG cmVlIFNvZnR3YXJlDQorICogRm91bmRhdGlvbiwgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGF0IExp Y2Vuc2Ugb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkNCisgKiBsYXRlciB2ZXJzaW9uLg0KKyAqDQor ICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBGcmVlc2NhbGUgU2VtaWNvbmR1Y3RvciBg YEFTIElTJycgQU5EIA0KK0FOWQ0KKyAqIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJ TkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgVEhFIA0KK0lNUExJRUQNCisgKiBXQVJSQU5U SUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBP U0UgDQorQVJFDQorICogRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgRnJlZXNjYWxlIFNl bWljb25kdWN0b3IgQkUgTElBQkxFIEZPUiANCitBTlkNCisgKiBESVJFQ1QsIElORElSRUNULCBJ TkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgDQorREFNQUdF Uw0KKyAqIChJTkNMVURJTkcsIEJVVCBOT1QgTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VC U1RJVFVURSBHT09EUyBPUiANCitTRVJWSUNFUzsNCisgKiBMT1NTIE9GIFVTRSwgREFUQSwgT1Ig UFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIA0KK0NBVVNFRCBBTkQN CisgKiBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RS SUNUIExJQUJJTElUWSwgDQorT1IgVE9SVA0KKyAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBP VEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIA0KK1VTRSBPRiBUSElTDQor ICogU09GVFdBUkUsIEVWRU4gSUYgQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBE QU1BR0UuDQorICoNCisgKi8NCisNCisjZGVmaW5lIFJFX0RQQUFfTU9ERQkJKDEgPDwgMzApDQor I2RlZmluZSBSRV9OT05fRFBBQV9NT0RFCSgxIDw8IDMxKQ0KKyNkZWZpbmUgUkVfR0ZNX1BPTFkJ CSgweDFkMDAwMDAwKQ0KKyNkZWZpbmUgUkVfSlJfSU5CX0pPQl9BREQoeCkJKCh4KSA8PCAxNikN CisjZGVmaW5lIFJFX0pSX09VQl9KT0JfUkVNT1ZFKHgpCSgoeCkgPDwgMTYpDQorI2RlZmluZSBS RV9KUl9DRkcxX0NCU0kJCTB4MDgwMDAwMDANCisjZGVmaW5lIFJFX0pSX0NGRzFfQ0JTMAkJMHgw MDA4MDAwMA0KKyNkZWZpbmUgUkVfSlJfT1VCX1NMT1RfRlVMTF9TSElGVAk4DQorI2RlZmluZSBS RV9KUl9PVUJfU0xPVF9GVUxMKHgpCSgoeCkgPj4gUkVfSlJfT1VCX1NMT1RfRlVMTF9TSElGVCkN CisjZGVmaW5lIFJFX0pSX0lOQl9TTE9UX0FWQUlMX1NISUZUCTgNCisjZGVmaW5lIFJFX0pSX0lO Ql9TTE9UX0FWQUlMKHgpCSgoeCkgPj4gUkVfSlJfSU5CX1NMT1RfQVZBSUxfU0hJRlQpDQorI2Rl ZmluZSBSRV9QUV9PUENPREUJCTB4MUINCisjZGVmaW5lIFJFX1hPUl9PUENPREUJCTB4MUENCisj ZGVmaW5lIFJFX01PVkVfT1BDT0RFCQkweDgNCisjZGVmaW5lIEZSQU1FX0RFU0NfQUxJR05NRU5U CTE2DQorI2RlZmluZSBSRV9CTE9DS19TSVpFCQkweDMgLyogNDA5NiBieXRlcyAqLw0KKyNkZWZp bmUgQ0FDSEVBQkxFX0lOUFVUX09VVFBVVAkweDANCisjZGVmaW5lIEJVRkZFUkFCTEVfT1VUUFVU CTB4MA0KKyNkZWZpbmUgSU5URVJSVVBUX09OX0VSUk9SCTB4MQ0KKyNkZWZpbmUgREFUQV9ERVBF TkRFTkNZCQkweDENCisjZGVmaW5lIEVOQUJMRV9EUEkJCTB4MA0KKyNkZWZpbmUgUklOR19TSVpF CQkweDEwMDANCisjZGVmaW5lIFJJTkdfU0laRV9TSElGVAkJOA0KKyNkZWZpbmUgUkVfSlJfQURE UkVTU19CSVRfU0hJRlQJNA0KKyNkZWZpbmUgUkVfSlJfQUREUkVTU19CSVRfTUFTSwkoKDEgPDwg UkVfSlJfQUREUkVTU19CSVRfU0hJRlQpIC0gMSkNCisjZGVmaW5lIFJFX0pSX0VSUk9SCQkweDQw MDAwMDAwDQorI2RlZmluZSBSRV9KUl9JTlRFUlJVUFQJCTB4ODAwMDAwMDANCisjZGVmaW5lIFJF X0pSX0NMRUFSX0lOVAkJMHg4MDAwMDAwMA0KKyNkZWZpbmUgUkVfSlJfUEFVU0UJCTB4ODAwMDAw MDANCisjZGVmaW5lIFJFX0pSX0VOQUJMRQkJMHg4MDAwMDAwMA0KKw0KKyNkZWZpbmUgUkVfSlJf UkVHX0xJT0ROX01BU0sJMHgwMDAwMGZmZg0KKyNkZWZpbmUgUkVfQ0ZfQ0RCX0FMSUdOCQk2NA0K Ky8qDQorICogdGhlIGxhcmdlc3QgY2YgYmxvY2sgaXMgMTkqc2l6ZW9mKHN0cnVjdCBjbXBuZF9m cmFtZSksIHdoaWNoIGlzIDMwNCBieXRlcy4NCisgKiBoZXJlIDE5ID0gMShjZGIpKzIoZGVzdCkr MTYoc3JjKSwgYWxpZ24gdG8gNjRieXRlcywgdGhhdCBpcyAzMjAgYnl0ZXMuDQorICogdGhlIGxh cmdlc3QgY2RiIGJsb2NrOiBzdHJ1Y3QgcHFfY2RiIHdoaWNoIGlzIDE4MCBieXRlcywgYWRkaW5n IHRvIA0KK2NmIGJsb2NrDQorICogMzIwKzE4MD01MDAsIGFsaWduIHRvIDY0Ynl0ZXMsIHRoYXQg aXMgNTEyIGJ5dGVzLg0KKyAqLw0KKyNkZWZpbmUgUkVfQ0ZfREVTQ19TSVpFCQkzMjANCisjZGVm aW5lIFJFX0NGX0NEQl9TSVpFCQk1MTINCisNCitzdHJ1Y3QgcmVfY3RybCB7DQorCS8qIEdlbmVy YWwgQ29uZmlndXJhdGlvbiBSZWdpc3RlcnMgKi8NCisJX19iZTMyIGdsb2JhbF9jb25maWc7CS8q IEdsb2JhbCBDb25maWd1cmF0aW9uIFJlZ2lzdGVyICovDQorCXU4ICAgICByc3ZkMVs0XTsNCisJ X19iZTMyIGdhbG9pc19maWVsZF9jb25maWc7IC8qIEdhbG9pcyBGaWVsZCBDb25maWd1cmF0aW9u IFJlZ2lzdGVyICovDQorCXU4ICAgICByc3ZkMls0XTsNCisJX19iZTMyIGpxX3dycl9jb25maWc7 ICAgLyogV1JSIENvbmZpZ3VyYXRpb24gcmVnaXN0ZXIgKi8NCisJdTggICAgIHJzdmQzWzRdOw0K KwlfX2JlMzIgY3JjX2NvbmZpZzsJLyogQ1JDIENvbmZpZ3VyYXRpb24gcmVnaXN0ZXIgKi8NCisJ dTggICAgIHJzdmQ0WzIyOF07DQorCV9fYmUzMiBzeXN0ZW1fcmVzZXQ7CS8qIFN5c3RlbSBSZXNl dCBSZWdpc3RlciAqLw0KKwl1OCAgICAgcnN2ZDVbMjUyXTsNCisJX19iZTMyIGdsb2JhbF9zdGF0 dXM7CS8qIEdsb2JhbCBTdGF0dXMgUmVnaXN0ZXIgKi8NCisJdTggICAgIHJzdmQ2WzgzMl07DQor CV9fYmUzMiByZV9saW9kbl9iYXNlOwkvKiBMSU9ETiBCYXNlIFJlZ2lzdGVyICovDQorCXU4ICAg ICByc3ZkN1sxNzEyXTsNCisJX19iZTMyIHJlX3ZlcnNpb25faWQ7CS8qIFZlcnNpb24gSUQgcmVn aXN0ZXIgb2YgUkUgKi8NCisJX19iZTMyIHJlX3ZlcnNpb25faWRfMjsgLyogVmVyc2lvbiBJRCAy IHJlZ2lzdGVyIG9mIFJFICovDQorCXU4ICAgICByc3ZkOFs1MTJdOw0KKwlfX2JlMzIgaG9zdF9j b25maWc7CS8qIEhvc3QgSS9GIENvbmZpZ3VyYXRpb24gUmVnaXN0ZXIgKi8NCit9Ow0KKw0KK3N0 cnVjdCBqcl9jb25maWdfcmVncyB7DQorCS8qIFJlZ2lzdGVycyBmb3IgSlIgaW50ZXJmYWNlICov DQorCV9fYmUzMiBqcl9jb25maWdfMDsJLyogSm9iIFF1ZXVlIENvbmZpZ3VyYXRpb24gMCBSZWdp c3RlciAqLw0KKwlfX2JlMzIganJfY29uZmlnXzE7CS8qIEpvYiBRdWV1ZSBDb25maWd1cmF0aW9u IDEgUmVnaXN0ZXIgKi8NCisJX19iZTMyIGpyX2ludGVycnVwdF9zdGF0dXM7IC8qIEpvYiBRdWV1 ZSBJbnRlcnJ1cHQgU3RhdHVzIFJlZ2lzdGVyICovDQorCXU4ICAgICByc3ZkMVs0XTsNCisJX19i ZTMyIGpyX2NvbW1hbmQ7CS8qIEpvYiBRdWV1ZSBDb21tYW5kIFJlZ2lzdGVyICovDQorCXU4ICAg ICByc3ZkMls0XTsNCisJX19iZTMyIGpyX3N0YXR1czsJLyogSm9iIFF1ZXVlIFN0YXR1cyBSZWdp c3RlciAqLw0KKwl1OCAgICAgcnN2ZDNbMjI4XTsNCisNCisJLyogSW5wdXQgUmluZyAqLw0KKwlf X2JlMzIgaW5icmluZ19iYXNlX2g7CS8qIEluYm91bmQgUmluZyBCYXNlIEFkZHJlc3MgUmVnaXN0 ZXIgLSBIaWdoICovDQorCV9fYmUzMiBpbmJyaW5nX2Jhc2VfbDsJLyogSW5ib3VuZCBSaW5nIEJh c2UgQWRkcmVzcyBSZWdpc3RlciAtIExvdyAqLw0KKwlfX2JlMzIgaW5icmluZ19zaXplOwkvKiBJ bmJvdW5kIFJpbmcgU2l6ZSBSZWdpc3RlciAqLw0KKwl1OCAgICAgcnN2ZDRbNF07DQorCV9fYmUz MiBpbmJyaW5nX3Nsb3RfYXZhaWw7IC8qIEluYm91bmQgUmluZyBTbG90IEF2YWlsYWJsZSBSZWdp c3RlciAqLw0KKwl1OCAgICAgcnN2ZDVbNF07DQorCV9fYmUzMiBpbmJyaW5nX2FkZF9qb2I7CS8q IEluYm91bmQgUmluZyBBZGQgSm9iIFJlZ2lzdGVyICovDQorCXU4ICAgICByc3ZkNls0XTsNCisJ X19iZTMyIGluYnJpbmdfY25zbXJfaW5keDsgLyogSW5ib3VuZCBSaW5nIENvbnN1bWVyIEluZGV4 IFJlZ2lzdGVyICovDQorCXU4ICAgICByc3ZkN1syMjBdOw0KKw0KKwkvKiBPdXRwdXQgUmluZyAq Lw0KKwlfX2JlMzIgb3VicmluZ19iYXNlX2g7CS8qIE91dGJvdW5kIFJpbmcgQmFzZSBBZGRyZXNz IFJlZ2lzdGVyIC0gSGlnaCAqLw0KKwlfX2JlMzIgb3VicmluZ19iYXNlX2w7CS8qIE91dGJvdW5k IFJpbmcgQmFzZSBBZGRyZXNzIFJlZ2lzdGVyIC0gTG93ICovDQorCV9fYmUzMiBvdWJyaW5nX3Np emU7CS8qIE91dGJvdW5kIFJpbmcgU2l6ZSBSZWdpc3RlciAqLw0KKwl1OCAgICAgcnN2ZDhbNF07 DQorCV9fYmUzMiBvdWJyaW5nX2pvYl9ybXZkOyAvKiBPdXRib3VuZCBSaW5nIEpvYiBSZW1vdmVk IFJlZ2lzdGVyICovDQorCXU4ICAgICByc3ZkOVs0XTsNCisJX19iZTMyIG91YnJpbmdfc2xvdF9m dWxsOyAvKiBPdXRib3VuZCBSaW5nIFNsb3QgRnVsbCBSZWdpc3RlciAqLw0KKwl1OCAgICAgcnN2 ZDEwWzRdOw0KKwlfX2JlMzIgb3VicmluZ19wcmRjcl9pbmR4OyAvKiBPdXRib3VuZCBSaW5nIFBy b2R1Y2VyIEluZGV4ICovIH07DQorDQorLyoNCisgKiBDb21tYW5kIERlc2NyaXB0b3IgQmxvY2sg KENEQikgZm9yIHVuaWNhc3QgbW92ZSBjb21tYW5kLg0KKyAqIEluIFJBSUQgRW5naW5lIHRlcm1z LCBtZW1jcHkgaXMgZG9uZSB0aHJvdWdoIG1vdmUgY29tbWFuZCAgKi8gc3RydWN0IA0KK21vdmVf Y2RiIHsNCisJdTMyIG9wY29kZTo1Ow0KKwl1MzIgcnN2ZDE6MTE7DQorCXUzMiBibGtfc2l6ZToy Ow0KKwl1MzIgY2FjaGVfYXR0cmliOjI7DQorCXUzMiBidWZmZXJfYXR0cmliOjE7DQorCXUzMiBl cnJvcl9hdHRyaWI6MTsNCisJdTMyIHJzdmQyOjY7DQorCXUzMiBkYXRhX2RlcGVuZDoxOw0KKwl1 MzIgZHBpOjE7DQorCXUzMiByc3ZkMzoyOw0KK30gX19wYWNrZWQ7DQorDQorLyogRGF0YSBwcm90 ZWN0aW9uL2ludGVncml0eSByZWxhdGVkIGZpZWxkcyAqLyBzdHJ1Y3QgZHBpX3JlbGF0ZWQgew0K Kwl1MzIgYXBwc19tdGhkOjI7DQorCXUzMiByZWZfbXRoZDoyOw0KKwl1MzIgZ3VhcmRfbXRoZDoy Ow0KKwl1MzIgZHBpX2F0dHI6MjsNCisJdTMyIHJzdmQxOjg7DQorCXUzMiBtZXRhX3RhZzoxNjsN CisJdTMyIHJlZl90YWc6MzI7DQorfSBfX3BhY2tlZDsNCisNCisvKg0KKyAqIENEQiBmb3IgR2Vu USBjb21tYW5kLiBJbiBSQUlEIEVuZ2luZSB0ZXJtaW5vbG9neSwgWE9SIGlzDQorICogZG9uZSB0 aHJvdWdoIHRoaXMgY29tbWFuZA0KKyAqLw0KK3N0cnVjdCB4b3JfY2RiIHsNCisJdTMyIG9wY29k ZTo1Ow0KKwl1MzIgcnN2ZDE6MTE7DQorCXUzMiBibGtfc2l6ZToyOw0KKwl1MzIgY2FjaGVfYXR0 cmliOjI7DQorCXUzMiBidWZmZXJfYXR0cmliOjE7DQorCXUzMiBlcnJvcl9hdHRyaWI6MTsNCisJ dTMyIG5yY3M6NDsNCisJdTMyIHJzdmQyOjI7DQorCXUzMiBkYXRhX2RlcGVuZDoxOw0KKwl1MzIg ZHBpOjE7DQorCXUzMiByc3ZkMzoyOw0KKwl1OCBnZm1bMTZdOw0KKwlzdHJ1Y3QgZHBpX3JlbGF0 ZWQgZHBpX2Rlc3Rfc3BlYzsNCisJc3RydWN0IGRwaV9yZWxhdGVkIGRwaV9zcmNfc3BlY1sxNl07 DQorfSBfX3BhY2tlZDsNCisNCisvKiBDREIgZm9yIG5vLW9wIGNvbW1hbmQgKi8NCitzdHJ1Y3Qg bm9vcF9jZGIgew0KKwl1MzIgb3Bjb2RlOjU7DQorCXUzMiByc3ZkMToyMzsNCisJdTMyIGRlcGVu ZGVuY3k6MTsNCisJdTMyIHJzdmQyOjM7DQorfSBfX3BhY2tlZDsNCisNCisvKg0KKyAqIENEQiBm b3IgR2VuUVEgY29tbWFuZC4gSW4gUkFJRCBFbmdpbmUgdGVybWlub2xvZ3ksIFAvUSBpcw0KKyAq IGRvbmUgdGhyb3VnaCB0aGlzIGNvbW1hbmQNCisgKi8NCitzdHJ1Y3QgcHFfY2RiIHsNCisJdTMy IG9wY29kZTo1Ow0KKwl1MzIgcnN2ZDE6MTsNCisJdTMyIGV4Y2xfZW5hYmxlOjI7DQorCXUzMiBl eGNsX3ExOjQ7DQorCXUzMiBleGNsX3EyOjQ7DQorCXUzMiBibGtfc2l6ZToyOw0KKwl1MzIgY2Fj aGVfYXR0cmliOjI7DQorCXUzMiBidWZmZXJfYXR0cmliOjE7DQorCXUzMiBlcnJvcl9hdHRyaWI6 MTsNCisJdTMyIG5yY3M6NDsNCisJdTMyIHJzdmQyOjI7DQorCXUzMiBkYXRhX2RlcGVuZDoxOw0K Kwl1MzIgZHBpOjE7DQorCXUzMiByc3ZkMzoyOw0KKwl1OCBnZm1fcTFbMTZdOw0KKwl1OCBnZm1f cTJbMTZdOw0KKwlzdHJ1Y3QgZHBpX3JlbGF0ZWQgZHBpX2Rlc3Rfc3BlY1syXTsNCisJc3RydWN0 IGRwaV9yZWxhdGVkIGRwaV9zcmNfc3BlY1sxNl07DQorfSBfX3BhY2tlZDsNCisNCisvKiBDb21w b3VuZCBmcmFtZSAqLw0KK3N0cnVjdCBjbXBuZF9mcmFtZSB7DQorCXU2NCByc3ZkMToyNDsNCisJ dTY0IGFkZHJlc3M6NDA7DQorCXUzMiBleHRlbnNpb246MTsNCisJdTMyIGZpbmFsOjE7DQorCXUz MiByc3ZkMzoxMDsNCisJdTMyIGxlbmd0aDoyMDsNCisJdTMyIHJzdmQ0Ojg7DQorCXUzMiBicGlk Ojg7DQorCXUzMiByc3ZkNTozOw0KKwl1MzIgb2Zmc2V0OjEzOw0KK30gX19wYWNrZWQ7DQorDQor LyogRnJhbWUgZGVzY3JpcHRvciAqLw0KK3N0cnVjdCBqcl9od19kZXNjIHsNCisJdTY0IGRlYnVn OjI7DQorCXU2NCBsaW9kbl9vZmY6NjsNCisJdTY0IGJwaWQ6ODsNCisJdTY0IGVsaW9kbl9vZmY6 NDsNCisJdTY0IHJzdmQxOjQ7DQorCXU2NCBhZGRyZXNzOjQwOw0KKwl1NjQgZm9ybWF0OjM7DQor CXU2NCByc3ZkMjoyOTsNCisJdTY0IHN0YXR1czozMjsNCit9IF9fcGFja2VkOw0KKw0KKyNkZWZp bmUgTUFYX1JFX0pSUwkJNA0KKw0KKy8qIFJhaWQgRW5naW5lIGRldmljZSBwcml2YXRlIGRhdGEg Ki8NCitzdHJ1Y3QgcmVfZHJ2X3ByaXZhdGUgew0KKwl1OCB0b3RhbF9qcnM7DQorCXN0cnVjdCBk bWFfZGV2aWNlIGRtYV9kZXY7DQorCXN0cnVjdCByZV9jdHJsICpyZV9yZWdzOw0KKwlzdHJ1Y3Qg cmVfanIgKnJlX2pyc1tNQVhfUkVfSlJTXTsNCisJc3RydWN0IGRtYV9wb29sICpkZXNjX3Bvb2w7 DQorCXN0cnVjdCBkbWFfcG9vbCAqaHdfZGVzY19wb29sOw0KK307DQorDQorLyogUGVyIGpvYiBy aW5nIGRhdGEgc3RydWN0dXJlICovDQorc3RydWN0IHJlX2pyIHsNCisJZG1hX2Nvb2tpZV90IGNv bXBsZXRlZF9jb29raWU7DQorCXNwaW5sb2NrX3QgZGVzY19sb2NrOw0KKwlzdHJ1Y3QgbGlzdF9o ZWFkIGFja19xOw0KKwlzdHJ1Y3QgZGV2aWNlICpkZXY7DQorCXN0cnVjdCByZV9kcnZfcHJpdmF0 ZSAqcmVfZGV2Ow0KKwlzdHJ1Y3QgZG1hX2NoYW4gY2hhbjsNCisJc3RydWN0IGpyX2NvbmZpZ19y ZWdzICpqcnJlZ3M7DQorCWludCBpcnE7DQorCXN0cnVjdCB0YXNrbGV0X3N0cnVjdCBpcnF0YXNr Ow0KKw0KKwkvKiBodyBkZXNjcmlwdG9yIHJpbmcgZm9yIGluYm91bmQgcXVldWUqLw0KKwlkbWFf YWRkcl90IGluYl9waHlzX2FkZHI7DQorCXN0cnVjdCBqcl9od19kZXNjICppbmJfcmluZ192aXJ0 X2FkZHI7DQorCXUzMiBpbmJfY291bnQ7DQorCXUzMiBwZW5kX2NvdW50Ow0KKwlzcGlubG9ja190 IGluYl9sb2NrOw0KKw0KKwkvKiBodyBkZXNjcmlwdG9yIHJpbmcgZm9yIG91dGJvdW5kIHF1ZXVl ICovDQorCWRtYV9hZGRyX3Qgb3ViX3BoeXNfYWRkcjsNCisJc3RydWN0IGpyX2h3X2Rlc2MgKm91 Yl9yaW5nX3ZpcnRfYWRkcjsNCisJdTMyIG91Yl9jb3VudDsNCisJc3BpbmxvY2tfdCBvdWJfbG9j azsNCisNCisJc3RydWN0IGZzbF9yZV9kbWFfYXN5bmNfdHhfZGVzYyAqZGVzY3M7IC8qIHN3IGRl c2NyaXB0b3IgcmluZyAqLw0KKwl2b2lkICpjZnM7CQkJCS8qIGRtYSBkZXNjcmlwdG9yIHJpbmcg Ki8NCisJZG1hX2FkZHJfdCBwaHlzOyAgICAgICAgICAvKiBwaHlzIGFkZHIgZm9yIGRtYSBkZXNj cmlwdG9yIHJpbmcgKi8NCisNCisJc3RydWN0IHRpbWVyX2xpc3QgdGltZXI7DQorfTsNCisNCitl bnVtIGRlc2Nfc3RhdGUgew0KKwlSRV9ERVNDX0VNUFRZLA0KKwlSRV9ERVNDX0FMTE9DLA0KK307 DQorDQorLyogQXN5bmMgdHJhbnNhY3Rpb24gZGVzY3JpcHRvciAqLw0KK3N0cnVjdCBmc2xfcmVf ZG1hX2FzeW5jX3R4X2Rlc2Mgew0KKwlzdHJ1Y3QgZG1hX2FzeW5jX3R4X2Rlc2NyaXB0b3IgYXN5 bmNfdHg7DQorCXN0cnVjdCBsaXN0X2hlYWQgbm9kZTsNCisJc3RydWN0IGxpc3RfaGVhZCB0eF9s aXN0Ow0KKwlzdHJ1Y3QganJfaHdfZGVzYyAqaHdkZXNjOw0KKwlzdHJ1Y3QgcmVfanIgKmpyOw0K Kw0KKwl2b2lkICpjZl9hZGRyOw0KKwlpbnQgZG1hX2xlbjsNCisJdTggZGVzdF9jbnQ7DQorCXU4 IHNyY19jbnQ7DQorDQorCXUxNiBjZGJfb3Bjb2RlOw0KKwl2b2lkICpjZGJfYWRkcjsNCisJZG1h X2FkZHJfdCBjZGJfcGFkZHI7DQorCWludCBjZGJfbGVuOw0KKw0KKwllbnVtIGRlc2Nfc3RhdGUg c3RhdGU7DQorfTsNCi0tDQoxLjcuOS41DQoNCg== ^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [PATCH 1/2] powerpc/dma/raidengine: add raidengine device 2012-11-21 9:01 [PATCH 1/2] powerpc/dma/raidengine: add raidengine device b29237 2012-11-21 9:01 ` [PATCH 2/2] powerpc/dma/raidengine: enable Freescale RaidEngine device b29237 @ 2012-11-25 13:21 ` Kumar Gala 1 sibling, 0 replies; 4+ messages in thread From: Kumar Gala @ 2012-11-25 13:21 UTC (permalink / raw) To: <b29237@freescale.com> Cc: Harninder Rai, iws, vinod.koul, linux-kernel, Naveen Burmi, dan.j.williams, linuxppc-dev On Nov 21, 2012, at 3:01 AM, <b29237@freescale.com> = <b29237@freescale.com> wrote: > From: Xuelin Shi <b29237@freescale.com> >=20 > The RaidEngine is a new Freescale hardware that used for parity > computation offloading in RAID5/6. >=20 > This patch adds the device node in device tree and related binding > documentation. >=20 > Signed-off-by: Harninder Rai <harninder.rai@freescale.com> > Signed-off-by: Naveen Burmi <naveenburmi@freescale.com> > Signed-off-by: Xuelin Shi <b29237@freescale.com> > --- > .../devicetree/bindings/powerpc/fsl/raideng.txt | 81 = +++++++++++++++++++ > arch/powerpc/boot/dts/fsl/p5020si-post.dtsi | 1 + > arch/powerpc/boot/dts/fsl/p5020si-pre.dtsi | 6 ++ > arch/powerpc/boot/dts/fsl/qoriq-raid1.0-0.dtsi | 85 = ++++++++++++++++++++ > 4 files changed, 173 insertions(+) > create mode 100644 = Documentation/devicetree/bindings/powerpc/fsl/raideng.txt > create mode 100644 arch/powerpc/boot/dts/fsl/qoriq-raid1.0-0.dtsi applied to next - k= ^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2013-04-10 5:07 UTC | newest] Thread overview: 4+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2012-11-21 9:01 [PATCH 1/2] powerpc/dma/raidengine: add raidengine device b29237 2012-11-21 9:01 ` [PATCH 2/2] powerpc/dma/raidengine: enable Freescale RaidEngine device b29237 2013-04-10 5:07 ` Shi Xuelin-B29237 2012-11-25 13:21 ` [PATCH 1/2] powerpc/dma/raidengine: add raidengine device Kumar Gala
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).