From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE, SPF_PASS,USER_AGENT_SANE_1 autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5B863C2BC11 for ; Fri, 11 Sep 2020 06:48:35 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 17168221EB for ; Fri, 11 Sep 2020 06:48:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1725730AbgIKGse (ORCPT ); Fri, 11 Sep 2020 02:48:34 -0400 Received: from mga03.intel.com ([134.134.136.65]:4588 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1725468AbgIKGsV (ORCPT ); Fri, 11 Sep 2020 02:48:21 -0400 IronPort-SDR: sTvoZAg4KRFt9GsEt8kRjGUA+YC1iTOCebAfe6urklT9yn/ZW9Cr1H5oMaYecnIPTvpp+SGBei 8y9TssW8Fxyw== X-IronPort-AV: E=McAfee;i="6000,8403,9740"; a="158740011" X-IronPort-AV: E=Sophos;i="5.76,414,1592895600"; d="scan'208";a="158740011" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by orsmga103.jf.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Sep 2020 23:48:20 -0700 IronPort-SDR: mCIJoz7ugalP3NcKLLaGgM+lMqf7ELnTC9MYH9PYX/K4fA75W9yof3gT2m/k4iyCW3UW5fNxm1 jMoQlOa7BX+A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.76,414,1592895600"; d="scan'208";a="506109212" Received: from linux.intel.com ([10.54.29.200]) by fmsmga005.fm.intel.com with ESMTP; 10 Sep 2020 23:48:20 -0700 Received: from [10.213.131.98] (vramuthx-MOBL1.gar.corp.intel.com [10.213.131.98]) by linux.intel.com (Postfix) with ESMTP id 25709580224; Thu, 10 Sep 2020 23:48:14 -0700 (PDT) Reply-To: vadivel.muruganx.ramuthevar@linux.intel.com Subject: Re: [RESEND PATCH v12 2/2] mtd: rawnand: Add NAND controller support on Intel LGM SoC To: Miquel Raynal Cc: linux-kernel@vger.kernel.org, linux-mtd@lists.infradead.org, devicetree@vger.kernel.org, richard@nod.at, vigneshr@ti.com, arnd@arndb.de, brendanhiggins@google.com, tglx@linutronix.de, boris.brezillon@collabora.com, anders.roxell@linaro.org, masonccyang@mxic.com.tw, robh+dt@kernel.org, linux-mips@vger.kernel.org, hauke.mehrtens@intel.com, andriy.shevchenko@intel.com, cheol.yong.kim@intel.com, qi-ming.wu@intel.com References: <20200817052709.47035-1-vadivel.muruganx.ramuthevar@linux.intel.com> <20200817052709.47035-3-vadivel.muruganx.ramuthevar@linux.intel.com> <20200907152025.66c18f5e@xps13> From: "Ramuthevar, Vadivel MuruganX" Message-ID: Date: Fri, 11 Sep 2020 14:48:13 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.12.0 MIME-Version: 1.0 In-Reply-To: <20200907152025.66c18f5e@xps13> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Hi Miquel, Thank you for your review comments... On 7/9/2020 9:20 pm, Miquel Raynal wrote: > Hi Murugan, > > A few more comments below, but I guess the driver looks better now. > >> +struct ebu_nand_controller { >> + struct nand_controller controller; >> + struct nand_chip chip; >> + struct device *dev; >> + void __iomem *ebu; >> + void __iomem *hsnand; >> + struct dma_chan *dma_tx; >> + struct dma_chan *dma_rx; >> + struct completion dma_access_complete; >> + unsigned long clk_rate; >> + struct clk *clk; >> + u32 nd_para0; >> + u8 cs_num; >> + struct ebu_nand_cs cs[MAX_CS]; >> +}; >> + >> +static inline struct ebu_nand_controller *nand_to_ebu(struct nand_chip *chip) >> +{ >> + return container_of(chip, struct ebu_nand_controller, chip); >> +} >> + >> +static u8 ebu_nand_readb(struct nand_chip *chip) > > Can't you prefix with intel_ instead of ebu_ ? > >> +{ >> + struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip); >> + void __iomem *nand_wait = ebu_host->ebu + EBU_WAIT; >> + u8 cs_num = ebu_host->cs_num; >> + u32 stat; >> + int ret; >> + u8 val; >> + >> + val = readb(ebu_host->cs[cs_num].chipaddr + HSNAND_CS_OFFS); >> + >> + ret = readl_poll_timeout(nand_wait, stat, stat & EBU_WAIT_WR_C, >> + 20, 1000); > > If you do this operation each time a byte is read/written, you probable > want to shrink the polling delay a little bit, to 1 or even 0. Ok, Noted. > >> + if (ret) >> + dev_warn(ebu_host->dev, >> + "ebu nand write timeout. nand_wait(0x%p)=0x%x\n", >> + nand_wait, readl(nand_wait)); >> + >> + return val; > > You should not return val if ret is !0 I guess Yes, You're correct. > >> +} >> + >> +static void ebu_nand_writeb(struct nand_chip *chip, u32 offset, u8 value) >> +{ >> + struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip); >> + void __iomem *nand_wait = ebu_host->ebu + EBU_WAIT; >> + u8 cs_num = ebu_host->cs_num; >> + u32 stat; >> + int ret; >> + >> + writeb(value, ebu_host->cs[cs_num].chipaddr + offset); >> + >> + ret = readl_poll_timeout(nand_wait, stat, stat & EBU_WAIT_WR_C, >> + 20, 1000); > > Here as well Noted. > >> + if (ret) >> + dev_warn(ebu_host->dev, >> + "ebu nand write timeout. nand_wait(0x%p)=0x%x\n", >> + nand_wait, readl(nand_wait)); > > If this can fail, then the helper should return an error and be treated. Noted, will update. > >> +} >> + >> +static void ebu_read_buf(struct nand_chip *chip, u_char *buf, unsigned int len) >> +{ >> + int i; >> + >> + for (i = 0; i < len; i++) >> + buf[i] = ebu_nand_readb(chip); >> +} >> + >> +static void ebu_write_buf(struct nand_chip *chip, const u_char *buf, int len) >> +{ >> + int i; >> + >> + for (i = 0; i < len; i++) >> + ebu_nand_writeb(chip, HSNAND_CS_OFFS, buf[i]); >> +} >> + >> +static void ebu_nand_disable(struct nand_chip *chip) >> +{ >> + struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip); >> + >> + writel(0, ebu_host->ebu + EBU_CON); >> +} >> + >> +static void ebu_select_chip(struct nand_chip *chip) >> +{ >> + struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip); >> + void __iomem *nand_con = ebu_host->ebu + EBU_CON; >> + u32 cs = ebu_host->cs_num; >> + >> + writel(EBU_CON_NANDM_EN | EBU_CON_CSMUX_E_EN | EBU_CON_CS_P_LOW | >> + EBU_CON_SE_P_LOW | EBU_CON_WP_P_LOW | EBU_CON_PRE_P_LOW | >> + EBU_CON_IN_CS_S(cs) | EBU_CON_OUT_CS_S(cs) | >> + EBU_CON_LAT_EN_CS_P, nand_con); >> +} >> + >> +static void ebu_nand_setup_timing(struct ebu_nand_controller *ctrl, >> + const struct nand_sdr_timings *timings) >> +{ >> + unsigned int rate = clk_get_rate(ctrl->clk) / 1000000; >> + unsigned int period = DIV_ROUND_UP(1000000, rate); >> + u32 trecov, thold, twrwait, trdwait; >> + u32 reg = 0; >> + >> + trecov = DIV_ROUND_UP(max(timings->tREA_max, timings->tREH_min), >> + period); >> + reg |= EBU_BUSCON_RECOVC(trecov); >> + >> + thold = DIV_ROUND_UP(max(timings->tDH_min, timings->tDS_min), period); >> + reg |= EBU_BUSCON_HOLDC(thold); >> + >> + trdwait = DIV_ROUND_UP(max(timings->tRC_min, timings->tREH_min), >> + period); >> + reg |= EBU_BUSCON_WAITRDC(trdwait); >> + >> + twrwait = DIV_ROUND_UP(max(timings->tWC_min, timings->tWH_min), period); >> + reg |= EBU_BUSCON_WAITWRC(twrwait); >> + >> + reg |= EBU_BUSCON_CMULT_V4 | EBU_BUSCON_BCGEN_CS | EBU_BUSCON_ALEC | >> + EBU_BUSCON_SETUP_EN; >> + >> + writel(reg, ctrl->ebu + EBU_BUSCON(ctrl->cs_num)); >> +} >> + >> +static int ebu_nand_setup_data_interface(struct nand_chip *chip, int csline, >> + const struct nand_data_interface *conf) > > I recently changed the naming around the data interface, please > have a look at the recent commits and update the namings here as > well. Sure, will go through update accordingly. > >> +{ >> + struct ebu_nand_controller *ctrl = nand_to_ebu(chip); >> + const struct nand_sdr_timings *timings; >> + >> + timings = nand_get_sdr_timings(conf); >> + if (IS_ERR(timings)) >> + return PTR_ERR(timings); >> + >> + if (csline == NAND_DATA_IFACE_CHECK_ONLY) >> + return 0; >> + >> + ebu_nand_setup_timing(ctrl, timings); >> + >> + return 0; >> +} >> + >> +static int ebu_nand_ooblayout_ecc(struct mtd_info *mtd, int section, >> + struct mtd_oob_region *oobregion) >> +{ >> + struct nand_chip *chip = mtd_to_nand(mtd); >> + >> + if (section) >> + return -ERANGE; >> + >> + oobregion->offset = HSNAND_ECC_OFFSET; >> + oobregion->length = chip->ecc.total; >> + >> + return 0; >> +} >> + >> +static int ebu_nand_ooblayout_free(struct mtd_info *mtd, int section, >> + struct mtd_oob_region *oobregion) >> +{ >> + struct nand_chip *chip = mtd_to_nand(mtd); >> + >> + if (section) >> + return -ERANGE; >> + >> + oobregion->offset = chip->ecc.total + HSNAND_ECC_OFFSET; >> + oobregion->length = mtd->oobsize - oobregion->offset; >> + >> + return 0; >> +} >> + >> +static const struct mtd_ooblayout_ops ebu_nand_ooblayout_ops = { >> + .ecc = ebu_nand_ooblayout_ecc, >> + .free = ebu_nand_ooblayout_free, >> +}; >> + >> +static void ebu_dma_rx_callback(void *cookie) >> +{ >> + struct ebu_nand_controller *ebu_host = cookie; >> + >> + dmaengine_terminate_async(ebu_host->dma_rx); >> + >> + complete(&ebu_host->dma_access_complete); >> +} >> + >> +static void ebu_dma_tx_callback(void *cookie) >> +{ >> + struct ebu_nand_controller *ebu_host = cookie; >> + >> + dmaengine_terminate_async(ebu_host->dma_tx); >> + >> + complete(&ebu_host->dma_access_complete); >> +} >> + >> +static int ebu_dma_start(struct ebu_nand_controller *ebu_host, u32 dir, >> + const u8 *buf, u32 len) >> +{ >> + struct dma_async_tx_descriptor *tx; >> + struct completion *dma_completion; >> + dma_async_tx_callback callback; >> + struct dma_chan *chan; >> + dma_cookie_t cookie; >> + unsigned long flags = DMA_CTRL_ACK | DMA_PREP_INTERRUPT; >> + dma_addr_t buf_dma; >> + int ret; >> + u32 timeout; >> + >> + if (dir == DMA_DEV_TO_MEM) { >> + chan = ebu_host->dma_rx; >> + dma_completion = &ebu_host->dma_access_complete; >> + callback = ebu_dma_rx_callback; >> + } else { >> + chan = ebu_host->dma_tx; >> + dma_completion = &ebu_host->dma_access_complete; >> + callback = ebu_dma_tx_callback; >> + } >> + >> + buf_dma = dma_map_single(chan->device->dev, (void *)buf, len, dir); >> + if (dma_mapping_error(chan->device->dev, buf_dma)) { >> + dev_err(ebu_host->dev, "Failed to map DMA buffer\n"); >> + ret = -EIO; >> + goto err_unmap; >> + } >> + >> + tx = dmaengine_prep_slave_single(chan, buf_dma, len, dir, flags); >> + if (!tx) >> + return -ENXIO; >> + >> + tx->callback = callback; >> + tx->callback_param = ebu_host; >> + cookie = tx->tx_submit(tx); >> + >> + ret = dma_submit_error(cookie); >> + if (ret) { >> + dev_err(ebu_host->dev, "dma_submit_error %d\n", cookie); >> + ret = -EIO; >> + goto err_unmap; >> + } >> + >> + init_completion(dma_completion); >> + dma_async_issue_pending(chan); >> + >> + /* Wait DMA to finish the data transfer.*/ >> + timeout = > > Don't break the line here Okay, Noted. > >> + wait_for_completion_timeout(dma_completion, msecs_to_jiffies(1000)); >> + if (!timeout) { >> + dev_err(ebu_host->dev, "I/O Error in DMA RX (status %d)\n", >> + dmaengine_tx_status(chan, cookie, NULL)); >> + dmaengine_terminate_sync(chan); >> + ret = -ETIMEDOUT; >> + goto err_unmap; >> + } >> + >> + return 0; >> + >> +err_unmap: >> + dma_unmap_single(ebu_host->dev, buf_dma, len, dir); >> + >> + return ret; >> +} >> + >> +static void ebu_nand_trigger(struct ebu_nand_controller *ebu_host, >> + int page, u32 cmd) >> +{ >> + unsigned int val; >> + >> + val = cmd | (page & 0xFF) << HSNAND_CTL1_ADDR_SHIFT; >> + writel(val, ebu_host->hsnand + HSNAND_CTL1); >> + val = (page & 0xFFFF00) >> 8 | HSNAND_CTL2_CYC_N_V5; >> + writel(val, ebu_host->hsnand + HSNAND_CTL2); >> + >> + writel(ebu_host->nd_para0, ebu_host->hsnand + HSNAND_PARA0); >> + >> + /* clear first, will update later */ >> + writel(0xFFFFFFFF, ebu_host->hsnand + HSNAND_CMSG_0); >> + writel(0xFFFFFFFF, ebu_host->hsnand + HSNAND_CMSG_1); >> + >> + writel(HSNAND_INT_MSK_CTL_WR_C, >> + ebu_host->hsnand + HSNAND_INT_MSK_CTL); >> + >> + val = cmd == NAND_CMD_READ0 ? HSNAND_CTL_RW_READ : HSNAND_CTL_RW_WRITE; > > I don't like this, prefer having a "read/write" boolean as a parameter. Noted, will update. > >> + >> + writel(HSNAND_CTL_MSG_EN | HSNAND_CTL_CKFF_EN | >> + HSNAND_CTL_ECC_OFF_V8TH | HSNAND_CTL_CE_SEL_CS(ebu_host->cs_num) | >> + HSNAND_CTL_ENABLE_ECC | HSNAND_CTL_GO | val, >> + ebu_host->hsnand + HSNAND_CTL); >> +} >> + >> +static int ebu_nand_read_page_hwecc(struct nand_chip *chip, u8 *buf, >> + int oob_required, int page) >> +{ >> + struct mtd_info *mtd = nand_to_mtd(chip); >> + struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip); >> + int ret, x; >> + >> + ebu_nand_trigger(ebu_host, page, NAND_CMD_READ0); >> + >> + ret = ebu_dma_start(ebu_host, DMA_DEV_TO_MEM, buf, mtd->writesize); >> + if (ret) >> + return ret; >> + >> + if (oob_required) >> + chip->ecc.read_oob(chip, page); >> + >> + x = readl(ebu_host->hsnand + HSNAND_CTL); >> + x &= ~HSNAND_CTL_GO; >> + writel(x, ebu_host->hsnand + HSNAND_CTL); >> + >> + return 0; >> +} >> + >> +static int ebu_nand_write_page_hwecc(struct nand_chip *chip, const u8 *buf, >> + int oob_required, int page) >> +{ >> + struct mtd_info *mtd = nand_to_mtd(chip); >> + struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip); >> + void __iomem *int_sta = ebu_host->hsnand + HSNAND_INT_STA; >> + int ret, val, x; >> + u32 reg; >> + >> + ebu_nand_trigger(ebu_host, page, NAND_CMD_SEQIN); >> + >> + ret = ebu_dma_start(ebu_host, DMA_MEM_TO_DEV, buf, mtd->writesize); >> + if (ret) >> + return ret; >> + >> + if (oob_required) { >> + reg = (chip->oob_poi[3] << 24) | (chip->oob_poi[2] << 16) | >> + (chip->oob_poi[1] << 8) | chip->oob_poi[0]; >> + >> + writel(reg, ebu_host->hsnand + HSNAND_CMSG_0); >> + >> + reg = (chip->oob_poi[7] << 24) | (chip->oob_poi[6] << 16) | >> + (chip->oob_poi[5] << 8) | chip->oob_poi[4]; >> + >> + writel(reg, ebu_host->hsnand + HSNAND_CMSG_1); >> + } >> + >> + ret = readl_poll_timeout_atomic(int_sta, val, >> + !(val & HSNAND_INT_STA_WR_C), 10, 1000); >> + if (ret) >> + return -EIO; > > return ret ? Yes, ret will come. > >> + >> + x = readl(ebu_host->hsnand + HSNAND_CTL); >> + x &= ~HSNAND_CTL_GO; >> + writel(x, ebu_host->hsnand + HSNAND_CTL); > > What is this? Looks like it deserves a helper with a nice name. Register High Speed NAND control, it is exceeding the 80 characters to avoid that, short it, will update. > >> + >> + return 0; >> +} >> + >> +static const u8 ecc_strength[] = { 1, 1, 4, 8, 24, 32, 40, 60, }; > > ^ is this normal? > >> + >> +static int ebu_nand_attach_chip(struct nand_chip *chip) >> +{ >> + struct mtd_info *mtd = nand_to_mtd(chip); >> + struct ebu_nand_controller *ebu_host = nand_get_controller_data(chip); >> + u32 ecc_steps, ecc_bytes, ecc_total, pagesize, pg_per_blk; >> + u32 ecc_strength_ds = chip->ecc.strength; >> + u32 ecc_size = chip->ecc.size; >> + u32 writesize = mtd->writesize; >> + u32 blocksize = mtd->erasesize; >> + int bch_algo, start, val; >> + >> + if (chip->ecc.mode != NAND_ECC_HW) >> + return 0; >> + >> + /* Default to an ECC size of 512 */ >> + if (!chip->ecc.size) >> + chip->ecc.size = 512; >> + >> + switch (ecc_size) { >> + case 512: >> + start = 1; >> + if (!ecc_strength_ds) >> + ecc_strength_ds = 4; >> + break; >> + case 1024: >> + start = 4; >> + if (!ecc_strength_ds) >> + ecc_strength_ds = 32; >> + break; >> + default: >> + return -EINVAL; >> + } >> + >> + /* BCH ECC algorithm Settings for number of bits per 512B/1024B */ >> + bch_algo = round_up(start + 1, 4); >> + for (val = start; val < bch_algo; val++) { >> + if (ecc_strength_ds == ecc_strength[val]) >> + break; >> + } >> + if (val == bch_algo) >> + return -EINVAL; >> + >> + if (ecc_strength_ds == 8) >> + ecc_bytes = 14; >> + else >> + ecc_bytes = DIV_ROUND_UP(ecc_strength_ds * fls(8 * ecc_size), 8); >> + >> + ecc_steps = writesize / ecc_size; >> + ecc_total = ecc_steps * ecc_bytes; >> + if ((ecc_total + 8) > mtd->oobsize) >> + return -ERANGE; >> + >> + chip->ecc.total = ecc_total; >> + pagesize = fls(writesize >> 11); >> + if (pagesize > HSNAND_PARA0_PAGE_V8192) >> + return -ERANGE; >> + >> + pg_per_blk = fls((blocksize / writesize) >> 6) << 4; > > If << 4 is here to mean / 8, then I don't want a shift operation > because it is highly unreadable and compilers know how to optimize > this. Thanks!, will update. > >> + if (pg_per_blk > HSNAND_PARA0_PIB_V256) >> + return -ERANGE; >> + >> + ebu_host->nd_para0 = pagesize | pg_per_blk | HSNAND_PARA0_BYP_EN_NP | >> + HSNAND_PARA0_BYP_DEC_NP | HSNAND_PARA0_ADEP_EN | >> + HSNAND_PARA0_TYPE_ONFI | (val << 29); >> + >> + mtd_set_ooblayout(mtd, &ebu_nand_ooblayout_ops); >> + chip->ecc.read_page = ebu_nand_read_page_hwecc; >> + chip->ecc.write_page = ebu_nand_write_page_hwecc; >> + >> + return 0; >> +} >> + >> +static int ebu_nand_exec_op(struct nand_chip *chip, >> + const struct nand_operation *op, bool check_only) >> +{ >> + struct ebu_nand_controller *ctrl = nand_to_ebu(chip); >> + const struct nand_op_instr *instr = NULL; >> + unsigned int op_id; >> + int i, time_out, ret = 0; >> + u32 stat; >> + >> + if (check_only) >> + ebu_select_chip(chip); > > What is the point of selecting the chip if check_only is true? while converting to exec_op() based data structure, added like other drivers, let me check and update accordingly, Thanks!. Regards Vadivel > >> + >> + for (op_id = 0; op_id < op->ninstrs; op_id++) { >> + instr = &op->instrs[op_id]; >> + >> + switch (instr->type) { >> + case NAND_OP_CMD_INSTR: >> + ebu_nand_writeb(chip, HSNAND_CLE_OFFS | HSNAND_CS_OFFS, >> + instr->ctx.cmd.opcode); >> + break; >> + >> + case NAND_OP_ADDR_INSTR: >> + for (i = 0; i < instr->ctx.addr.naddrs; i++) >> + ebu_nand_writeb(chip, >> + HSNAND_ALE_OFFS | HSNAND_CS_OFFS, >> + instr->ctx.addr.addrs[i]); >> + break; >> + >> + case NAND_OP_DATA_IN_INSTR: >> + ebu_read_buf(chip, instr->ctx.data.buf.in, >> + instr->ctx.data.len); >> + break; >> + >> + case NAND_OP_DATA_OUT_INSTR: >> + ebu_write_buf(chip, instr->ctx.data.buf.out, >> + instr->ctx.data.len); >> + break; >> + >> + case NAND_OP_WAITRDY_INSTR: >> + time_out = instr->ctx.waitrdy.timeout_ms * 1000; >> + ret = readl_poll_timeout(ctrl->ebu + EBU_WAIT, >> + stat, stat & EBU_WAIT_RDBY, >> + 20, time_out); >> + break; >> + } >> + } >> + >> + return ret; >> +} > > > Thanks, > Miquèl > From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-7.7 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,MAILING_LIST_MULTI, NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED,USER_AGENT_SANE_1 autolearn=no autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 88491C433E2 for ; Fri, 11 Sep 2020 06:49:15 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 13AA9221EB for ; Fri, 11 Sep 2020 06:49:14 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="UofbBBkq" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 13AA9221EB Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=linux.intel.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-mtd-bounces+linux-mtd=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Type: Content-Transfer-Encoding:Cc:Reply-To:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:Date: Message-ID:From:References:To:Subject:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Y9v6gX7uC/f7LSae0Fm1P0JXMrDLSooLfIFGOdX3GoQ=; b=UofbBBkqkp1dM3 gbSO3FuJMa3qlu129zjlM8XHfvlp4k5BPThuqKjMOVfA2JMoiv5x91/5qQ6k0zcgiApMTwTraU0AV /LLySJ9EOSju0BaUF8You0fOg9oec2WZzOZW5tV264zN5IhBaBVWF5KX2W551woxhEUQoOOdA5M4j YwL60H+q6uAMhV22Ol2n/mPcYip/LGcx+ViwhPA23yZf7JwrJmaEgwW2OWavYt7bu3e1bu+Um+M85 0ZTWfhELPEkUmRgfeqOlpDRf/ly1hcLaMflIDsTKgUJtpWK8xWbhcfRllQdE6dqLfBNnvoRwUMBfW pPhL9YIwpCWzF2cS/o5g==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1kGcrE-00081Q-HX; Fri, 11 Sep 2020 06:48:28 +0000 Received: from mga11.intel.com ([192.55.52.93]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1kGcrA-00080a-P8 for linux-mtd@lists.infradead.org; Fri, 11 Sep 2020 06:48:26 +0000 IronPort-SDR: /H2h5W9ty4An/3/xHJUlD2jr87MBGdDpKWxrHRsFovqQryZXkfLqw0gJ1NmADjOebjG5DKpRbd A3Gk5k/jU4bg== X-IronPort-AV: E=McAfee;i="6000,8403,9740"; a="156156680" X-IronPort-AV: E=Sophos;i="5.76,414,1592895600"; d="scan'208";a="156156680" X-Amp-Result: SKIPPED(no attachment in message) X-Amp-File-Uploaded: False Received: from fmsmga005.fm.intel.com ([10.253.24.32]) by fmsmga102.fm.intel.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 10 Sep 2020 23:48:20 -0700 IronPort-SDR: mCIJoz7ugalP3NcKLLaGgM+lMqf7ELnTC9MYH9PYX/K4fA75W9yof3gT2m/k4iyCW3UW5fNxm1 jMoQlOa7BX+A== X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.76,414,1592895600"; d="scan'208";a="506109212" Received: from linux.intel.com ([10.54.29.200]) by fmsmga005.fm.intel.com with ESMTP; 10 Sep 2020 23:48:20 -0700 Received: from [10.213.131.98] (vramuthx-MOBL1.gar.corp.intel.com [10.213.131.98]) by linux.intel.com (Postfix) with ESMTP id 25709580224; Thu, 10 Sep 2020 23:48:14 -0700 (PDT) Subject: Re: [RESEND PATCH v12 2/2] mtd: rawnand: Add NAND controller support on Intel LGM SoC To: Miquel Raynal References: <20200817052709.47035-1-vadivel.muruganx.ramuthevar@linux.intel.com> <20200817052709.47035-3-vadivel.muruganx.ramuthevar@linux.intel.com> <20200907152025.66c18f5e@xps13> From: "Ramuthevar, Vadivel MuruganX" Message-ID: Date: Fri, 11 Sep 2020 14:48:13 +0800 User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:68.0) Gecko/20100101 Thunderbird/68.12.0 MIME-Version: 1.0 In-Reply-To: <20200907152025.66c18f5e@xps13> Content-Language: en-US X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200911_024825_031587_F3D770A0 X-CRM114-Status: GOOD ( 32.70 ) X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: vadivel.muruganx.ramuthevar@linux.intel.com Cc: cheol.yong.kim@intel.com, devicetree@vger.kernel.org, qi-ming.wu@intel.com, anders.roxell@linaro.org, vigneshr@ti.com, arnd@arndb.de, hauke.mehrtens@intel.com, richard@nod.at, brendanhiggins@google.com, linux-kernel@vger.kernel.org, robh+dt@kernel.org, linux-mips@vger.kernel.org, boris.brezillon@collabora.com, linux-mtd@lists.infradead.org, tglx@linutronix.de, masonccyang@mxic.com.tw, andriy.shevchenko@intel.com Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "linux-mtd" Errors-To: linux-mtd-bounces+linux-mtd=archiver.kernel.org@lists.infradead.org SGkgTWlxdWVsLAoKVGhhbmsgeW91IGZvciB5b3VyIHJldmlldyBjb21tZW50cy4uLgoKT24gNy85 LzIwMjAgOToyMCBwbSwgTWlxdWVsIFJheW5hbCB3cm90ZToKPiBIaSBNdXJ1Z2FuLAo+IAo+IEEg ZmV3IG1vcmUgY29tbWVudHMgYmVsb3csIGJ1dCBJIGd1ZXNzIHRoZSBkcml2ZXIgbG9va3MgYmV0 dGVyIG5vdy4KPiAKPj4gK3N0cnVjdCBlYnVfbmFuZF9jb250cm9sbGVyIHsKPj4gKwlzdHJ1Y3Qg bmFuZF9jb250cm9sbGVyIGNvbnRyb2xsZXI7Cj4+ICsJc3RydWN0IG5hbmRfY2hpcCBjaGlwOwo+ PiArCXN0cnVjdCBkZXZpY2UgKmRldjsKPj4gKwl2b2lkIF9faW9tZW0gKmVidTsKPj4gKwl2b2lk IF9faW9tZW0gKmhzbmFuZDsKPj4gKwlzdHJ1Y3QgZG1hX2NoYW4gKmRtYV90eDsKPj4gKwlzdHJ1 Y3QgZG1hX2NoYW4gKmRtYV9yeDsKPj4gKwlzdHJ1Y3QgY29tcGxldGlvbiBkbWFfYWNjZXNzX2Nv bXBsZXRlOwo+PiArCXVuc2lnbmVkIGxvbmcgY2xrX3JhdGU7Cj4+ICsJc3RydWN0IGNsayAqY2xr Owo+PiArCXUzMiBuZF9wYXJhMDsKPj4gKwl1OCBjc19udW07Cj4+ICsJc3RydWN0IGVidV9uYW5k X2NzIGNzW01BWF9DU107Cj4+ICt9Owo+PiArCj4+ICtzdGF0aWMgaW5saW5lIHN0cnVjdCBlYnVf bmFuZF9jb250cm9sbGVyICpuYW5kX3RvX2VidShzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwKQo+PiAr ewo+PiArCXJldHVybiBjb250YWluZXJfb2YoY2hpcCwgc3RydWN0IGVidV9uYW5kX2NvbnRyb2xs ZXIsIGNoaXApOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdTggZWJ1X25hbmRfcmVhZGIoc3RydWN0 IG5hbmRfY2hpcCAqY2hpcCkKPiAKPiBDYW4ndCB5b3UgcHJlZml4IHdpdGggaW50ZWxfIGluc3Rl YWQgb2YgZWJ1XyA/Cj4gCj4+ICt7Cj4+ICsJc3RydWN0IGVidV9uYW5kX2NvbnRyb2xsZXIgKmVi dV9ob3N0ID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRhKGNoaXApOwo+PiArCXZvaWQgX19pb21l bSAqbmFuZF93YWl0ID0gZWJ1X2hvc3QtPmVidSArIEVCVV9XQUlUOwo+PiArCXU4IGNzX251bSA9 IGVidV9ob3N0LT5jc19udW07Cj4+ICsJdTMyIHN0YXQ7Cj4+ICsJaW50IHJldDsKPj4gKwl1OCB2 YWw7Cj4+ICsKPj4gKwl2YWwgPSByZWFkYihlYnVfaG9zdC0+Y3NbY3NfbnVtXS5jaGlwYWRkciAr IEhTTkFORF9DU19PRkZTKTsKPj4gKwo+PiArCXJldCA9IHJlYWRsX3BvbGxfdGltZW91dChuYW5k X3dhaXQsIHN0YXQsIHN0YXQgJiBFQlVfV0FJVF9XUl9DLAo+PiArCQkJCSAyMCwgMTAwMCk7Cj4g Cj4gSWYgeW91IGRvIHRoaXMgb3BlcmF0aW9uIGVhY2ggdGltZSBhIGJ5dGUgaXMgcmVhZC93cml0 dGVuLCB5b3UgcHJvYmFibGUKPiB3YW50IHRvIHNocmluayB0aGUgcG9sbGluZyBkZWxheSBhIGxp dHRsZSBiaXQsIHRvIDEgb3IgZXZlbiAwLgpPaywgTm90ZWQuCj4gCj4+ICsJaWYgKHJldCkKPj4g KwkJZGV2X3dhcm4oZWJ1X2hvc3QtPmRldiwKPj4gKwkJCSAiZWJ1IG5hbmQgd3JpdGUgdGltZW91 dC4gbmFuZF93YWl0KDB4JXApPTB4JXhcbiIsCj4+ICsJCQkgbmFuZF93YWl0LCByZWFkbChuYW5k X3dhaXQpKTsKPj4gKwo+PiArCXJldHVybiB2YWw7Cj4gCj4gWW91IHNob3VsZCBub3QgcmV0dXJu IHZhbCBpZiByZXQgaXMgITAgSSBndWVzcwpZZXMsIFlvdSdyZSBjb3JyZWN0Lgo+IAo+PiArfQo+ PiArCj4+ICtzdGF0aWMgdm9pZCBlYnVfbmFuZF93cml0ZWIoc3RydWN0IG5hbmRfY2hpcCAqY2hp cCwgdTMyIG9mZnNldCwgdTggdmFsdWUpCj4+ICt7Cj4+ICsJc3RydWN0IGVidV9uYW5kX2NvbnRy b2xsZXIgKmVidV9ob3N0ID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRhKGNoaXApOwo+PiArCXZv aWQgX19pb21lbSAqbmFuZF93YWl0ID0gZWJ1X2hvc3QtPmVidSArIEVCVV9XQUlUOwo+PiArCXU4 IGNzX251bSA9IGVidV9ob3N0LT5jc19udW07Cj4+ICsJdTMyIHN0YXQ7Cj4+ICsJaW50IHJldDsK Pj4gKwo+PiArCXdyaXRlYih2YWx1ZSwgZWJ1X2hvc3QtPmNzW2NzX251bV0uY2hpcGFkZHIgKyBv ZmZzZXQpOwo+PiArCj4+ICsJcmV0ID0gcmVhZGxfcG9sbF90aW1lb3V0KG5hbmRfd2FpdCwgc3Rh dCwgc3RhdCAmIEVCVV9XQUlUX1dSX0MsCj4+ICsJCQkJIDIwLCAxMDAwKTsKPiAKPiBIZXJlIGFz IHdlbGwKTm90ZWQuCj4gCj4+ICsJaWYgKHJldCkKPj4gKwkJZGV2X3dhcm4oZWJ1X2hvc3QtPmRl diwKPj4gKwkJCSAiZWJ1IG5hbmQgd3JpdGUgdGltZW91dC4gbmFuZF93YWl0KDB4JXApPTB4JXhc biIsCj4+ICsJCQkgbmFuZF93YWl0LCByZWFkbChuYW5kX3dhaXQpKTsKPiAKPiBJZiB0aGlzIGNh biBmYWlsLCB0aGVuIHRoZSBoZWxwZXIgc2hvdWxkIHJldHVybiBhbiBlcnJvciBhbmQgYmUgdHJl YXRlZC4KTm90ZWQsIHdpbGwgdXBkYXRlLgo+IAo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBl YnVfcmVhZF9idWYoc3RydWN0IG5hbmRfY2hpcCAqY2hpcCwgdV9jaGFyICpidWYsIHVuc2lnbmVk IGludCBsZW4pCj4+ICt7Cj4+ICsJaW50IGk7Cj4+ICsKPj4gKwlmb3IgKGkgPSAwOyBpIDwgbGVu OyBpKyspCj4+ICsJCWJ1ZltpXSA9IGVidV9uYW5kX3JlYWRiKGNoaXApOwo+PiArfQo+PiArCj4+ ICtzdGF0aWMgdm9pZCBlYnVfd3JpdGVfYnVmKHN0cnVjdCBuYW5kX2NoaXAgKmNoaXAsIGNvbnN0 IHVfY2hhciAqYnVmLCBpbnQgbGVuKQo+PiArewo+PiArCWludCBpOwo+PiArCj4+ICsJZm9yIChp ID0gMDsgaSA8IGxlbjsgaSsrKQo+PiArCQllYnVfbmFuZF93cml0ZWIoY2hpcCwgSFNOQU5EX0NT X09GRlMsIGJ1ZltpXSk7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGVidV9uYW5kX2Rpc2Fi bGUoc3RydWN0IG5hbmRfY2hpcCAqY2hpcCkKPj4gK3sKPj4gKwlzdHJ1Y3QgZWJ1X25hbmRfY29u dHJvbGxlciAqZWJ1X2hvc3QgPSBuYW5kX2dldF9jb250cm9sbGVyX2RhdGEoY2hpcCk7Cj4+ICsK Pj4gKwl3cml0ZWwoMCwgZWJ1X2hvc3QtPmVidSArIEVCVV9DT04pOwo+PiArfQo+PiArCj4+ICtz dGF0aWMgdm9pZCBlYnVfc2VsZWN0X2NoaXAoc3RydWN0IG5hbmRfY2hpcCAqY2hpcCkKPj4gK3sK Pj4gKwlzdHJ1Y3QgZWJ1X25hbmRfY29udHJvbGxlciAqZWJ1X2hvc3QgPSBuYW5kX2dldF9jb250 cm9sbGVyX2RhdGEoY2hpcCk7Cj4+ICsJdm9pZCBfX2lvbWVtICpuYW5kX2NvbiA9IGVidV9ob3N0 LT5lYnUgKyBFQlVfQ09OOwo+PiArCXUzMiBjcyA9IGVidV9ob3N0LT5jc19udW07Cj4+ICsKPj4g Kwl3cml0ZWwoRUJVX0NPTl9OQU5ETV9FTiB8IEVCVV9DT05fQ1NNVVhfRV9FTiB8IEVCVV9DT05f Q1NfUF9MT1cgfAo+PiArCSAgICAgICBFQlVfQ09OX1NFX1BfTE9XIHwgRUJVX0NPTl9XUF9QX0xP VyB8IEVCVV9DT05fUFJFX1BfTE9XIHwKPj4gKwkgICAgICAgRUJVX0NPTl9JTl9DU19TKGNzKSB8 IEVCVV9DT05fT1VUX0NTX1MoY3MpIHwKPj4gKwkgICAgICAgRUJVX0NPTl9MQVRfRU5fQ1NfUCwg bmFuZF9jb24pOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBlYnVfbmFuZF9zZXR1cF90aW1p bmcoc3RydWN0IGVidV9uYW5kX2NvbnRyb2xsZXIgKmN0cmwsCj4+ICsJCQkJICBjb25zdCBzdHJ1 Y3QgbmFuZF9zZHJfdGltaW5ncyAqdGltaW5ncykKPj4gK3sKPj4gKwl1bnNpZ25lZCBpbnQgcmF0 ZSA9IGNsa19nZXRfcmF0ZShjdHJsLT5jbGspIC8gMTAwMDAwMDsKPj4gKwl1bnNpZ25lZCBpbnQg cGVyaW9kID0gRElWX1JPVU5EX1VQKDEwMDAwMDAsIHJhdGUpOwo+PiArCXUzMiB0cmVjb3YsIHRo b2xkLCB0d3J3YWl0LCB0cmR3YWl0Owo+PiArCXUzMiByZWcgPSAwOwo+PiArCj4+ICsJdHJlY292 ID0gRElWX1JPVU5EX1VQKG1heCh0aW1pbmdzLT50UkVBX21heCwgdGltaW5ncy0+dFJFSF9taW4p LAo+PiArCQkJICAgICAgcGVyaW9kKTsKPj4gKwlyZWcgfD0gRUJVX0JVU0NPTl9SRUNPVkModHJl Y292KTsKPj4gKwo+PiArCXRob2xkID0gRElWX1JPVU5EX1VQKG1heCh0aW1pbmdzLT50REhfbWlu LCB0aW1pbmdzLT50RFNfbWluKSwgcGVyaW9kKTsKPj4gKwlyZWcgfD0gRUJVX0JVU0NPTl9IT0xE Qyh0aG9sZCk7Cj4+ICsKPj4gKwl0cmR3YWl0ID0gRElWX1JPVU5EX1VQKG1heCh0aW1pbmdzLT50 UkNfbWluLCB0aW1pbmdzLT50UkVIX21pbiksCj4+ICsJCQkgICAgICAgcGVyaW9kKTsKPj4gKwly ZWcgfD0gRUJVX0JVU0NPTl9XQUlUUkRDKHRyZHdhaXQpOwo+PiArCj4+ICsJdHdyd2FpdCA9IERJ Vl9ST1VORF9VUChtYXgodGltaW5ncy0+dFdDX21pbiwgdGltaW5ncy0+dFdIX21pbiksIHBlcmlv ZCk7Cj4+ICsJcmVnIHw9IEVCVV9CVVNDT05fV0FJVFdSQyh0d3J3YWl0KTsKPj4gKwo+PiArCXJl ZyB8PSBFQlVfQlVTQ09OX0NNVUxUX1Y0IHwgRUJVX0JVU0NPTl9CQ0dFTl9DUyB8IEVCVV9CVVND T05fQUxFQyB8Cj4+ICsJCUVCVV9CVVNDT05fU0VUVVBfRU47Cj4+ICsKPj4gKwl3cml0ZWwocmVn LCBjdHJsLT5lYnUgKyBFQlVfQlVTQ09OKGN0cmwtPmNzX251bSkpOwo+PiArfQo+PiArCj4+ICtz dGF0aWMgaW50IGVidV9uYW5kX3NldHVwX2RhdGFfaW50ZXJmYWNlKHN0cnVjdCBuYW5kX2NoaXAg KmNoaXAsIGludCBjc2xpbmUsCj4+ICsJCQkJCSBjb25zdCBzdHJ1Y3QgbmFuZF9kYXRhX2ludGVy ZmFjZSAqY29uZikKPiAKPiBJIHJlY2VudGx5IGNoYW5nZWQgdGhlIG5hbWluZyBhcm91bmQgdGhl IGRhdGEgaW50ZXJmYWNlLCBwbGVhc2UKPiBoYXZlIGEgbG9vayBhdCB0aGUgcmVjZW50IGNvbW1p dHMgYW5kIHVwZGF0ZSB0aGUgbmFtaW5ncyBoZXJlIGFzCj4gd2VsbC4KU3VyZSwgd2lsbCBnbyB0 aHJvdWdoIHVwZGF0ZSBhY2NvcmRpbmdseS4KPiAKPj4gK3sKPj4gKwlzdHJ1Y3QgZWJ1X25hbmRf Y29udHJvbGxlciAqY3RybCA9IG5hbmRfdG9fZWJ1KGNoaXApOwo+PiArCWNvbnN0IHN0cnVjdCBu YW5kX3Nkcl90aW1pbmdzICp0aW1pbmdzOwo+PiArCj4+ICsJdGltaW5ncyA9IG5hbmRfZ2V0X3Nk cl90aW1pbmdzKGNvbmYpOwo+PiArCWlmIChJU19FUlIodGltaW5ncykpCj4+ICsJCXJldHVybiBQ VFJfRVJSKHRpbWluZ3MpOwo+PiArCj4+ICsJaWYgKGNzbGluZSA9PSBOQU5EX0RBVEFfSUZBQ0Vf Q0hFQ0tfT05MWSkKPj4gKwkJcmV0dXJuIDA7Cj4+ICsKPj4gKwllYnVfbmFuZF9zZXR1cF90aW1p bmcoY3RybCwgdGltaW5ncyk7Cj4+ICsKPj4gKwlyZXR1cm4gMDsKPj4gK30KPj4gKwo+PiArc3Rh dGljIGludCBlYnVfbmFuZF9vb2JsYXlvdXRfZWNjKHN0cnVjdCBtdGRfaW5mbyAqbXRkLCBpbnQg c2VjdGlvbiwKPj4gKwkJCQkgIHN0cnVjdCBtdGRfb29iX3JlZ2lvbiAqb29icmVnaW9uKQo+PiAr ewo+PiArCXN0cnVjdCBuYW5kX2NoaXAgKmNoaXAgPSBtdGRfdG9fbmFuZChtdGQpOwo+PiArCj4+ ICsJaWYgKHNlY3Rpb24pCj4+ICsJCXJldHVybiAtRVJBTkdFOwo+PiArCj4+ICsJb29icmVnaW9u LT5vZmZzZXQgPSBIU05BTkRfRUNDX09GRlNFVDsKPj4gKwlvb2JyZWdpb24tPmxlbmd0aCA9IGNo aXAtPmVjYy50b3RhbDsKPj4gKwo+PiArCXJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMg aW50IGVidV9uYW5kX29vYmxheW91dF9mcmVlKHN0cnVjdCBtdGRfaW5mbyAqbXRkLCBpbnQgc2Vj dGlvbiwKPj4gKwkJCQkgICBzdHJ1Y3QgbXRkX29vYl9yZWdpb24gKm9vYnJlZ2lvbikKPj4gK3sK Pj4gKwlzdHJ1Y3QgbmFuZF9jaGlwICpjaGlwID0gbXRkX3RvX25hbmQobXRkKTsKPj4gKwo+PiAr CWlmIChzZWN0aW9uKQo+PiArCQlyZXR1cm4gLUVSQU5HRTsKPj4gKwo+PiArCW9vYnJlZ2lvbi0+ b2Zmc2V0ID0gY2hpcC0+ZWNjLnRvdGFsICsgSFNOQU5EX0VDQ19PRkZTRVQ7Cj4+ICsJb29icmVn aW9uLT5sZW5ndGggPSBtdGQtPm9vYnNpemUgLSBvb2JyZWdpb24tPm9mZnNldDsKPj4gKwo+PiAr CXJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgY29uc3Qgc3RydWN0IG10ZF9vb2JsYXlv dXRfb3BzIGVidV9uYW5kX29vYmxheW91dF9vcHMgPSB7Cj4+ICsJLmVjYyA9IGVidV9uYW5kX29v YmxheW91dF9lY2MsCj4+ICsJLmZyZWUgPSBlYnVfbmFuZF9vb2JsYXlvdXRfZnJlZSwKPj4gK307 Cj4+ICsKPj4gK3N0YXRpYyB2b2lkIGVidV9kbWFfcnhfY2FsbGJhY2sodm9pZCAqY29va2llKQo+ PiArewo+PiArCXN0cnVjdCBlYnVfbmFuZF9jb250cm9sbGVyICplYnVfaG9zdCA9IGNvb2tpZTsK Pj4gKwo+PiArCWRtYWVuZ2luZV90ZXJtaW5hdGVfYXN5bmMoZWJ1X2hvc3QtPmRtYV9yeCk7Cj4+ ICsKPj4gKwljb21wbGV0ZSgmZWJ1X2hvc3QtPmRtYV9hY2Nlc3NfY29tcGxldGUpOwo+PiArfQo+ PiArCj4+ICtzdGF0aWMgdm9pZCBlYnVfZG1hX3R4X2NhbGxiYWNrKHZvaWQgKmNvb2tpZSkKPj4g K3sKPj4gKwlzdHJ1Y3QgZWJ1X25hbmRfY29udHJvbGxlciAqZWJ1X2hvc3QgPSBjb29raWU7Cj4+ ICsKPj4gKwlkbWFlbmdpbmVfdGVybWluYXRlX2FzeW5jKGVidV9ob3N0LT5kbWFfdHgpOwo+PiAr Cj4+ICsJY29tcGxldGUoJmVidV9ob3N0LT5kbWFfYWNjZXNzX2NvbXBsZXRlKTsKPj4gK30KPj4g Kwo+PiArc3RhdGljIGludCBlYnVfZG1hX3N0YXJ0KHN0cnVjdCBlYnVfbmFuZF9jb250cm9sbGVy ICplYnVfaG9zdCwgdTMyIGRpciwKPj4gKwkJCSBjb25zdCB1OCAqYnVmLCB1MzIgbGVuKQo+PiAr ewo+PiArCXN0cnVjdCBkbWFfYXN5bmNfdHhfZGVzY3JpcHRvciAqdHg7Cj4+ICsJc3RydWN0IGNv bXBsZXRpb24gKmRtYV9jb21wbGV0aW9uOwo+PiArCWRtYV9hc3luY190eF9jYWxsYmFjayBjYWxs YmFjazsKPj4gKwlzdHJ1Y3QgZG1hX2NoYW4gKmNoYW47Cj4+ICsJZG1hX2Nvb2tpZV90IGNvb2tp ZTsKPj4gKwl1bnNpZ25lZCBsb25nIGZsYWdzID0gRE1BX0NUUkxfQUNLIHwgRE1BX1BSRVBfSU5U RVJSVVBUOwo+PiArCWRtYV9hZGRyX3QgYnVmX2RtYTsKPj4gKwlpbnQgcmV0Owo+PiArCXUzMiB0 aW1lb3V0Owo+PiArCj4+ICsJaWYgKGRpciA9PSBETUFfREVWX1RPX01FTSkgewo+PiArCQljaGFu ID0gZWJ1X2hvc3QtPmRtYV9yeDsKPj4gKwkJZG1hX2NvbXBsZXRpb24gPSAmZWJ1X2hvc3QtPmRt YV9hY2Nlc3NfY29tcGxldGU7Cj4+ICsJCWNhbGxiYWNrID0gZWJ1X2RtYV9yeF9jYWxsYmFjazsK Pj4gKwl9IGVsc2Ugewo+PiArCQljaGFuID0gZWJ1X2hvc3QtPmRtYV90eDsKPj4gKwkJZG1hX2Nv bXBsZXRpb24gPSAmZWJ1X2hvc3QtPmRtYV9hY2Nlc3NfY29tcGxldGU7Cj4+ICsJCWNhbGxiYWNr ID0gZWJ1X2RtYV90eF9jYWxsYmFjazsKPj4gKwl9Cj4+ICsKPj4gKwlidWZfZG1hID0gZG1hX21h cF9zaW5nbGUoY2hhbi0+ZGV2aWNlLT5kZXYsICh2b2lkICopYnVmLCBsZW4sIGRpcik7Cj4+ICsJ aWYgKGRtYV9tYXBwaW5nX2Vycm9yKGNoYW4tPmRldmljZS0+ZGV2LCBidWZfZG1hKSkgewo+PiAr CQlkZXZfZXJyKGVidV9ob3N0LT5kZXYsICJGYWlsZWQgdG8gbWFwIERNQSBidWZmZXJcbiIpOwo+ PiArCQlyZXQgPSAtRUlPOwo+PiArCQlnb3RvIGVycl91bm1hcDsKPj4gKwl9Cj4+ICsKPj4gKwl0 eCA9IGRtYWVuZ2luZV9wcmVwX3NsYXZlX3NpbmdsZShjaGFuLCBidWZfZG1hLCBsZW4sIGRpciwg ZmxhZ3MpOwo+PiArCWlmICghdHgpCj4+ICsJCXJldHVybiAtRU5YSU87Cj4+ICsKPj4gKwl0eC0+ Y2FsbGJhY2sgPSBjYWxsYmFjazsKPj4gKwl0eC0+Y2FsbGJhY2tfcGFyYW0gPSBlYnVfaG9zdDsK Pj4gKwljb29raWUgPSB0eC0+dHhfc3VibWl0KHR4KTsKPj4gKwo+PiArCXJldCA9IGRtYV9zdWJt aXRfZXJyb3IoY29va2llKTsKPj4gKwlpZiAocmV0KSB7Cj4+ICsJCWRldl9lcnIoZWJ1X2hvc3Qt PmRldiwgImRtYV9zdWJtaXRfZXJyb3IgJWRcbiIsIGNvb2tpZSk7Cj4+ICsJCXJldCA9IC1FSU87 Cj4+ICsJCWdvdG8gZXJyX3VubWFwOwo+PiArCX0KPj4gKwo+PiArCWluaXRfY29tcGxldGlvbihk bWFfY29tcGxldGlvbik7Cj4+ICsJZG1hX2FzeW5jX2lzc3VlX3BlbmRpbmcoY2hhbik7Cj4+ICsK Pj4gKwkvKiBXYWl0IERNQSB0byBmaW5pc2ggdGhlIGRhdGEgdHJhbnNmZXIuKi8KPj4gKwl0aW1l b3V0ID0KPiAKPiBEb24ndCBicmVhayB0aGUgbGluZSBoZXJlCk9rYXksIE5vdGVkLgo+IAo+PiAr CXdhaXRfZm9yX2NvbXBsZXRpb25fdGltZW91dChkbWFfY29tcGxldGlvbiwgbXNlY3NfdG9famlm ZmllcygxMDAwKSk7Cj4+ICsJaWYgKCF0aW1lb3V0KSB7Cj4+ICsJCWRldl9lcnIoZWJ1X2hvc3Qt PmRldiwgIkkvTyBFcnJvciBpbiBETUEgUlggKHN0YXR1cyAlZClcbiIsCj4+ICsJCQlkbWFlbmdp bmVfdHhfc3RhdHVzKGNoYW4sIGNvb2tpZSwgTlVMTCkpOwo+PiArCQlkbWFlbmdpbmVfdGVybWlu YXRlX3N5bmMoY2hhbik7Cj4+ICsJCXJldCA9IC1FVElNRURPVVQ7Cj4+ICsJCWdvdG8gZXJyX3Vu bWFwOwo+PiArCX0KPj4gKwo+PiArCXJldHVybiAwOwo+PiArCj4+ICtlcnJfdW5tYXA6Cj4+ICsJ ZG1hX3VubWFwX3NpbmdsZShlYnVfaG9zdC0+ZGV2LCBidWZfZG1hLCBsZW4sIGRpcik7Cj4+ICsK Pj4gKwlyZXR1cm4gcmV0Owo+PiArfQo+PiArCj4+ICtzdGF0aWMgdm9pZCBlYnVfbmFuZF90cmln Z2VyKHN0cnVjdCBlYnVfbmFuZF9jb250cm9sbGVyICplYnVfaG9zdCwKPj4gKwkJCSAgICAgaW50 IHBhZ2UsIHUzMiBjbWQpCj4+ICt7Cj4+ICsJdW5zaWduZWQgaW50IHZhbDsKPj4gKwo+PiArCXZh bCA9IGNtZCB8IChwYWdlICYgMHhGRikgPDwgSFNOQU5EX0NUTDFfQUREUl9TSElGVDsKPj4gKwl3 cml0ZWwodmFsLCBlYnVfaG9zdC0+aHNuYW5kICsgSFNOQU5EX0NUTDEpOwo+PiArCXZhbCA9IChw YWdlICYgMHhGRkZGMDApID4+IDggfCBIU05BTkRfQ1RMMl9DWUNfTl9WNTsKPj4gKwl3cml0ZWwo dmFsLCBlYnVfaG9zdC0+aHNuYW5kICsgSFNOQU5EX0NUTDIpOwo+PiArCj4+ICsJd3JpdGVsKGVi dV9ob3N0LT5uZF9wYXJhMCwgZWJ1X2hvc3QtPmhzbmFuZCArIEhTTkFORF9QQVJBMCk7Cj4+ICsK Pj4gKwkvKiBjbGVhciBmaXJzdCwgd2lsbCB1cGRhdGUgbGF0ZXIgKi8KPj4gKwl3cml0ZWwoMHhG RkZGRkZGRiwgZWJ1X2hvc3QtPmhzbmFuZCArIEhTTkFORF9DTVNHXzApOwo+PiArCXdyaXRlbCgw eEZGRkZGRkZGLCBlYnVfaG9zdC0+aHNuYW5kICsgSFNOQU5EX0NNU0dfMSk7Cj4+ICsKPj4gKwl3 cml0ZWwoSFNOQU5EX0lOVF9NU0tfQ1RMX1dSX0MsCj4+ICsJICAgICAgIGVidV9ob3N0LT5oc25h bmQgKyBIU05BTkRfSU5UX01TS19DVEwpOwo+PiArCj4+ICsJdmFsID0gY21kID09IE5BTkRfQ01E X1JFQUQwID8gSFNOQU5EX0NUTF9SV19SRUFEIDogSFNOQU5EX0NUTF9SV19XUklURTsKPiAKPiBJ IGRvbid0IGxpa2UgdGhpcywgcHJlZmVyIGhhdmluZyBhICJyZWFkL3dyaXRlIiBib29sZWFuIGFz IGEgcGFyYW1ldGVyLgpOb3RlZCwgd2lsbCB1cGRhdGUuCj4gCj4+ICsKPj4gKwl3cml0ZWwoSFNO QU5EX0NUTF9NU0dfRU4gfCBIU05BTkRfQ1RMX0NLRkZfRU4gfAo+PiArCSAgICAgICBIU05BTkRf Q1RMX0VDQ19PRkZfVjhUSCB8IEhTTkFORF9DVExfQ0VfU0VMX0NTKGVidV9ob3N0LT5jc19udW0p IHwKPj4gKwkgICAgICAgSFNOQU5EX0NUTF9FTkFCTEVfRUNDIHwgSFNOQU5EX0NUTF9HTyB8IHZh bCwKPj4gKwkgICAgICAgZWJ1X2hvc3QtPmhzbmFuZCArIEhTTkFORF9DVEwpOwo+PiArfQo+PiAr Cj4+ICtzdGF0aWMgaW50IGVidV9uYW5kX3JlYWRfcGFnZV9od2VjYyhzdHJ1Y3QgbmFuZF9jaGlw ICpjaGlwLCB1OCAqYnVmLAo+PiArCQkJCSAgICBpbnQgb29iX3JlcXVpcmVkLCBpbnQgcGFnZSkK Pj4gK3sKPj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10ZCA9IG5hbmRfdG9fbXRkKGNoaXApOwo+PiAr CXN0cnVjdCBlYnVfbmFuZF9jb250cm9sbGVyICplYnVfaG9zdCA9IG5hbmRfZ2V0X2NvbnRyb2xs ZXJfZGF0YShjaGlwKTsKPj4gKwlpbnQgcmV0LCB4Owo+PiArCj4+ICsJZWJ1X25hbmRfdHJpZ2dl cihlYnVfaG9zdCwgcGFnZSwgTkFORF9DTURfUkVBRDApOwo+PiArCj4+ICsJcmV0ID0gZWJ1X2Rt YV9zdGFydChlYnVfaG9zdCwgRE1BX0RFVl9UT19NRU0sIGJ1ZiwgbXRkLT53cml0ZXNpemUpOwo+ PiArCWlmIChyZXQpCj4+ICsJCXJldHVybiByZXQ7Cj4+ICsKPj4gKwlpZiAob29iX3JlcXVpcmVk KQo+PiArCQljaGlwLT5lY2MucmVhZF9vb2IoY2hpcCwgcGFnZSk7Cj4+ICsKPj4gKwl4ID0gcmVh ZGwoZWJ1X2hvc3QtPmhzbmFuZCArIEhTTkFORF9DVEwpOwo+PiArCXggJj0gfkhTTkFORF9DVExf R087Cj4+ICsJd3JpdGVsKHgsIGVidV9ob3N0LT5oc25hbmQgKyBIU05BTkRfQ1RMKTsKPj4gKwo+ PiArCXJldHVybiAwOwo+PiArfQo+PiArCj4+ICtzdGF0aWMgaW50IGVidV9uYW5kX3dyaXRlX3Bh Z2VfaHdlY2Moc3RydWN0IG5hbmRfY2hpcCAqY2hpcCwgY29uc3QgdTggKmJ1ZiwKPj4gKwkJCQkg ICAgIGludCBvb2JfcmVxdWlyZWQsIGludCBwYWdlKQo+PiArewo+PiArCXN0cnVjdCBtdGRfaW5m byAqbXRkID0gbmFuZF90b19tdGQoY2hpcCk7Cj4+ICsJc3RydWN0IGVidV9uYW5kX2NvbnRyb2xs ZXIgKmVidV9ob3N0ID0gbmFuZF9nZXRfY29udHJvbGxlcl9kYXRhKGNoaXApOwo+PiArCXZvaWQg X19pb21lbSAqaW50X3N0YSA9IGVidV9ob3N0LT5oc25hbmQgKyBIU05BTkRfSU5UX1NUQTsKPj4g KwlpbnQgcmV0LCB2YWwsIHg7Cj4+ICsJdTMyIHJlZzsKPj4gKwo+PiArCWVidV9uYW5kX3RyaWdn ZXIoZWJ1X2hvc3QsIHBhZ2UsIE5BTkRfQ01EX1NFUUlOKTsKPj4gKwo+PiArCXJldCA9IGVidV9k bWFfc3RhcnQoZWJ1X2hvc3QsIERNQV9NRU1fVE9fREVWLCBidWYsIG10ZC0+d3JpdGVzaXplKTsK Pj4gKwlpZiAocmV0KQo+PiArCQlyZXR1cm4gcmV0Owo+PiArCj4+ICsJaWYgKG9vYl9yZXF1aXJl ZCkgewo+PiArCQlyZWcgPSAoY2hpcC0+b29iX3BvaVszXSA8PCAyNCkgfCAoY2hpcC0+b29iX3Bv aVsyXSA8PCAxNikgfAo+PiArCQkJKGNoaXAtPm9vYl9wb2lbMV0gPDwgOCkgfCBjaGlwLT5vb2Jf cG9pWzBdOwo+PiArCj4+ICsJCXdyaXRlbChyZWcsIGVidV9ob3N0LT5oc25hbmQgKyBIU05BTkRf Q01TR18wKTsKPj4gKwo+PiArCQlyZWcgPSAoY2hpcC0+b29iX3BvaVs3XSA8PCAyNCkgfCAoY2hp cC0+b29iX3BvaVs2XSA8PCAxNikgfAo+PiArCQkJKGNoaXAtPm9vYl9wb2lbNV0gPDwgOCkgfCBj aGlwLT5vb2JfcG9pWzRdOwo+PiArCj4+ICsJCXdyaXRlbChyZWcsIGVidV9ob3N0LT5oc25hbmQg KyBIU05BTkRfQ01TR18xKTsKPj4gKwl9Cj4+ICsKPj4gKwlyZXQgPSByZWFkbF9wb2xsX3RpbWVv dXRfYXRvbWljKGludF9zdGEsIHZhbCwKPj4gKwkJCQkJISh2YWwgJiBIU05BTkRfSU5UX1NUQV9X Ul9DKSwgMTAsIDEwMDApOwo+PiArCWlmIChyZXQpCj4+ICsJCXJldHVybiAtRUlPOwo+IAo+IHJl dHVybiByZXQgPwpZZXMsIHJldCB3aWxsIGNvbWUuCj4gCj4+ICsKPj4gKwl4ID0gcmVhZGwoZWJ1 X2hvc3QtPmhzbmFuZCArIEhTTkFORF9DVEwpOwo+PiArCXggJj0gfkhTTkFORF9DVExfR087Cj4+ ICsJd3JpdGVsKHgsIGVidV9ob3N0LT5oc25hbmQgKyBIU05BTkRfQ1RMKTsKPiAKPiBXaGF0IGlz IHRoaXM/IExvb2tzIGxpa2UgaXQgZGVzZXJ2ZXMgYSBoZWxwZXIgd2l0aCBhIG5pY2UgbmFtZS4K UmVnaXN0ZXIgSGlnaCBTcGVlZCBOQU5EIGNvbnRyb2wsIGl0IGlzIGV4Y2VlZGluZyB0aGUgODAg Y2hhcmFjdGVycyB0byAKYXZvaWQgdGhhdCwgc2hvcnQgaXQsIHdpbGwgdXBkYXRlLgo+IAo+PiAr Cj4+ICsJcmV0dXJuIDA7Cj4+ICt9Cj4+ICsKPj4gK3N0YXRpYyBjb25zdCB1OCBlY2Nfc3RyZW5n dGhbXSA9IHsgMSwgMSwgNCwgOCwgMjQsIDMyLCA0MCwgNjAsIH07Cj4gCj4gICAgICAgICAgICAg ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXiBpcyB0aGlzIG5vcm1hbD8KPiAKPj4gKwo+ PiArc3RhdGljIGludCBlYnVfbmFuZF9hdHRhY2hfY2hpcChzdHJ1Y3QgbmFuZF9jaGlwICpjaGlw KQo+PiArewo+PiArCXN0cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZF90b19tdGQoY2hpcCk7Cj4+ ICsJc3RydWN0IGVidV9uYW5kX2NvbnRyb2xsZXIgKmVidV9ob3N0ID0gbmFuZF9nZXRfY29udHJv bGxlcl9kYXRhKGNoaXApOwo+PiArCXUzMiBlY2Nfc3RlcHMsIGVjY19ieXRlcywgZWNjX3RvdGFs LCBwYWdlc2l6ZSwgcGdfcGVyX2JsazsKPj4gKwl1MzIgZWNjX3N0cmVuZ3RoX2RzID0gY2hpcC0+ ZWNjLnN0cmVuZ3RoOwo+PiArCXUzMiBlY2Nfc2l6ZSA9IGNoaXAtPmVjYy5zaXplOwo+PiArCXUz MiB3cml0ZXNpemUgPSBtdGQtPndyaXRlc2l6ZTsKPj4gKwl1MzIgYmxvY2tzaXplID0gbXRkLT5l cmFzZXNpemU7Cj4+ICsJaW50IGJjaF9hbGdvLCBzdGFydCwgdmFsOwo+PiArCj4+ICsJaWYgKGNo aXAtPmVjYy5tb2RlICE9IE5BTkRfRUNDX0hXKQo+PiArCQlyZXR1cm4gMDsKPj4gKwo+PiArCS8q IERlZmF1bHQgdG8gYW4gRUNDIHNpemUgb2YgNTEyICovCj4+ICsJaWYgKCFjaGlwLT5lY2Muc2l6 ZSkKPj4gKwkJY2hpcC0+ZWNjLnNpemUgPSA1MTI7Cj4+ICsKPj4gKwlzd2l0Y2ggKGVjY19zaXpl KSB7Cj4+ICsJY2FzZSA1MTI6Cj4+ICsJCXN0YXJ0ID0gMTsKPj4gKwkJaWYgKCFlY2Nfc3RyZW5n dGhfZHMpCj4+ICsJCQllY2Nfc3RyZW5ndGhfZHMgPSA0Owo+PiArCQlicmVhazsKPj4gKwljYXNl IDEwMjQ6Cj4+ICsJCXN0YXJ0ID0gNDsKPj4gKwkJaWYgKCFlY2Nfc3RyZW5ndGhfZHMpCj4+ICsJ CQllY2Nfc3RyZW5ndGhfZHMgPSAzMjsKPj4gKwkJYnJlYWs7Cj4+ICsJZGVmYXVsdDoKPj4gKwkJ cmV0dXJuIC1FSU5WQUw7Cj4+ICsJfQo+PiArCj4+ICsJLyogQkNIIEVDQyBhbGdvcml0aG0gU2V0 dGluZ3MgZm9yIG51bWJlciBvZiBiaXRzIHBlciA1MTJCLzEwMjRCICovCj4+ICsJYmNoX2FsZ28g PSByb3VuZF91cChzdGFydCArIDEsIDQpOwo+PiArCWZvciAodmFsID0gc3RhcnQ7IHZhbCA8IGJj aF9hbGdvOyB2YWwrKykgewo+PiArCQlpZiAoZWNjX3N0cmVuZ3RoX2RzID09IGVjY19zdHJlbmd0 aFt2YWxdKQo+PiArCQkJYnJlYWs7Cj4+ICsJfQo+PiArCWlmICh2YWwgPT0gYmNoX2FsZ28pCj4+ ICsJCXJldHVybiAtRUlOVkFMOwo+PiArCj4+ICsJaWYgKGVjY19zdHJlbmd0aF9kcyA9PSA4KQo+ PiArCQllY2NfYnl0ZXMgPSAxNDsKPj4gKwllbHNlCj4+ICsJCWVjY19ieXRlcyA9IERJVl9ST1VO RF9VUChlY2Nfc3RyZW5ndGhfZHMgKiBmbHMoOCAqIGVjY19zaXplKSwgOCk7Cj4+ICsKPj4gKwll Y2Nfc3RlcHMgPSB3cml0ZXNpemUgLyBlY2Nfc2l6ZTsKPj4gKwllY2NfdG90YWwgPSBlY2Nfc3Rl cHMgKiBlY2NfYnl0ZXM7Cj4+ICsJaWYgKChlY2NfdG90YWwgKyA4KSA+IG10ZC0+b29ic2l6ZSkK Pj4gKwkJcmV0dXJuIC1FUkFOR0U7Cj4+ICsKPj4gKwljaGlwLT5lY2MudG90YWwgPSBlY2NfdG90 YWw7Cj4+ICsJcGFnZXNpemUgPSBmbHMod3JpdGVzaXplID4+IDExKTsKPj4gKwlpZiAocGFnZXNp emUgPiBIU05BTkRfUEFSQTBfUEFHRV9WODE5MikKPj4gKwkJcmV0dXJuIC1FUkFOR0U7Cj4+ICsK Pj4gKwlwZ19wZXJfYmxrID0gZmxzKChibG9ja3NpemUgLyB3cml0ZXNpemUpID4+IDYpIDw8IDQ7 Cj4gCj4gSWYgPDwgNCBpcyBoZXJlIHRvIG1lYW4gLyA4LCB0aGVuIEkgZG9uJ3Qgd2FudCBhIHNo aWZ0IG9wZXJhdGlvbgo+IGJlY2F1c2UgaXQgaXMgaGlnaGx5IHVucmVhZGFibGUgYW5kIGNvbXBp bGVycyBrbm93IGhvdyB0byBvcHRpbWl6ZQo+IHRoaXMuClRoYW5rcyEsIHdpbGwgdXBkYXRlLgo+ IAo+PiArCWlmIChwZ19wZXJfYmxrID4gSFNOQU5EX1BBUkEwX1BJQl9WMjU2KQo+PiArCQlyZXR1 cm4gLUVSQU5HRTsKPj4gKwo+PiArCWVidV9ob3N0LT5uZF9wYXJhMCA9IHBhZ2VzaXplIHwgcGdf cGVyX2JsayB8IEhTTkFORF9QQVJBMF9CWVBfRU5fTlAgfAo+PiArCQkJICAgICBIU05BTkRfUEFS QTBfQllQX0RFQ19OUCB8IEhTTkFORF9QQVJBMF9BREVQX0VOIHwKPj4gKwkJCSAgICAgSFNOQU5E X1BBUkEwX1RZUEVfT05GSSB8ICh2YWwgPDwgMjkpOwo+PiArCj4+ICsJbXRkX3NldF9vb2JsYXlv dXQobXRkLCAmZWJ1X25hbmRfb29ibGF5b3V0X29wcyk7Cj4+ICsJY2hpcC0+ZWNjLnJlYWRfcGFn ZSA9IGVidV9uYW5kX3JlYWRfcGFnZV9od2VjYzsKPj4gKwljaGlwLT5lY2Mud3JpdGVfcGFnZSA9 IGVidV9uYW5kX3dyaXRlX3BhZ2VfaHdlY2M7Cj4+ICsKPj4gKwlyZXR1cm4gMDsKPj4gK30KPj4g Kwo+PiArc3RhdGljIGludCBlYnVfbmFuZF9leGVjX29wKHN0cnVjdCBuYW5kX2NoaXAgKmNoaXAs Cj4+ICsJCQkgICAgY29uc3Qgc3RydWN0IG5hbmRfb3BlcmF0aW9uICpvcCwgYm9vbCBjaGVja19v bmx5KQo+PiArewo+PiArCXN0cnVjdCBlYnVfbmFuZF9jb250cm9sbGVyICpjdHJsID0gbmFuZF90 b19lYnUoY2hpcCk7Cj4+ICsJY29uc3Qgc3RydWN0IG5hbmRfb3BfaW5zdHIgKmluc3RyID0gTlVM TDsKPj4gKwl1bnNpZ25lZCBpbnQgb3BfaWQ7Cj4+ICsJaW50IGksIHRpbWVfb3V0LCByZXQgPSAw Owo+PiArCXUzMiBzdGF0Owo+PiArCj4+ICsJaWYgKGNoZWNrX29ubHkpCj4+ICsJCWVidV9zZWxl Y3RfY2hpcChjaGlwKTsKPiAKPiBXaGF0IGlzIHRoZSBwb2ludCBvZiBzZWxlY3RpbmcgdGhlIGNo aXAgaWYgY2hlY2tfb25seSBpcyB0cnVlPwp3aGlsZSBjb252ZXJ0aW5nIHRvIGV4ZWNfb3AoKSBi YXNlZCBkYXRhIHN0cnVjdHVyZSwgYWRkZWQgbGlrZSBvdGhlciAKZHJpdmVycywgbGV0IG1lIGNo ZWNrIGFuZCB1cGRhdGUgYWNjb3JkaW5nbHksIFRoYW5rcyEuCgpSZWdhcmRzClZhZGl2ZWwKPiAK Pj4gKwo+PiArCWZvciAob3BfaWQgPSAwOyBvcF9pZCA8IG9wLT5uaW5zdHJzOyBvcF9pZCsrKSB7 Cj4+ICsJCWluc3RyID0gJm9wLT5pbnN0cnNbb3BfaWRdOwo+PiArCj4+ICsJCXN3aXRjaCAoaW5z dHItPnR5cGUpIHsKPj4gKwkJY2FzZSBOQU5EX09QX0NNRF9JTlNUUjoKPj4gKwkJCWVidV9uYW5k X3dyaXRlYihjaGlwLCBIU05BTkRfQ0xFX09GRlMgfCBIU05BTkRfQ1NfT0ZGUywKPj4gKwkJCQkJ aW5zdHItPmN0eC5jbWQub3Bjb2RlKTsKPj4gKwkJCWJyZWFrOwo+PiArCj4+ICsJCWNhc2UgTkFO RF9PUF9BRERSX0lOU1RSOgo+PiArCQkJZm9yIChpID0gMDsgaSA8IGluc3RyLT5jdHguYWRkci5u YWRkcnM7IGkrKykKPj4gKwkJCQllYnVfbmFuZF93cml0ZWIoY2hpcCwKPj4gKwkJCQkJCUhTTkFO RF9BTEVfT0ZGUyB8IEhTTkFORF9DU19PRkZTLAo+PiArCQkJCQkJaW5zdHItPmN0eC5hZGRyLmFk ZHJzW2ldKTsKPj4gKwkJCWJyZWFrOwo+PiArCj4+ICsJCWNhc2UgTkFORF9PUF9EQVRBX0lOX0lO U1RSOgo+PiArCQkJZWJ1X3JlYWRfYnVmKGNoaXAsIGluc3RyLT5jdHguZGF0YS5idWYuaW4sCj4+ ICsJCQkJICAgICBpbnN0ci0+Y3R4LmRhdGEubGVuKTsKPj4gKwkJCWJyZWFrOwo+PiArCj4+ICsJ CWNhc2UgTkFORF9PUF9EQVRBX09VVF9JTlNUUjoKPj4gKwkJCWVidV93cml0ZV9idWYoY2hpcCwg aW5zdHItPmN0eC5kYXRhLmJ1Zi5vdXQsCj4+ICsJCQkJICAgICAgaW5zdHItPmN0eC5kYXRhLmxl bik7Cj4+ICsJCQlicmVhazsKPj4gKwo+PiArCQljYXNlIE5BTkRfT1BfV0FJVFJEWV9JTlNUUjoK Pj4gKwkJCXRpbWVfb3V0ID0gaW5zdHItPmN0eC53YWl0cmR5LnRpbWVvdXRfbXMgKiAxMDAwOwo+ PiArCQkJcmV0ID0gcmVhZGxfcG9sbF90aW1lb3V0KGN0cmwtPmVidSArIEVCVV9XQUlULAo+PiAr CQkJCQkJIHN0YXQsIHN0YXQgJiBFQlVfV0FJVF9SREJZLAo+PiArCQkJCQkJIDIwLCB0aW1lX291 dCk7Cj4+ICsJCQlicmVhazsKPj4gKwkJfQo+PiArCX0KPj4gKwo+PiArCXJldHVybiByZXQ7Cj4+ ICt9Cj4gCj4gCj4gVGhhbmtzLAo+IE1pcXXDqGwKPiAKCl9fX19fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fXwpMaW51eCBNVEQgZGlzY3Vzc2lvbiBtYWls aW5nIGxpc3QKaHR0cDovL2xpc3RzLmluZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51 eC1tdGQvCg==