From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from relay8-d.mail.gandi.net (relay8-d.mail.gandi.net [217.70.183.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EF8B3130A53; Wed, 22 May 2024 12:33:22 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=217.70.183.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716381206; cv=none; b=QGq/t6ELQeQbomY8Wh888URtaXX5G4OwryqNB4BJw3Ts1x7CRicp04M+HXwOsILH2IEKDNxTEoSfxezrfVda2Ap8FwIPtFgiO3x/D+198sOTDdZVeefcJM6MhoRTGo9bOzt4Lz/ip5AHByc1y478Uv57f0Q+oKsJ0WnJpDzv76w= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1716381206; c=relaxed/simple; bh=EMhvfd4ILhEWsFWJgTd9LIrVGsi+7U3+WdORZpeDiew=; h=Date:From:To:Cc:Subject:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Vc9pRCRFupZZi5kEzTwEcCVScVY8mQ4An0+gqkzV94s6GlaPjFNYoxQx2xBlOqS/lPpOWivTfURfqqfUmBSTPDT6wBPk/6JYwd6iwnIbERUGu8zzNo91LFb0ebMmn2SlxQLqYgOkmpbCIf1P9AYP0DfRbEVuCBMC4iwgUMGcA9g= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com; spf=pass smtp.mailfrom=bootlin.com; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b=PQN0sewa; arc=none smtp.client-ip=217.70.183.201 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=bootlin.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=bootlin.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=bootlin.com header.i=@bootlin.com header.b="PQN0sewa" Received: by mail.gandi.net (Postfix) with ESMTPSA id 71DC41BF213; Wed, 22 May 2024 12:33:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1716381200; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=D4J4CYGBoBW9h9ZVxR2P3e6r3PhKjkKgpn0sAzWc+hM=; b=PQN0sewa7o74X7XHG9jJNLXCGqTq6dvbQnVsbAjK2VH9LBu8We3jOqSOl4lugWwnQ4EvZX 7hfztpgkGJWuZhZM3LaH5cH+ajxvuom8/OtTzGK6HywyloiICj9JC3nveLDkIhNottyhL5 Ot8dDhcA6u6nYPBuTGxv5AYKsKXOve/y5EmRIyXopeFGMixOaT8wGnvlWcbue0aDrB4X2I RviL4GzHh0Cd68a9dw+a9HMtVVG6HlBGRQvXFjYlWlOo7jv/sSNjbov8Gc+eYjOOyF6iRt 54asP+RYiy/do2bPNZccGSMg1ERyGu+Jh58+lTyPtn1hwmmKKi/DfqIeGuJwMw== Date: Wed, 22 May 2024 14:33:17 +0200 From: Miquel Raynal To: Md Sadre Alam Cc: , , , , , , , , , , , , , , , Subject: Re: [PATCH v6 6/8] spi: spi-qpic: add driver for QCOM SPI NAND flash Interface Message-ID: <20240522143317.07f78601@xps-13> In-Reply-To: <5b96e24a-edcd-df85-9e70-332a6059ee73@quicinc.com> References: <20240521105532.1537845-1-quic_mdalam@quicinc.com> <20240521105532.1537845-7-quic_mdalam@quicinc.com> <20240521152410.7cff71ab@xps-13> <5b96e24a-edcd-df85-9e70-332a6059ee73@quicinc.com> Organization: Bootlin X-Mailer: Claws Mail 4.1.1 (GTK 3.24.38; x86_64-pc-linux-gnu) Precedence: bulk X-Mailing-List: linux-arm-msm@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable X-GND-Sasl: miquel.raynal@bootlin.com Hi, > >> +static int qcom_spi_ooblayout_ecc(struct mtd_info *mtd, int section, > >> + struct mtd_oob_region *oobregion) > >> +{ > >> + struct nand_device *nand =3D mtd_to_nanddev(mtd); > >> + struct qcom_nand_controller *snandc =3D nand_to_qcom_snand(nand); > >> + struct qpic_ecc *qecc =3D snandc->qspi->ecc; > >> + > >> + if (section > 1) > >> + return -ERANGE; > >> + > >> + if (!section) { > >> + oobregion->length =3D (qecc->bytes * (qecc->steps - 1)) + qecc->bbm= _size; > >> + oobregion->offset =3D 0; =20 > >=20 > > No, offset 0 is for the BBM. This is wrong. > > The whole oob layout looks really really wrong. > >=20 > > ECC bytes are where the ECC engine puts its bytes in the OOB area. > > Free bytes start after the BBM and fill the gaps until the end of the > > area, except where there are ECC bytes. =20 > QPIC NAND controller having its own page layout with ecc and without ec= c. > The same layout we are using in raw nand driver as well, so i used the > same here. The below info is already there in qcom raw nand driver file > in page layout info. >=20 > QPIC NAND controller layout as below: >=20 > Layout with ECC enabled: >=20 > |----------------------| |---------------------------------| > | xx.......yy| | *********xx.......yy| > | DATA xx..ECC..yy| | DATA **SPARE**xx..ECC..yy| > | (516) xx.......yy| | (516-n*4) **(n*4)**xx.......yy| > | xx.......yy| | *********xx.......yy| > |----------------------| |---------------------------------| > codeword 1,2..n-1 codeword n > <---(528/532 Bytes)--> <-------(528/532 Bytes)---------> >=20 > n =3D Number of codewords in the page > . =3D ECC bytes > * =3D Spare/free bytes > x =3D Unused byte(s) > y =3D Reserved byte(s) >=20 > 2K page: n =3D 4, spare =3D 16 bytes > 4K page: n =3D 8, spare =3D 32 bytes > 8K page: n =3D 16, spare =3D 64 bytes >=20 > the qcom nand controller operates at a sub page/codeword level. each > codeword is 528 and 532 bytes for 4 bit and 8 bit ECC modes respecti= vely. > the number of ECC bytes vary based on the ECC strength and the bus w= idth. >=20 > the first n - 1 codewords contains 516 bytes of user data, the remai= ning > 12/16 bytes consist of ECC and reserved data. The nth codeword conta= ins > both user data and spare(oobavail) bytes that sum up to 516 bytes. >=20 > When we access a page with ECC enabled, the reserved bytes(s) are not > accessible at all. When reading, we fill up these unreadable positio= ns > with 0xffs. When writing, the controller skips writing the inaccessi= ble > bytes. >=20 > Layout with ECC disabled: >=20 > |------------------------------| |---------------------------------= ------| > | yy xx.......| | bb *********xx.= ......| > | DATA1 yy DATA2 xx..ECC..| | DATA1 bb DATA2 **SPARE**xx.= .ECC..| > | (size1) yy (size2) xx.......| | (size1) bb (size2) **(n*4)**xx.= ......| > | yy xx.......| | bb *********xx.= ......| > |------------------------------| |---------------------------------= ------| > codeword 1,2..n-1 codeword n > <-------(528/532 Bytes)------> <-----------(528/532 Bytes)-------= ----> >=20 > n =3D Number of codewords in the page > . =3D ECC bytes > * =3D Spare/free bytes > x =3D Unused byte(s) > y =3D Dummy Bad Bock byte(s) > b =3D Real Bad Block byte(s) > size1/size2 =3D function of codeword size and 'n' >=20 > when the ECC block is disabled, one reserved byte (or two for 16 bit= bus > width) is now accessible. For the first n - 1 codewords, these are d= ummy Bad > Block Markers. In the last codeword, this position contains the real= BBM >=20 > In order to have a consistent layout between RAW and ECC modes, we a= ssume > the following OOB layout arrangement: >=20 > |-----------| |--------------------| > |yyxx.......| |bb*********xx.......| > |yyxx..ECC..| |bb*FREEOOB*xx..ECC..| > |yyxx.......| |bb*********xx.......| > |yyxx.......| |bb*********xx.......| > |-----------| |--------------------| > first n - 1 nth OOB region > OOB regions >=20 > n =3D Number of codewords in the page > . =3D ECC bytes > * =3D FREE OOB bytes > y =3D Dummy bad block byte(s) (inaccessible when ECC enabled) > x =3D Unused byte(s) > b =3D Real bad block byte(s) (inaccessible when ECC enabled) >=20 > This layout is read as is when ECC is disabled. When ECC is enabled,= the > inaccessible Bad Block byte(s) are ignored when we write to a page/o= ob, > and assumed as 0xffs when we read a page/oob. The ECC, unused and > dummy/real bad block bytes are grouped as ecc bytes (i.e, ecc->bytes= is > the sum of the three). Thanks for the detailed explanation (which would benefit from being added somewhere in a comment, maybe at the top of the file). Unfortunately, these ooblayout callbacks do work on a flat layout, not on the hardware ECC engine layout. So whatever the real physical position of the bad block marker within the NAND array, these markers will always be at offset 0 and 1 in the OOB final buffer. Same applies to the spare and ECC bytes. These layouts are totally wrong and must be fixed. If the layouts are the same in both raw/spi cases, maybe they should be part of the common file? > >> + } else { > >> + oobregion->length =3D qecc->ecc_bytes_hw + qecc->spare_bytes; > >> + oobregion->offset =3D mtd->oobsize - oobregion->length; > >> + } > >> + > >> + return 0; > >> +} > >> + > >> +static int qcom_spi_ooblayout_free(struct mtd_info *mtd, int section, > >> + struct mtd_oob_region *oobregion) > >> +{ > >> + struct nand_device *nand =3D mtd_to_nanddev(mtd); > >> + struct qcom_nand_controller *snandc =3D nand_to_qcom_snand(nand); > >> + struct qpic_ecc *qecc =3D snandc->qspi->ecc; > >> + > >> + if (section) > >> + return -ERANGE; > >> + > >> + oobregion->length =3D qecc->steps * 4; > >> + oobregion->offset =3D ((qecc->steps - 1) * qecc->bytes) + qecc->bbm_= size; > >> + > >> + return 0; > >> +} > >> + =20 > >=20 > > ... > > =20 > >> +static int qcom_spi_ecc_prepare_io_req_pipelined(struct nand_device *= nand, > >> + struct nand_page_io_req *req) > >> +{ > >> + struct qcom_nand_controller *snandc =3D nand_to_qcom_snand(nand); > >> + struct qpic_ecc *ecc_cfg =3D nand_to_ecc_ctx(nand); > >> + struct mtd_info *mtd =3D nanddev_to_mtd(nand); > >> + > >> + snandc->qspi->ecc =3D ecc_cfg; > >> + snandc->qspi->pagesize =3D mtd->writesize; > >> + snandc->qspi->raw_rw =3D false; > >> + snandc->qspi->oob_rw =3D false; > >> + snandc->qspi->page_rw =3D false; > >> + > >> + if (req->datalen) > >> + snandc->qspi->page_rw =3D true; > >> + > >> + if (req->ooblen) { > >> + snandc->qspi->oob_rw =3D true; > >> + if (req->ooblen =3D=3D BAD_BLOCK_MARKER_SIZE) > >> + snandc->qspi->read_last_cw =3D true; =20 > >=20 > > ??? =20 > As per QPIC controller layout , the actual babd block marker will > be present in last code word. Thats why i have added this check. > to read only last codeword for bad block check. You need to comply with the request. If ooblen is !=3D 0, you need to read the codeword(s) where the oob is. Please don't try to be smarter than that. Checking the _value_ of ooblen is an optimization I don't think is worth. > > =20 > >> + } > >> + > >> + if (req->mode =3D=3D MTD_OPS_RAW) > >> + snandc->qspi->raw_rw =3D true; > >> + > >> + return 0; > >> +} > >> + > >> +static int qcom_spi_ecc_finish_io_req_pipelined(struct nand_device *n= and, > >> + struct nand_page_io_req *req) > >> +{ > >> + struct qcom_nand_controller *snandc =3D nand_to_qcom_snand(nand); > >> + struct mtd_info *mtd =3D nanddev_to_mtd(nand); > >> + > >> + if (req->mode =3D=3D MTD_OPS_RAW || req->type !=3D NAND_PAGE_READ) > >> + return 0; > >> + > >> + if (snandc->qspi->ecc_stats.failed) > >> + mtd->ecc_stats.failed +=3D snandc->qspi->ecc_stats.failed; > >> + mtd->ecc_stats.corrected +=3D snandc->qspi->ecc_stats.corrected; =20 > >=20 > > Seems strange =20 > In flash error check for each code word i am updating the error value. > So on finishing on io i am assigning that error to mtd variables so th= at > upper layer check for error. You don't clear the qspi ecc_stats so this cannot work properly. Plus, I would welcome an else statement for incrementing the corrected field. > > =20 > >> + > >> + if (snandc->qspi->ecc_stats.failed) > >> + return -EBADMSG; > >> + else > >> + return snandc->qspi->ecc_stats.bitflips; > >> +} > >> + > >> +static struct nand_ecc_engine_ops qcom_spi_ecc_engine_ops_pipelined = =3D { > >> + .init_ctx =3D qcom_spi_ecc_init_ctx_pipelined, > >> + .cleanup_ctx =3D qcom_spi_ecc_cleanup_ctx_pipelined, > >> + .prepare_io_req =3D qcom_spi_ecc_prepare_io_req_pipelined, > >> + .finish_io_req =3D qcom_spi_ecc_finish_io_req_pipelined, > >> +}; > >> + =20 > >=20 > > ... > > =20 > >> +static int qcom_spi_read_page_raw(struct qcom_nand_controller *snandc, > >> + const struct spi_mem_op *op) > >> +{ > >> + struct qpic_ecc *ecc_cfg =3D snandc->qspi->ecc; > >> + u8 *data_buf =3D NULL, *oob_buf =3D NULL; > >> + int ret, cw; > >> + u32 num_cw =3D snandc->qspi->num_cw; > >> + > >> + if (snandc->qspi->page_rw) =20 > >=20 > > I don't like this indirection very much. Can't you simplify this and > > just follow the spi-mem op instead of constantly trying to add > > additional stuff? =20 > This indirection needed due to QPIC controller will not take all the i= nstruction > one-by-one , once we will set CMD_EXEC =3D 1, then it will execute all= the instruction > at once. The spi_mem_op structure already describes the whole operation. Why do you split the operation in sub routines if you can't actually do that? > >=20 > > The hardware is already quite complex, but it feels like your adding > > yet another pile of unnecessary complexity. =20 > Yes hardware is complex. let me check if i can further optimize as per= spi-mem op > as you suggested. > > =20 > >> + data_buf =3D op->data.buf.in; > >> + > >> + if (snandc->qspi->oob_rw) > >> + oob_buf =3D op->data.buf.in; =20 ... > >> +static int qcom_spi_write_page_cache(struct qcom_nand_controller *sna= ndc, > >> + const struct spi_mem_op *op) > >> +{ > >> + struct qpic_snand_op s_op =3D {}; > >> + u32 cmd; > >> + > >> + cmd =3D qcom_spi_cmd_mapping(snandc, op->cmd.opcode); =20 > >=20 > > I've asked for switch cases to return an error in case they could not > > handle the request. If you don't check the returned values, it > > does not make any sense. =20 > Ok, will fix in next patch. > > =20 > >> + s_op.cmd_reg =3D cmd; > >> + > >> + if (op->cmd.opcode =3D=3D SPINAND_PROGRAM_LOAD) { > >> + if (snandc->qspi->page_rw) > >> + snandc->qspi->data_buf =3D (u8 *)op->data.buf.out; =20 > >=20 > > What you do here does not write anything in a page cache. =20 > No here just updating the buffer , actual write will happen in program= _execute. > This is due to QPIC controller will not take all the instruction one-b= y-one. > once we will set CMD_EXEC =3D 1, then it will execute all the instruct= ion > at once. So accumulating all the instruction and then executing at onc= e in > program_execute. > >=20 > > I also don't understand why you would have to check against the > > SPINAND_PROGRAM_LOAD opcode. =20 > Because the actual write will happen in program_execute. and here > PROGRAM_EXECUTE command will also land, so that added the check. > > =20 > >> + } > >> + > >> + return 0; > >> +} > >> + > >> +static int qcom_spi_send_cmdaddr(struct qcom_nand_controller *snandc, > >> + const struct spi_mem_op *op) > >> +{ > >> + struct qpic_snand_op s_op =3D {}; > >> + u32 cmd; > >> + int ret, opcode; > >> + > >> + cmd =3D qcom_spi_cmd_mapping(snandc, op->cmd.opcode); > >> + > >> + s_op.cmd_reg =3D cmd; > >> + s_op.addr1_reg =3D op->addr.val; > >> + s_op.addr2_reg =3D 0; > >> + > >> + opcode =3D op->cmd.opcode; > >> + > >> + switch (opcode) { > >> + case SPINAND_WRITE_EN: > >> + return 0; > >> + case SPINAND_PROGRAM_EXECUTE: > >> + s_op.addr1_reg =3D op->addr.val << 16; > >> + s_op.addr2_reg =3D op->addr.val >> 16 & 0xff; > >> + snandc->qspi->addr1 =3D s_op.addr1_reg; > >> + snandc->qspi->addr2 =3D s_op.addr2_reg; > >> + snandc->qspi->cmd =3D cmd; > >> + return qcom_spi_program_execute(snandc, op); > >> + case SPINAND_READ: > >> + s_op.addr1_reg =3D (op->addr.val << 16); > >> + s_op.addr2_reg =3D op->addr.val >> 16 & 0xff; > >> + snandc->qspi->addr1 =3D s_op.addr1_reg; > >> + snandc->qspi->addr2 =3D s_op.addr2_reg; > >> + snandc->qspi->cmd =3D cmd; > >> + return 0; > >> + case SPINAND_ERASE: > >> + s_op.addr2_reg =3D (op->addr.val >> 16) & 0xffff; > >> + s_op.addr1_reg =3D op->addr.val; > >> + snandc->qspi->addr1 =3D (s_op.addr1_reg << 16); > >> + snandc->qspi->addr2 =3D s_op.addr2_reg; > >> + snandc->qspi->cmd =3D cmd; > >> + qcom_spi_block_erase(snandc); > >> + return 0; > >> + default: > >> + break; > >> + } > >> + > >> + snandc->buf_count =3D 0; > >> + snandc->buf_start =3D 0; > >> + qcom_clear_read_regs(snandc); > >> + qcom_clear_bam_transaction(snandc); > >> + > >> + snandc->regs->cmd =3D s_op.cmd_reg; > >> + snandc->regs->exec =3D 1; > >> + snandc->regs->addr0 =3D s_op.addr1_reg; > >> + snandc->regs->addr1 =3D s_op.addr2_reg; > >> + > >> + qcom_write_reg_dma(snandc, &snandc->regs->cmd, NAND_FLASH_CMD, 3, NA= ND_BAM_NEXT_SGL); > >> + qcom_write_reg_dma(snandc, &snandc->regs->exec, NAND_EXEC_CMD, 1, NA= ND_BAM_NEXT_SGL); > >> + > >> + ret =3D qcom_submit_descs(snandc); And you really don't want to check the validity of the opcode with what you support before submitting the descriptors? > >> + if (ret) > >> + dev_err(snandc->dev, "failure in sbumitting cmd descriptor\n"); =20 > >=20 > > typo =20 > Ok , will fix in next patch. > > =20 > >> + > >> + return ret; > >> +} > >> + > >> +static int qcom_spi_io_op(struct qcom_nand_controller *snandc, const = struct spi_mem_op *op) > >> +{ > >> + int ret, val, opcode; > >> + bool copy =3D false, copy_ftr =3D false; > >> + > >> + ret =3D qcom_spi_send_cmdaddr(snandc, op); > >> + if (ret) > >> + return ret; > >> + > >> + snandc->buf_count =3D 0; > >> + snandc->buf_start =3D 0; > >> + qcom_clear_read_regs(snandc); > >> + qcom_clear_bam_transaction(snandc); > >> + opcode =3D op->cmd.opcode; > >> + > >> + switch (opcode) { > >> + case SPINAND_READID: > >> + snandc->buf_count =3D 4; > >> + qcom_read_reg_dma(snandc, NAND_READ_ID, 1, NAND_BAM_NEXT_SGL); > >> + copy =3D true; > >> + break; > >> + case SPINAND_GET_FEATURE: > >> + snandc->buf_count =3D 4; > >> + qcom_read_reg_dma(snandc, NAND_FLASH_FEATURES, 1, NAND_BAM_NEXT_SGL= ); > >> + copy_ftr =3D true; > >> + break; > >> + case SPINAND_SET_FEATURE: > >> + snandc->regs->flash_feature =3D *(u32 *)op->data.buf.out; > >> + qcom_write_reg_dma(snandc, &snandc->regs->flash_feature, > >> + NAND_FLASH_FEATURES, 1, NAND_BAM_NEXT_SGL); > >> + break; > >> + case SPINAND_RESET: > >> + return 0; > >> + case SPINAND_PROGRAM_EXECUTE: > >> + return 0; > >> + case SPINAND_WRITE_EN: > >> + return 0; > >> + case SPINAND_ERASE: > >> + return 0; > >> + case SPINAND_READ: > >> + return 0; =20 > >=20 > > You can stack the cases =20 > Ok > > =20 > >> + default: > >> + return -EOPNOTSUPP; > >> + } > >> + > >> + ret =3D qcom_submit_descs(snandc); > >> + if (ret) > >> + dev_err(snandc->dev, "failure in submitting descriptor for:%d\n", o= pcode); > >> + > >> + if (copy) { > >> + qcom_nandc_dev_to_mem(snandc, true); > >> + memcpy(op->data.buf.in, snandc->reg_read_buf, snandc->buf_count); > >> + } > >> + > >> + if (copy_ftr) { > >> + qcom_nandc_dev_to_mem(snandc, true); > >> + val =3D le32_to_cpu(*(__le32 *)snandc->reg_read_buf); > >> + val >>=3D 8; > >> + memcpy(op->data.buf.in, &val, snandc->buf_count); > >> + } > >> + > >> + return ret; > >> +} Thanks, Miqu=C3=A8l 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 Received: from bombadil.infradead.org (bombadil.infradead.org [198.137.202.133]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.lore.kernel.org (Postfix) with ESMTPS id 34F9DC25B77 for ; Wed, 22 May 2024 12:33:38 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=bombadil.20210309; h=Sender: Content-Transfer-Encoding:Content-Type:List-Subscribe:List-Help:List-Post: List-Archive:List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To: Message-ID:Subject:Cc:To:From:Date:Reply-To:Content-ID:Content-Description: Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID: List-Owner; bh=Q6CWaJQ7q0ljb5R+lFigTSv/oAd9ZV50g5/Nu1FUskw=; b=nuy19dg3Y+tCAv R1PofdT74lSf2iYtc1yq62ENz9xpZyHFRg9kI2bmSmcDGMEUrJLjBKoIziR2oaYWFilO9kkw+zYFd Z3FXk8WrGacEKcAah6EXIUSgiVJgSqbYQmVF0G3YFqJGTDfPQUQTWcheOaavMYOZcU5Q00uZdi2fu xCGtiKv1IGt7tD7eGeJiFMhGSKHBmgndQxofCF4497cunWAleRw4zVnx0MG6ZKPVxLHpip5p+KmI4 rhUrGqLz2sI+VgSbm4nNMlytGtMd+ULNu3zNHxAv5+dls2j2cfBr8HJYoprMe1SEw4Jnkke1gTxla Xyx0ryv/98fZushPLIwQ==; Received: from localhost ([::1] helo=bombadil.infradead.org) by bombadil.infradead.org with esmtp (Exim 4.97.1 #2 (Red Hat Linux)) id 1s9l9t-00000002w0H-0UNg; Wed, 22 May 2024 12:33:29 +0000 Received: from relay8-d.mail.gandi.net ([217.70.183.201]) by bombadil.infradead.org with esmtps (Exim 4.97.1 #2 (Red Hat Linux)) id 1s9l9n-00000002vxd-3Ljz for linux-mtd@lists.infradead.org; Wed, 22 May 2024 12:33:26 +0000 Received: by mail.gandi.net (Postfix) with ESMTPSA id 71DC41BF213; Wed, 22 May 2024 12:33:18 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=bootlin.com; s=gm1; t=1716381200; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=D4J4CYGBoBW9h9ZVxR2P3e6r3PhKjkKgpn0sAzWc+hM=; b=PQN0sewa7o74X7XHG9jJNLXCGqTq6dvbQnVsbAjK2VH9LBu8We3jOqSOl4lugWwnQ4EvZX 7hfztpgkGJWuZhZM3LaH5cH+ajxvuom8/OtTzGK6HywyloiICj9JC3nveLDkIhNottyhL5 Ot8dDhcA6u6nYPBuTGxv5AYKsKXOve/y5EmRIyXopeFGMixOaT8wGnvlWcbue0aDrB4X2I RviL4GzHh0Cd68a9dw+a9HMtVVG6HlBGRQvXFjYlWlOo7jv/sSNjbov8Gc+eYjOOyF6iRt 54asP+RYiy/do2bPNZccGSMg1ERyGu+Jh58+lTyPtn1hwmmKKi/DfqIeGuJwMw== Date: Wed, 22 May 2024 14:33:17 +0200 From: Miquel Raynal To: Md Sadre Alam Cc: , , , , , , , , , , , , , , , Subject: Re: [PATCH v6 6/8] spi: spi-qpic: add driver for QCOM SPI NAND flash Interface Message-ID: <20240522143317.07f78601@xps-13> In-Reply-To: <5b96e24a-edcd-df85-9e70-332a6059ee73@quicinc.com> References: <20240521105532.1537845-1-quic_mdalam@quicinc.com> <20240521105532.1537845-7-quic_mdalam@quicinc.com> <20240521152410.7cff71ab@xps-13> <5b96e24a-edcd-df85-9e70-332a6059ee73@quicinc.com> Organization: Bootlin X-Mailer: Claws Mail 4.1.1 (GTK 3.24.38; x86_64-pc-linux-gnu) MIME-Version: 1.0 X-GND-Sasl: miquel.raynal@bootlin.com X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20240522_053324_316932_21FF0EA9 X-CRM114-Status: GOOD ( 44.93 ) X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Sender: "linux-mtd" Errors-To: linux-mtd-bounces+linux-mtd=archiver.kernel.org@lists.infradead.org SGksCgo+ID4+ICtzdGF0aWMgaW50IHFjb21fc3BpX29vYmxheW91dF9lY2Moc3RydWN0IG10ZF9p bmZvICptdGQsIGludCBzZWN0aW9uLAo+ID4+ICsJCQkJICBzdHJ1Y3QgbXRkX29vYl9yZWdpb24g Km9vYnJlZ2lvbikKPiA+PiArewo+ID4+ICsJc3RydWN0IG5hbmRfZGV2aWNlICpuYW5kID0gbXRk X3RvX25hbmRkZXYobXRkKTsKPiA+PiArCXN0cnVjdCBxY29tX25hbmRfY29udHJvbGxlciAqc25h bmRjID0gbmFuZF90b19xY29tX3NuYW5kKG5hbmQpOwo+ID4+ICsJc3RydWN0IHFwaWNfZWNjICpx ZWNjID0gc25hbmRjLT5xc3BpLT5lY2M7Cj4gPj4gKwo+ID4+ICsJaWYgKHNlY3Rpb24gPiAxKQo+ ID4+ICsJCXJldHVybiAtRVJBTkdFOwo+ID4+ICsKPiA+PiArCWlmICghc2VjdGlvbikgewo+ID4+ ICsJCW9vYnJlZ2lvbi0+bGVuZ3RoID0gKHFlY2MtPmJ5dGVzICogKHFlY2MtPnN0ZXBzIC0gMSkp ICsgcWVjYy0+YmJtX3NpemU7Cj4gPj4gKwkJb29icmVnaW9uLT5vZmZzZXQgPSAwOyAgCj4gPiAK PiA+IE5vLCBvZmZzZXQgMCBpcyBmb3IgdGhlIEJCTS4gVGhpcyBpcyB3cm9uZy4KPiA+IFRoZSB3 aG9sZSBvb2IgbGF5b3V0IGxvb2tzIHJlYWxseSByZWFsbHkgd3JvbmcuCj4gPiAKPiA+IEVDQyBi eXRlcyBhcmUgd2hlcmUgdGhlIEVDQyBlbmdpbmUgcHV0cyBpdHMgYnl0ZXMgaW4gdGhlIE9PQiBh cmVhLgo+ID4gRnJlZSBieXRlcyBzdGFydCBhZnRlciB0aGUgQkJNIGFuZCBmaWxsIHRoZSBnYXBz IHVudGlsIHRoZSBlbmQgb2YgdGhlCj4gPiBhcmVhLCBleGNlcHQgd2hlcmUgdGhlcmUgYXJlIEVD QyBieXRlcy4gIAo+ICAgUVBJQyBOQU5EIGNvbnRyb2xsZXIgaGF2aW5nIGl0cyBvd24gcGFnZSBs YXlvdXQgd2l0aCBlY2MgYW5kIHdpdGhvdXQgZWNjLgo+ICAgVGhlIHNhbWUgbGF5b3V0IHdlIGFy ZSB1c2luZyBpbiByYXcgbmFuZCBkcml2ZXIgYXMgd2VsbCwgc28gaSB1c2VkIHRoZQo+ICAgc2Ft ZSBoZXJlLiBUaGUgYmVsb3cgaW5mbyBpcyBhbHJlYWR5IHRoZXJlIGluIHFjb20gcmF3IG5hbmQg ZHJpdmVyIGZpbGUKPiAgIGluIHBhZ2UgbGF5b3V0IGluZm8uCj4gCj4gICBRUElDIE5BTkQgY29u dHJvbGxlciBsYXlvdXQgYXMgYmVsb3c6Cj4gCj4gICAgTGF5b3V0IHdpdGggRUNDIGVuYWJsZWQ6 Cj4gCj4gICAgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgIHwtLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS18Cj4gICAgICB8ICAgICAgICAgICB4eC4uLi4uLi55eXwgIHwgICAgICAg ICAgICAgKioqKioqKioqeHguLi4uLi4ueXl8Cj4gICAgICB8ICAgIERBVEEgICB4eC4uRUNDLi55 eXwgIHwgICAgREFUQSAgICAgKipTUEFSRSoqeHguLkVDQy4ueXl8Cj4gICAgICB8ICAgKDUxNikg ICB4eC4uLi4uLi55eXwgIHwgICg1MTYtbio0KSAgKioobio0KSoqeHguLi4uLi4ueXl8Cj4gICAg ICB8ICAgICAgICAgICB4eC4uLi4uLi55eXwgIHwgICAgICAgICAgICAgKioqKioqKioqeHguLi4u Li4ueXl8Cj4gICAgICB8LS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgIHwtLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS18Cj4gICAgICAgY29kZXdvcmQgMSwyLi5uLTEgICAgICAgICAgICAg ICAgICBjb2Rld29yZCBuCj4gICAgICA8LS0tKDUyOC81MzIgQnl0ZXMpLS0+ICAgIDwtLS0tLS0t KDUyOC81MzIgQnl0ZXMpLS0tLS0tLS0tPgo+IAo+ICAgICAgbiA9IE51bWJlciBvZiBjb2Rld29y ZHMgaW4gdGhlIHBhZ2UKPiAgICAgIC4gPSBFQ0MgYnl0ZXMKPiAgICAgICogPSBTcGFyZS9mcmVl IGJ5dGVzCj4gICAgICB4ID0gVW51c2VkIGJ5dGUocykKPiAgICAgIHkgPSBSZXNlcnZlZCBieXRl KHMpCj4gCj4gICAgICAySyBwYWdlOiBuID0gNCwgc3BhcmUgPSAxNiBieXRlcwo+ICAgICAgNEsg cGFnZTogbiA9IDgsIHNwYXJlID0gMzIgYnl0ZXMKPiAgICAgIDhLIHBhZ2U6IG4gPSAxNiwgc3Bh cmUgPSA2NCBieXRlcwo+IAo+ICAgICAgdGhlIHFjb20gbmFuZCBjb250cm9sbGVyIG9wZXJhdGVz IGF0IGEgc3ViIHBhZ2UvY29kZXdvcmQgbGV2ZWwuIGVhY2gKPiAgICAgIGNvZGV3b3JkIGlzIDUy OCBhbmQgNTMyIGJ5dGVzIGZvciA0IGJpdCBhbmQgOCBiaXQgRUNDIG1vZGVzIHJlc3BlY3RpdmVs eS4KPiAgICAgIHRoZSBudW1iZXIgb2YgRUNDIGJ5dGVzIHZhcnkgYmFzZWQgb24gdGhlIEVDQyBz dHJlbmd0aCBhbmQgdGhlIGJ1cyB3aWR0aC4KPiAKPiAgICAgIHRoZSBmaXJzdCBuIC0gMSBjb2Rl d29yZHMgY29udGFpbnMgNTE2IGJ5dGVzIG9mIHVzZXIgZGF0YSwgdGhlIHJlbWFpbmluZwo+ICAg ICAgMTIvMTYgYnl0ZXMgY29uc2lzdCBvZiBFQ0MgYW5kIHJlc2VydmVkIGRhdGEuIFRoZSBudGgg Y29kZXdvcmQgY29udGFpbnMKPiAgICAgIGJvdGggdXNlciBkYXRhIGFuZCBzcGFyZShvb2JhdmFp bCkgYnl0ZXMgdGhhdCBzdW0gdXAgdG8gNTE2IGJ5dGVzLgo+IAo+ICAgICAgV2hlbiB3ZSBhY2Nl c3MgYSBwYWdlIHdpdGggRUNDIGVuYWJsZWQsIHRoZSByZXNlcnZlZCBieXRlcyhzKSBhcmUgbm90 Cj4gICAgICBhY2Nlc3NpYmxlIGF0IGFsbC4gV2hlbiByZWFkaW5nLCB3ZSBmaWxsIHVwIHRoZXNl IHVucmVhZGFibGUgcG9zaXRpb25zCj4gICAgICB3aXRoIDB4ZmZzLiBXaGVuIHdyaXRpbmcsIHRo ZSBjb250cm9sbGVyIHNraXBzIHdyaXRpbmcgdGhlIGluYWNjZXNzaWJsZQo+ICAgICAgYnl0ZXMu Cj4gCj4gICAgICBMYXlvdXQgd2l0aCBFQ0MgZGlzYWJsZWQ6Cj4gCj4gICAgICB8LS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tfCAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0t LS0tLS0tLXwKPiAgICAgIHwgICAgICAgICB5eSAgICAgICAgICB4eC4uLi4uLi58ICB8ICAgICAg ICAgYmIgICAgICAgICAgKioqKioqKioqeHguLi4uLi4ufAo+ICAgICAgfCAgREFUQTEgIHl5ICBE QVRBMiAgIHh4Li5FQ0MuLnwgIHwgIERBVEExICBiYiAgREFUQTIgICAqKlNQQVJFKip4eC4uRUND Li58Cj4gICAgICB8IChzaXplMSkgeXkgKHNpemUyKSAgeHguLi4uLi4ufCAgfCAoc2l6ZTEpIGJi IChzaXplMikgICoqKG4qNCkqKnh4Li4uLi4uLnwKPiAgICAgIHwgICAgICAgICB5eSAgICAgICAg ICB4eC4uLi4uLi58ICB8ICAgICAgICAgYmIgICAgICAgICAgKioqKioqKioqeHguLi4uLi4ufAo+ ICAgICAgfC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLXwgIHwtLS0tLS0tLS0tLS0tLS0t LS0tLS0tLS0tLS0tLS0tLS0tLS0tLS18Cj4gICAgICAgICAgIGNvZGV3b3JkIDEsMi4ubi0xICAg ICAgICAgICAgICAgICAgICAgICAgY29kZXdvcmQgbgo+ICAgICAgPC0tLS0tLS0oNTI4LzUzMiBC eXRlcyktLS0tLS0+ICAgIDwtLS0tLS0tLS0tLSg1MjgvNTMyIEJ5dGVzKS0tLS0tLS0tLS0tPgo+ IAo+ICAgICAgbiA9IE51bWJlciBvZiBjb2Rld29yZHMgaW4gdGhlIHBhZ2UKPiAgICAgIC4gPSBF Q0MgYnl0ZXMKPiAgICAgICogPSBTcGFyZS9mcmVlIGJ5dGVzCj4gICAgICB4ID0gVW51c2VkIGJ5 dGUocykKPiAgICAgIHkgPSBEdW1teSBCYWQgQm9jayBieXRlKHMpCj4gICAgICBiID0gUmVhbCBC YWQgQmxvY2sgYnl0ZShzKQo+ICAgICAgc2l6ZTEvc2l6ZTIgPSBmdW5jdGlvbiBvZiBjb2Rld29y ZCBzaXplIGFuZCAnbicKPiAKPiAgICAgIHdoZW4gdGhlIEVDQyBibG9jayBpcyBkaXNhYmxlZCwg b25lIHJlc2VydmVkIGJ5dGUgKG9yIHR3byBmb3IgMTYgYml0IGJ1cwo+ICAgICAgd2lkdGgpIGlz IG5vdyBhY2Nlc3NpYmxlLiBGb3IgdGhlIGZpcnN0IG4gLSAxIGNvZGV3b3JkcywgdGhlc2UgYXJl IGR1bW15IEJhZAo+ICAgICAgQmxvY2sgTWFya2Vycy4gSW4gdGhlIGxhc3QgY29kZXdvcmQsIHRo aXMgcG9zaXRpb24gY29udGFpbnMgdGhlIHJlYWwgQkJNCj4gCj4gICAgICBJbiBvcmRlciB0byBo YXZlIGEgY29uc2lzdGVudCBsYXlvdXQgYmV0d2VlbiBSQVcgYW5kIEVDQyBtb2Rlcywgd2UgYXNz dW1lCj4gICAgICB0aGUgZm9sbG93aW5nIE9PQiBsYXlvdXQgYXJyYW5nZW1lbnQ6Cj4gCj4gICAg ICB8LS0tLS0tLS0tLS18ICB8LS0tLS0tLS0tLS0tLS0tLS0tLS18Cj4gICAgICB8eXl4eC4uLi4u Li58ICB8YmIqKioqKioqKip4eC4uLi4uLi58Cj4gICAgICB8eXl4eC4uRUNDLi58ICB8YmIqRlJF RU9PQip4eC4uRUNDLi58Cj4gICAgICB8eXl4eC4uLi4uLi58ICB8YmIqKioqKioqKip4eC4uLi4u Li58Cj4gICAgICB8eXl4eC4uLi4uLi58ICB8YmIqKioqKioqKip4eC4uLi4uLi58Cj4gICAgICB8 LS0tLS0tLS0tLS18ICB8LS0tLS0tLS0tLS0tLS0tLS0tLS18Cj4gICAgICBmaXJzdCBuIC0gMSAg ICAgICBudGggT09CIHJlZ2lvbgo+ICAgICAgT09CIHJlZ2lvbnMKPiAKPiAgICAgIG4gPSBOdW1i ZXIgb2YgY29kZXdvcmRzIGluIHRoZSBwYWdlCj4gICAgICAuID0gRUNDIGJ5dGVzCj4gICAgICAq ID0gRlJFRSBPT0IgYnl0ZXMKPiAgICAgIHkgPSBEdW1teSBiYWQgYmxvY2sgYnl0ZShzKSAoaW5h Y2Nlc3NpYmxlIHdoZW4gRUNDIGVuYWJsZWQpCj4gICAgICB4ID0gVW51c2VkIGJ5dGUocykKPiAg ICAgIGIgPSBSZWFsIGJhZCBibG9jayBieXRlKHMpIChpbmFjY2Vzc2libGUgd2hlbiBFQ0MgZW5h YmxlZCkKPiAKPiAgICAgIFRoaXMgbGF5b3V0IGlzIHJlYWQgYXMgaXMgd2hlbiBFQ0MgaXMgZGlz YWJsZWQuIFdoZW4gRUNDIGlzIGVuYWJsZWQsIHRoZQo+ICAgICAgaW5hY2Nlc3NpYmxlIEJhZCBC bG9jayBieXRlKHMpIGFyZSBpZ25vcmVkIHdoZW4gd2Ugd3JpdGUgdG8gYSBwYWdlL29vYiwKPiAg ICAgIGFuZCBhc3N1bWVkIGFzIDB4ZmZzIHdoZW4gd2UgcmVhZCBhIHBhZ2Uvb29iLiBUaGUgRUND LCB1bnVzZWQgYW5kCj4gICAgICBkdW1teS9yZWFsIGJhZCBibG9jayBieXRlcyBhcmUgZ3JvdXBl ZCBhcyBlY2MgYnl0ZXMgKGkuZSwgZWNjLT5ieXRlcyBpcwo+ICAgICAgdGhlIHN1bSBvZiB0aGUg dGhyZWUpLgoKVGhhbmtzIGZvciB0aGUgZGV0YWlsZWQgZXhwbGFuYXRpb24gKHdoaWNoIHdvdWxk IGJlbmVmaXQgZnJvbSBiZWluZwphZGRlZCBzb21ld2hlcmUgaW4gYSBjb21tZW50LCBtYXliZSBh dCB0aGUgdG9wIG9mIHRoZSBmaWxlKS4KClVuZm9ydHVuYXRlbHksIHRoZXNlIG9vYmxheW91dCBj YWxsYmFja3MgZG8gd29yayBvbiBhIGZsYXQgPGRhdGE+PG9vYj4KbGF5b3V0LCBub3Qgb24gdGhl IGhhcmR3YXJlIEVDQyBlbmdpbmUgbGF5b3V0LiBTbyB3aGF0ZXZlciB0aGUgcmVhbApwaHlzaWNh bCBwb3NpdGlvbiBvZiB0aGUgYmFkIGJsb2NrIG1hcmtlciB3aXRoaW4gdGhlIE5BTkQgYXJyYXks IHRoZXNlCm1hcmtlcnMgd2lsbCBhbHdheXMgYmUgYXQgb2Zmc2V0IDAgYW5kIDEgaW4gdGhlIE9P QiBmaW5hbCBidWZmZXIuCgpTYW1lIGFwcGxpZXMgdG8gdGhlIHNwYXJlIGFuZCBFQ0MgYnl0ZXMu IFRoZXNlIGxheW91dHMgYXJlIHRvdGFsbHkKd3JvbmcgYW5kIG11c3QgYmUgZml4ZWQuIElmIHRo ZSBsYXlvdXRzIGFyZSB0aGUgc2FtZSBpbiBib3RoIHJhdy9zcGkKY2FzZXMsIG1heWJlIHRoZXkg c2hvdWxkIGJlIHBhcnQgb2YgdGhlIGNvbW1vbiBmaWxlPwoKPiA+PiArCX0gZWxzZSB7Cj4gPj4g KwkJb29icmVnaW9uLT5sZW5ndGggPSBxZWNjLT5lY2NfYnl0ZXNfaHcgKyBxZWNjLT5zcGFyZV9i eXRlczsKPiA+PiArCQlvb2JyZWdpb24tPm9mZnNldCA9IG10ZC0+b29ic2l6ZSAtIG9vYnJlZ2lv bi0+bGVuZ3RoOwo+ID4+ICsJfQo+ID4+ICsKPiA+PiArCXJldHVybiAwOwo+ID4+ICt9Cj4gPj4g Kwo+ID4+ICtzdGF0aWMgaW50IHFjb21fc3BpX29vYmxheW91dF9mcmVlKHN0cnVjdCBtdGRfaW5m byAqbXRkLCBpbnQgc2VjdGlvbiwKPiA+PiArCQkJCSAgIHN0cnVjdCBtdGRfb29iX3JlZ2lvbiAq b29icmVnaW9uKQo+ID4+ICt7Cj4gPj4gKwlzdHJ1Y3QgbmFuZF9kZXZpY2UgKm5hbmQgPSBtdGRf dG9fbmFuZGRldihtdGQpOwo+ID4+ICsJc3RydWN0IHFjb21fbmFuZF9jb250cm9sbGVyICpzbmFu ZGMgPSBuYW5kX3RvX3Fjb21fc25hbmQobmFuZCk7Cj4gPj4gKwlzdHJ1Y3QgcXBpY19lY2MgKnFl Y2MgPSBzbmFuZGMtPnFzcGktPmVjYzsKPiA+PiArCj4gPj4gKwlpZiAoc2VjdGlvbikKPiA+PiAr CQlyZXR1cm4gLUVSQU5HRTsKPiA+PiArCj4gPj4gKwlvb2JyZWdpb24tPmxlbmd0aCA9IHFlY2Mt PnN0ZXBzICogNDsKPiA+PiArCW9vYnJlZ2lvbi0+b2Zmc2V0ID0gKChxZWNjLT5zdGVwcyAtIDEp ICogcWVjYy0+Ynl0ZXMpICsgcWVjYy0+YmJtX3NpemU7Cj4gPj4gKwo+ID4+ICsJcmV0dXJuIDA7 Cj4gPj4gK30KPiA+PiArICAKPiA+IAo+ID4gLi4uCj4gPiAgIAo+ID4+ICtzdGF0aWMgaW50IHFj b21fc3BpX2VjY19wcmVwYXJlX2lvX3JlcV9waXBlbGluZWQoc3RydWN0IG5hbmRfZGV2aWNlICpu YW5kLAo+ID4+ICsJCQkJCQkgc3RydWN0IG5hbmRfcGFnZV9pb19yZXEgKnJlcSkKPiA+PiArewo+ ID4+ICsJc3RydWN0IHFjb21fbmFuZF9jb250cm9sbGVyICpzbmFuZGMgPSBuYW5kX3RvX3Fjb21f c25hbmQobmFuZCk7Cj4gPj4gKwlzdHJ1Y3QgcXBpY19lY2MgKmVjY19jZmcgPSBuYW5kX3RvX2Vj Y19jdHgobmFuZCk7Cj4gPj4gKwlzdHJ1Y3QgbXRkX2luZm8gKm10ZCA9IG5hbmRkZXZfdG9fbXRk KG5hbmQpOwo+ID4+ICsKPiA+PiArCXNuYW5kYy0+cXNwaS0+ZWNjID0gZWNjX2NmZzsKPiA+PiAr CXNuYW5kYy0+cXNwaS0+cGFnZXNpemUgPSBtdGQtPndyaXRlc2l6ZTsKPiA+PiArCXNuYW5kYy0+ cXNwaS0+cmF3X3J3ID0gZmFsc2U7Cj4gPj4gKwlzbmFuZGMtPnFzcGktPm9vYl9ydyA9IGZhbHNl Owo+ID4+ICsJc25hbmRjLT5xc3BpLT5wYWdlX3J3ID0gZmFsc2U7Cj4gPj4gKwo+ID4+ICsJaWYg KHJlcS0+ZGF0YWxlbikKPiA+PiArCQlzbmFuZGMtPnFzcGktPnBhZ2VfcncgPSB0cnVlOwo+ID4+ ICsKPiA+PiArCWlmIChyZXEtPm9vYmxlbikgewo+ID4+ICsJCXNuYW5kYy0+cXNwaS0+b29iX3J3 ID0gdHJ1ZTsKPiA+PiArCQlpZiAocmVxLT5vb2JsZW4gPT0gQkFEX0JMT0NLX01BUktFUl9TSVpF KQo+ID4+ICsJCQlzbmFuZGMtPnFzcGktPnJlYWRfbGFzdF9jdyA9IHRydWU7ICAKPiA+IAo+ID4g Pz8/ICAKPiAgICBBcyBwZXIgUVBJQyBjb250cm9sbGVyIGxheW91dCAsIHRoZSBhY3R1YWwgYmFi ZCBibG9jayBtYXJrZXIgd2lsbAo+ICAgIGJlIHByZXNlbnQgaW4gbGFzdCBjb2RlIHdvcmQuIFRo YXRzIHdoeSBpIGhhdmUgYWRkZWQgdGhpcyBjaGVjay4KPiAgICB0byByZWFkIG9ubHkgbGFzdCBj b2Rld29yZCBmb3IgYmFkIGJsb2NrIGNoZWNrLgoKWW91IG5lZWQgdG8gY29tcGx5IHdpdGggdGhl IHJlcXVlc3QuIElmIG9vYmxlbiBpcyAhPSAwLCB5b3UgbmVlZCB0bwpyZWFkIHRoZSBjb2Rld29y ZChzKSB3aGVyZSB0aGUgb29iIGlzLiBQbGVhc2UgZG9uJ3QgdHJ5IHRvIGJlIHNtYXJ0ZXIKdGhh biB0aGF0LiBDaGVja2luZyB0aGUgX3ZhbHVlXyBvZiBvb2JsZW4gaXMgYW4gb3B0aW1pemF0aW9u IEkgZG9uJ3QKdGhpbmsgaXMgd29ydGguCgo+ID4gICAKPiA+PiArCX0KPiA+PiArCj4gPj4gKwlp ZiAocmVxLT5tb2RlID09IE1URF9PUFNfUkFXKQo+ID4+ICsJCXNuYW5kYy0+cXNwaS0+cmF3X3J3 ID0gdHJ1ZTsKPiA+PiArCj4gPj4gKwlyZXR1cm4gMDsKPiA+PiArfQo+ID4+ICsKPiA+PiArc3Rh dGljIGludCBxY29tX3NwaV9lY2NfZmluaXNoX2lvX3JlcV9waXBlbGluZWQoc3RydWN0IG5hbmRf ZGV2aWNlICpuYW5kLAo+ID4+ICsJCQkJCQlzdHJ1Y3QgbmFuZF9wYWdlX2lvX3JlcSAqcmVxKQo+ ID4+ICt7Cj4gPj4gKwlzdHJ1Y3QgcWNvbV9uYW5kX2NvbnRyb2xsZXIgKnNuYW5kYyA9IG5hbmRf dG9fcWNvbV9zbmFuZChuYW5kKTsKPiA+PiArCXN0cnVjdCBtdGRfaW5mbyAqbXRkID0gbmFuZGRl dl90b19tdGQobmFuZCk7Cj4gPj4gKwo+ID4+ICsJaWYgKHJlcS0+bW9kZSA9PSBNVERfT1BTX1JB VyB8fCByZXEtPnR5cGUgIT0gTkFORF9QQUdFX1JFQUQpCj4gPj4gKwkJcmV0dXJuIDA7Cj4gPj4g Kwo+ID4+ICsJaWYgKHNuYW5kYy0+cXNwaS0+ZWNjX3N0YXRzLmZhaWxlZCkKPiA+PiArCQltdGQt PmVjY19zdGF0cy5mYWlsZWQgKz0gc25hbmRjLT5xc3BpLT5lY2Nfc3RhdHMuZmFpbGVkOwo+ID4+ ICsJbXRkLT5lY2Nfc3RhdHMuY29ycmVjdGVkICs9IHNuYW5kYy0+cXNwaS0+ZWNjX3N0YXRzLmNv cnJlY3RlZDsgIAo+ID4gCj4gPiBTZWVtcyBzdHJhbmdlICAKPiAgICBJbiBmbGFzaCBlcnJvciBj aGVjayBmb3IgZWFjaCBjb2RlIHdvcmQgaSBhbSB1cGRhdGluZyB0aGUgZXJyb3IgdmFsdWUuCj4g ICAgU28gb24gZmluaXNoaW5nIG9uIGlvIGkgYW0gYXNzaWduaW5nIHRoYXQgZXJyb3IgdG8gbXRk IHZhcmlhYmxlcyBzbyB0aGF0Cj4gICAgdXBwZXIgbGF5ZXIgY2hlY2sgZm9yIGVycm9yLgoKWW91 IGRvbid0IGNsZWFyIHRoZSBxc3BpIGVjY19zdGF0cyBzbyB0aGlzIGNhbm5vdCB3b3JrIHByb3Bl cmx5LgoKUGx1cywgSSB3b3VsZCB3ZWxjb21lIGFuIGVsc2Ugc3RhdGVtZW50IGZvciBpbmNyZW1l bnRpbmcgdGhlIGNvcnJlY3RlZApmaWVsZC4KCj4gPiAgIAo+ID4+ICsKPiA+PiArCWlmIChzbmFu ZGMtPnFzcGktPmVjY19zdGF0cy5mYWlsZWQpCj4gPj4gKwkJcmV0dXJuIC1FQkFETVNHOwo+ID4+ ICsJZWxzZQo+ID4+ICsJCXJldHVybiBzbmFuZGMtPnFzcGktPmVjY19zdGF0cy5iaXRmbGlwczsK PiA+PiArfQo+ID4+ICsKPiA+PiArc3RhdGljIHN0cnVjdCBuYW5kX2VjY19lbmdpbmVfb3BzIHFj b21fc3BpX2VjY19lbmdpbmVfb3BzX3BpcGVsaW5lZCA9IHsKPiA+PiArCS5pbml0X2N0eCA9IHFj b21fc3BpX2VjY19pbml0X2N0eF9waXBlbGluZWQsCj4gPj4gKwkuY2xlYW51cF9jdHggPSBxY29t X3NwaV9lY2NfY2xlYW51cF9jdHhfcGlwZWxpbmVkLAo+ID4+ICsJLnByZXBhcmVfaW9fcmVxID0g cWNvbV9zcGlfZWNjX3ByZXBhcmVfaW9fcmVxX3BpcGVsaW5lZCwKPiA+PiArCS5maW5pc2hfaW9f cmVxID0gcWNvbV9zcGlfZWNjX2ZpbmlzaF9pb19yZXFfcGlwZWxpbmVkLAo+ID4+ICt9Owo+ID4+ ICsgIAo+ID4gCj4gPiAuLi4KPiA+ICAgCj4gPj4gK3N0YXRpYyBpbnQgcWNvbV9zcGlfcmVhZF9w YWdlX3JhdyhzdHJ1Y3QgcWNvbV9uYW5kX2NvbnRyb2xsZXIgKnNuYW5kYywKPiA+PiArCQkJCSAg Y29uc3Qgc3RydWN0IHNwaV9tZW1fb3AgKm9wKQo+ID4+ICt7Cj4gPj4gKwlzdHJ1Y3QgcXBpY19l Y2MgKmVjY19jZmcgPSBzbmFuZGMtPnFzcGktPmVjYzsKPiA+PiArCXU4ICpkYXRhX2J1ZiA9IE5V TEwsICpvb2JfYnVmID0gTlVMTDsKPiA+PiArCWludCByZXQsIGN3Owo+ID4+ICsJdTMyIG51bV9j dyA9IHNuYW5kYy0+cXNwaS0+bnVtX2N3Owo+ID4+ICsKPiA+PiArCWlmIChzbmFuZGMtPnFzcGkt PnBhZ2VfcncpICAKPiA+IAo+ID4gSSBkb24ndCBsaWtlIHRoaXMgaW5kaXJlY3Rpb24gdmVyeSBt dWNoLiBDYW4ndCB5b3Ugc2ltcGxpZnkgdGhpcyBhbmQKPiA+IGp1c3QgZm9sbG93IHRoZSBzcGkt bWVtIG9wIGluc3RlYWQgb2YgY29uc3RhbnRseSB0cnlpbmcgdG8gYWRkCj4gPiBhZGRpdGlvbmFs IHN0dWZmPyAgCj4gICAgVGhpcyBpbmRpcmVjdGlvbiBuZWVkZWQgZHVlIHRvIFFQSUMgY29udHJv bGxlciB3aWxsIG5vdCB0YWtlIGFsbCB0aGUgaW5zdHJ1Y3Rpb24KPiAgICBvbmUtYnktb25lICwg b25jZSB3ZSB3aWxsIHNldCBDTURfRVhFQyA9IDEsIHRoZW4gaXQgd2lsbCBleGVjdXRlIGFsbCB0 aGUgaW5zdHJ1Y3Rpb24KPiAgICBhdCBvbmNlLgoKVGhlIHNwaV9tZW1fb3Agc3RydWN0dXJlIGFs cmVhZHkgZGVzY3JpYmVzIHRoZSB3aG9sZSBvcGVyYXRpb24uIFdoeSBkbwp5b3Ugc3BsaXQgdGhl IG9wZXJhdGlvbiBpbiBzdWIgcm91dGluZXMgaWYgeW91IGNhbid0IGFjdHVhbGx5IGRvIHRoYXQ/ Cgo+ID4gCj4gPiBUaGUgaGFyZHdhcmUgaXMgYWxyZWFkeSBxdWl0ZSBjb21wbGV4LCBidXQgaXQg ZmVlbHMgbGlrZSB5b3VyIGFkZGluZwo+ID4geWV0IGFub3RoZXIgcGlsZSBvZiB1bm5lY2Vzc2Fy eSBjb21wbGV4aXR5LiAgCj4gICAgWWVzIGhhcmR3YXJlIGlzIGNvbXBsZXguIGxldCBtZSBjaGVj ayBpZiBpIGNhbiBmdXJ0aGVyIG9wdGltaXplIGFzIHBlciBzcGktbWVtIG9wCj4gICAgYXMgeW91 IHN1Z2dlc3RlZC4KPiA+ICAgCj4gPj4gKwkJZGF0YV9idWYgPSBvcC0+ZGF0YS5idWYuaW47Cj4g Pj4gKwo+ID4+ICsJaWYgKHNuYW5kYy0+cXNwaS0+b29iX3J3KQo+ID4+ICsJCW9vYl9idWYgPSBv cC0+ZGF0YS5idWYuaW47ICAKCi4uLgoKPiA+PiArc3RhdGljIGludCBxY29tX3NwaV93cml0ZV9w YWdlX2NhY2hlKHN0cnVjdCBxY29tX25hbmRfY29udHJvbGxlciAqc25hbmRjLAo+ID4+ICsJCQkJ ICAgICBjb25zdCBzdHJ1Y3Qgc3BpX21lbV9vcCAqb3ApCj4gPj4gK3sKPiA+PiArCXN0cnVjdCBx cGljX3NuYW5kX29wIHNfb3AgPSB7fTsKPiA+PiArCXUzMiBjbWQ7Cj4gPj4gKwo+ID4+ICsJY21k ID0gcWNvbV9zcGlfY21kX21hcHBpbmcoc25hbmRjLCBvcC0+Y21kLm9wY29kZSk7ICAKPiA+IAo+ ID4gSSd2ZSBhc2tlZCBmb3Igc3dpdGNoIGNhc2VzIHRvIHJldHVybiBhbiBlcnJvciBpbiBjYXNl IHRoZXkgY291bGQgbm90Cj4gPiBoYW5kbGUgdGhlIHJlcXVlc3QuIElmIHlvdSBkb24ndCBjaGVj ayB0aGUgcmV0dXJuZWQgdmFsdWVzLCBpdAo+ID4gZG9lcyBub3QgbWFrZSBhbnkgc2Vuc2UuICAK PiAgIE9rLCB3aWxsIGZpeCBpbiBuZXh0IHBhdGNoLgo+ID4gICAKPiA+PiArCXNfb3AuY21kX3Jl ZyA9IGNtZDsKPiA+PiArCj4gPj4gKwlpZiAob3AtPmNtZC5vcGNvZGUgPT0gU1BJTkFORF9QUk9H UkFNX0xPQUQpIHsKPiA+PiArCQlpZiAoc25hbmRjLT5xc3BpLT5wYWdlX3J3KQo+ID4+ICsJCQlz bmFuZGMtPnFzcGktPmRhdGFfYnVmID0gKHU4ICopb3AtPmRhdGEuYnVmLm91dDsgIAo+ID4gCj4g PiBXaGF0IHlvdSBkbyBoZXJlIGRvZXMgbm90IHdyaXRlIGFueXRoaW5nIGluIGEgcGFnZSBjYWNo ZS4gIAo+ICAgIE5vIGhlcmUganVzdCB1cGRhdGluZyB0aGUgYnVmZmVyICwgYWN0dWFsIHdyaXRl IHdpbGwgaGFwcGVuIGluIHByb2dyYW1fZXhlY3V0ZS4KPiAgICBUaGlzIGlzIGR1ZSB0byBRUElD IGNvbnRyb2xsZXIgd2lsbCBub3QgdGFrZSBhbGwgdGhlIGluc3RydWN0aW9uIG9uZS1ieS1vbmUu Cj4gICAgb25jZSB3ZSB3aWxsIHNldCBDTURfRVhFQyA9IDEsIHRoZW4gaXQgd2lsbCBleGVjdXRl IGFsbCB0aGUgaW5zdHJ1Y3Rpb24KPiAgICBhdCBvbmNlLiBTbyBhY2N1bXVsYXRpbmcgYWxsIHRo ZSBpbnN0cnVjdGlvbiBhbmQgdGhlbiBleGVjdXRpbmcgYXQgb25jZSBpbgo+ICAgIHByb2dyYW1f ZXhlY3V0ZS4KPiA+IAo+ID4gSSBhbHNvIGRvbid0IHVuZGVyc3RhbmQgd2h5IHlvdSB3b3VsZCBo YXZlIHRvIGNoZWNrIGFnYWluc3QgdGhlCj4gPiBTUElOQU5EX1BST0dSQU1fTE9BRCBvcGNvZGUu ICAKPiAgICBCZWNhdXNlIHRoZSBhY3R1YWwgd3JpdGUgd2lsbCBoYXBwZW4gaW4gcHJvZ3JhbV9l eGVjdXRlLiBhbmQgaGVyZQo+ICAgIFBST0dSQU1fRVhFQ1VURSBjb21tYW5kIHdpbGwgYWxzbyBs YW5kLCBzbyB0aGF0IGFkZGVkIHRoZSBjaGVjay4KPiA+ICAgCj4gPj4gKwl9Cj4gPj4gKwo+ID4+ ICsJcmV0dXJuIDA7Cj4gPj4gK30KPiA+PiArCj4gPj4gK3N0YXRpYyBpbnQgcWNvbV9zcGlfc2Vu ZF9jbWRhZGRyKHN0cnVjdCBxY29tX25hbmRfY29udHJvbGxlciAqc25hbmRjLAo+ID4+ICsJCQkJ IGNvbnN0IHN0cnVjdCBzcGlfbWVtX29wICpvcCkKPiA+PiArewo+ID4+ICsJc3RydWN0IHFwaWNf c25hbmRfb3Agc19vcCA9IHt9Owo+ID4+ICsJdTMyIGNtZDsKPiA+PiArCWludCByZXQsIG9wY29k ZTsKPiA+PiArCj4gPj4gKwljbWQgPSBxY29tX3NwaV9jbWRfbWFwcGluZyhzbmFuZGMsIG9wLT5j bWQub3Bjb2RlKTsKPiA+PiArCj4gPj4gKwlzX29wLmNtZF9yZWcgPSBjbWQ7Cj4gPj4gKwlzX29w LmFkZHIxX3JlZyA9IG9wLT5hZGRyLnZhbDsKPiA+PiArCXNfb3AuYWRkcjJfcmVnID0gMDsKPiA+ PiArCj4gPj4gKwlvcGNvZGUgPSBvcC0+Y21kLm9wY29kZTsKPiA+PiArCj4gPj4gKwlzd2l0Y2gg KG9wY29kZSkgewo+ID4+ICsJY2FzZSBTUElOQU5EX1dSSVRFX0VOOgo+ID4+ICsJCXJldHVybiAw Owo+ID4+ICsJY2FzZSBTUElOQU5EX1BST0dSQU1fRVhFQ1VURToKPiA+PiArCQlzX29wLmFkZHIx X3JlZyA9IG9wLT5hZGRyLnZhbCA8PCAxNjsKPiA+PiArCQlzX29wLmFkZHIyX3JlZyA9IG9wLT5h ZGRyLnZhbCA+PiAxNiAmIDB4ZmY7Cj4gPj4gKwkJc25hbmRjLT5xc3BpLT5hZGRyMSA9IHNfb3Au YWRkcjFfcmVnOwo+ID4+ICsJCXNuYW5kYy0+cXNwaS0+YWRkcjIgPSBzX29wLmFkZHIyX3JlZzsK PiA+PiArCQlzbmFuZGMtPnFzcGktPmNtZCA9IGNtZDsKPiA+PiArCQlyZXR1cm4gcWNvbV9zcGlf cHJvZ3JhbV9leGVjdXRlKHNuYW5kYywgb3ApOwo+ID4+ICsJY2FzZSBTUElOQU5EX1JFQUQ6Cj4g Pj4gKwkJc19vcC5hZGRyMV9yZWcgPSAob3AtPmFkZHIudmFsIDw8IDE2KTsKPiA+PiArCQlzX29w LmFkZHIyX3JlZyA9IG9wLT5hZGRyLnZhbCA+PiAxNiAmIDB4ZmY7Cj4gPj4gKwkJc25hbmRjLT5x c3BpLT5hZGRyMSA9IHNfb3AuYWRkcjFfcmVnOwo+ID4+ICsJCXNuYW5kYy0+cXNwaS0+YWRkcjIg PSBzX29wLmFkZHIyX3JlZzsKPiA+PiArCQlzbmFuZGMtPnFzcGktPmNtZCA9IGNtZDsKPiA+PiAr CQlyZXR1cm4gMDsKPiA+PiArCWNhc2UgU1BJTkFORF9FUkFTRToKPiA+PiArCQlzX29wLmFkZHIy X3JlZyA9IChvcC0+YWRkci52YWwgPj4gMTYpICYgMHhmZmZmOwo+ID4+ICsJCXNfb3AuYWRkcjFf cmVnID0gb3AtPmFkZHIudmFsOwo+ID4+ICsJCXNuYW5kYy0+cXNwaS0+YWRkcjEgPSAoc19vcC5h ZGRyMV9yZWcgPDwgMTYpOwo+ID4+ICsJCXNuYW5kYy0+cXNwaS0+YWRkcjIgPSBzX29wLmFkZHIy X3JlZzsKPiA+PiArCQlzbmFuZGMtPnFzcGktPmNtZCA9IGNtZDsKPiA+PiArCQlxY29tX3NwaV9i bG9ja19lcmFzZShzbmFuZGMpOwo+ID4+ICsJCXJldHVybiAwOwo+ID4+ICsJZGVmYXVsdDoKPiA+ PiArCQlicmVhazsKPiA+PiArCX0KPiA+PiArCj4gPj4gKwlzbmFuZGMtPmJ1Zl9jb3VudCA9IDA7 Cj4gPj4gKwlzbmFuZGMtPmJ1Zl9zdGFydCA9IDA7Cj4gPj4gKwlxY29tX2NsZWFyX3JlYWRfcmVn cyhzbmFuZGMpOwo+ID4+ICsJcWNvbV9jbGVhcl9iYW1fdHJhbnNhY3Rpb24oc25hbmRjKTsKPiA+ PiArCj4gPj4gKwlzbmFuZGMtPnJlZ3MtPmNtZCA9IHNfb3AuY21kX3JlZzsKPiA+PiArCXNuYW5k Yy0+cmVncy0+ZXhlYyA9IDE7Cj4gPj4gKwlzbmFuZGMtPnJlZ3MtPmFkZHIwID0gc19vcC5hZGRy MV9yZWc7Cj4gPj4gKwlzbmFuZGMtPnJlZ3MtPmFkZHIxID0gc19vcC5hZGRyMl9yZWc7Cj4gPj4g Kwo+ID4+ICsJcWNvbV93cml0ZV9yZWdfZG1hKHNuYW5kYywgJnNuYW5kYy0+cmVncy0+Y21kLCBO QU5EX0ZMQVNIX0NNRCwgMywgTkFORF9CQU1fTkVYVF9TR0wpOwo+ID4+ICsJcWNvbV93cml0ZV9y ZWdfZG1hKHNuYW5kYywgJnNuYW5kYy0+cmVncy0+ZXhlYywgTkFORF9FWEVDX0NNRCwgMSwgTkFO RF9CQU1fTkVYVF9TR0wpOwo+ID4+ICsKPiA+PiArCXJldCA9IHFjb21fc3VibWl0X2Rlc2NzKHNu YW5kYyk7CgpBbmQgeW91IHJlYWxseSBkb24ndCB3YW50IHRvIGNoZWNrIHRoZSB2YWxpZGl0eSBv ZiB0aGUgb3Bjb2RlIHdpdGggd2hhdAp5b3Ugc3VwcG9ydCBiZWZvcmUgc3VibWl0dGluZyB0aGUg ZGVzY3JpcHRvcnM/Cgo+ID4+ICsJaWYgKHJldCkKPiA+PiArCQlkZXZfZXJyKHNuYW5kYy0+ZGV2 LCAiZmFpbHVyZSBpbiBzYnVtaXR0aW5nIGNtZCBkZXNjcmlwdG9yXG4iKTsgIAo+ID4gCj4gPiB0 eXBvICAKPiAgIE9rICwgd2lsbCBmaXggaW4gbmV4dCBwYXRjaC4KPiA+ICAgCj4gPj4gKwo+ID4+ ICsJcmV0dXJuIHJldDsKPiA+PiArfQo+ID4+ICsKPiA+PiArc3RhdGljIGludCBxY29tX3NwaV9p b19vcChzdHJ1Y3QgcWNvbV9uYW5kX2NvbnRyb2xsZXIgKnNuYW5kYywgY29uc3Qgc3RydWN0IHNw aV9tZW1fb3AgKm9wKQo+ID4+ICt7Cj4gPj4gKwlpbnQgcmV0LCB2YWwsIG9wY29kZTsKPiA+PiAr CWJvb2wgY29weSA9IGZhbHNlLCBjb3B5X2Z0ciA9IGZhbHNlOwo+ID4+ICsKPiA+PiArCXJldCA9 IHFjb21fc3BpX3NlbmRfY21kYWRkcihzbmFuZGMsIG9wKTsKPiA+PiArCWlmIChyZXQpCj4gPj4g KwkJcmV0dXJuIHJldDsKPiA+PiArCj4gPj4gKwlzbmFuZGMtPmJ1Zl9jb3VudCA9IDA7Cj4gPj4g KwlzbmFuZGMtPmJ1Zl9zdGFydCA9IDA7Cj4gPj4gKwlxY29tX2NsZWFyX3JlYWRfcmVncyhzbmFu ZGMpOwo+ID4+ICsJcWNvbV9jbGVhcl9iYW1fdHJhbnNhY3Rpb24oc25hbmRjKTsKPiA+PiArCW9w Y29kZSA9IG9wLT5jbWQub3Bjb2RlOwo+ID4+ICsKPiA+PiArCXN3aXRjaCAob3Bjb2RlKSB7Cj4g Pj4gKwljYXNlIFNQSU5BTkRfUkVBRElEOgo+ID4+ICsJCXNuYW5kYy0+YnVmX2NvdW50ID0gNDsK PiA+PiArCQlxY29tX3JlYWRfcmVnX2RtYShzbmFuZGMsIE5BTkRfUkVBRF9JRCwgMSwgTkFORF9C QU1fTkVYVF9TR0wpOwo+ID4+ICsJCWNvcHkgPSB0cnVlOwo+ID4+ICsJCWJyZWFrOwo+ID4+ICsJ Y2FzZSBTUElOQU5EX0dFVF9GRUFUVVJFOgo+ID4+ICsJCXNuYW5kYy0+YnVmX2NvdW50ID0gNDsK PiA+PiArCQlxY29tX3JlYWRfcmVnX2RtYShzbmFuZGMsIE5BTkRfRkxBU0hfRkVBVFVSRVMsIDEs IE5BTkRfQkFNX05FWFRfU0dMKTsKPiA+PiArCQljb3B5X2Z0ciA9IHRydWU7Cj4gPj4gKwkJYnJl YWs7Cj4gPj4gKwljYXNlIFNQSU5BTkRfU0VUX0ZFQVRVUkU6Cj4gPj4gKwkJc25hbmRjLT5yZWdz LT5mbGFzaF9mZWF0dXJlID0gKih1MzIgKilvcC0+ZGF0YS5idWYub3V0Owo+ID4+ICsJCXFjb21f d3JpdGVfcmVnX2RtYShzbmFuZGMsICZzbmFuZGMtPnJlZ3MtPmZsYXNoX2ZlYXR1cmUsCj4gPj4g KwkJCQkgICBOQU5EX0ZMQVNIX0ZFQVRVUkVTLCAxLCBOQU5EX0JBTV9ORVhUX1NHTCk7Cj4gPj4g KwkJYnJlYWs7Cj4gPj4gKwljYXNlIFNQSU5BTkRfUkVTRVQ6Cj4gPj4gKwkJcmV0dXJuIDA7Cj4g Pj4gKwljYXNlIFNQSU5BTkRfUFJPR1JBTV9FWEVDVVRFOgo+ID4+ICsJCXJldHVybiAwOwo+ID4+ ICsJY2FzZSBTUElOQU5EX1dSSVRFX0VOOgo+ID4+ICsJCXJldHVybiAwOwo+ID4+ICsJY2FzZSBT UElOQU5EX0VSQVNFOgo+ID4+ICsJCXJldHVybiAwOwo+ID4+ICsJY2FzZSBTUElOQU5EX1JFQUQ6 Cj4gPj4gKwkJcmV0dXJuIDA7ICAKPiA+IAo+ID4gWW91IGNhbiBzdGFjayB0aGUgY2FzZXMgIAo+ IE9rCj4gPiAgIAo+ID4+ICsJZGVmYXVsdDoKPiA+PiArCQlyZXR1cm4gLUVPUE5PVFNVUFA7Cj4g Pj4gKwl9Cj4gPj4gKwo+ID4+ICsJcmV0ID0gcWNvbV9zdWJtaXRfZGVzY3Moc25hbmRjKTsKPiA+ PiArCWlmIChyZXQpCj4gPj4gKwkJZGV2X2VycihzbmFuZGMtPmRldiwgImZhaWx1cmUgaW4gc3Vi bWl0dGluZyBkZXNjcmlwdG9yIGZvcjolZFxuIiwgb3Bjb2RlKTsKPiA+PiArCj4gPj4gKwlpZiAo Y29weSkgewo+ID4+ICsJCXFjb21fbmFuZGNfZGV2X3RvX21lbShzbmFuZGMsIHRydWUpOwo+ID4+ ICsJCW1lbWNweShvcC0+ZGF0YS5idWYuaW4sIHNuYW5kYy0+cmVnX3JlYWRfYnVmLCBzbmFuZGMt PmJ1Zl9jb3VudCk7Cj4gPj4gKwl9Cj4gPj4gKwo+ID4+ICsJaWYgKGNvcHlfZnRyKSB7Cj4gPj4g KwkJcWNvbV9uYW5kY19kZXZfdG9fbWVtKHNuYW5kYywgdHJ1ZSk7Cj4gPj4gKwkJdmFsID0gbGUz Ml90b19jcHUoKihfX2xlMzIgKilzbmFuZGMtPnJlZ19yZWFkX2J1Zik7Cj4gPj4gKwkJdmFsID4+ PSA4Owo+ID4+ICsJCW1lbWNweShvcC0+ZGF0YS5idWYuaW4sICZ2YWwsIHNuYW5kYy0+YnVmX2Nv dW50KTsKPiA+PiArCX0KPiA+PiArCj4gPj4gKwlyZXR1cm4gcmV0Owo+ID4+ICt9CgpUaGFua3Ms Ck1pcXXDqGwKCl9fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19f X19fX19fXwpMaW51eCBNVEQgZGlzY3Vzc2lvbiBtYWlsaW5nIGxpc3QKaHR0cDovL2xpc3RzLmlu ZnJhZGVhZC5vcmcvbWFpbG1hbi9saXN0aW5mby9saW51eC1tdGQvCg==