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=-15.3 required=3.0 tests=BAYES_00, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS,USER_AGENT_SANE_1 autolearn=ham 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 2BC83C43460 for ; Sun, 2 May 2021 11:53:46 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id EEFEC610A7 for ; Sun, 2 May 2021 11:53:45 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S231284AbhEBLyY (ORCPT ); Sun, 2 May 2021 07:54:24 -0400 Received: from mx2.suse.de ([195.135.220.15]:46764 "EHLO mx2.suse.de" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230120AbhEBLyY (ORCPT ); Sun, 2 May 2021 07:54:24 -0400 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 103AFB1B9; Sun, 2 May 2021 11:53:32 +0000 (UTC) Subject: Re: [RFC PATCH v4 24/27] qedn: Add support of NVME ICReq & ICResp To: Shai Malin , netdev@vger.kernel.org, linux-nvme@lists.infradead.org, sagi@grimberg.me, hch@lst.de, axboe@fb.com, kbusch@kernel.org Cc: "David S . Miller davem @ davemloft . net --cc=Jakub Kicinski" , aelior@marvell.com, mkalderon@marvell.com, okulkarni@marvell.com, pkushwaha@marvell.com, malin1024@gmail.com References: <20210429190926.5086-1-smalin@marvell.com> <20210429190926.5086-25-smalin@marvell.com> From: Hannes Reinecke Message-ID: <0114e63f-bea8-cd9f-2fe8-7f8f46fa26bd@suse.de> Date: Sun, 2 May 2021 13:53:31 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.8.0 MIME-Version: 1.0 In-Reply-To: <20210429190926.5086-25-smalin@marvell.com> Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-US Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org On 4/29/21 9:09 PM, Shai Malin wrote: > From: Prabhakar Kushwaha > > Once a TCP connection established, the host sends an Initialize > Connection Request (ICReq) PDU to the controller. > Further Initialize Connection Response (ICResp) PDU received from > controller is processed by host to establish a connection and > exchange connection configuration parameters. > > This patch present support of generation of ICReq and processing of > ICResp. It also update host configuration based on exchanged parameters. > > Acked-by: Igor Russkikh > Signed-off-by: Prabhakar Kushwaha > Signed-off-by: Omkar Kulkarni > Signed-off-by: Michal Kalderon > Signed-off-by: Ariel Elior > Signed-off-by: Shai Malin > --- > drivers/nvme/hw/qedn/qedn.h | 36 ++++ > drivers/nvme/hw/qedn/qedn_conn.c | 317 ++++++++++++++++++++++++++++++- > drivers/nvme/hw/qedn/qedn_main.c | 22 +++ > drivers/nvme/hw/qedn/qedn_task.c | 8 +- > 4 files changed, 379 insertions(+), 4 deletions(-) > > diff --git a/drivers/nvme/hw/qedn/qedn.h b/drivers/nvme/hw/qedn/qedn.h > index 880ca245b02c..773a57994148 100644 > --- a/drivers/nvme/hw/qedn/qedn.h > +++ b/drivers/nvme/hw/qedn/qedn.h > @@ -16,6 +16,7 @@ > > /* Driver includes */ > #include "../../host/tcp-offload.h" > +#include > > #define QEDN_MAJOR_VERSION 8 > #define QEDN_MINOR_VERSION 62 > @@ -52,6 +53,8 @@ > > /* Protocol defines */ > #define QEDN_MAX_IO_SIZE QED_NVMETCP_MAX_IO_SIZE > +#define QEDN_MAX_PDU_SIZE 0x80000 /* 512KB */ > +#define QEDN_MAX_OUTSTANDING_R2T_PDUS 0 /* 0 Based == 1 max R2T */ > > #define QEDN_SGE_BUFF_SIZE 4096 > #define QEDN_MAX_SGES_PER_TASK DIV_ROUND_UP(QEDN_MAX_IO_SIZE, QEDN_SGE_BUFF_SIZE) > @@ -65,6 +68,11 @@ > #define QEDN_TASK_INSIST_TMO 1000 /* 1 sec */ > #define QEDN_INVALID_ITID 0xFFFF > > +#define QEDN_ICREQ_FW_PAYLOAD (sizeof(struct nvme_tcp_icreq_pdu) - \ > + sizeof(struct nvmetcp_init_conn_req_hdr)) > +/* The FW will handle the ICReq as CCCID 0 (FW internal design) */ > +#define QEDN_ICREQ_CCCID 0 > + > /* > * TCP offload stack default configurations and defines. > * Future enhancements will allow controlling the configurable > @@ -136,6 +144,16 @@ struct qedn_fp_queue { > char irqname[QEDN_IRQ_NAME_LEN]; > }; > > +struct qedn_negotiation_params { > + u32 maxh2cdata; /* Negotiation */ > + u32 maxr2t; /* Validation */ > + u16 pfv; /* Validation */ > + bool hdr_digest; /* Negotiation */ > + bool data_digest; /* Negotiation */ > + u8 cpda; /* Negotiation */ > + u8 hpda; /* Validation */ > +}; > + > struct qedn_ctx { > struct pci_dev *pdev; > struct qed_dev *cdev; > @@ -195,6 +213,9 @@ struct qedn_endpoint { > struct qed_chain fw_sq_chain; > void __iomem *p_doorbell; > > + /* Spinlock for accessing FW queue */ > + spinlock_t doorbell_lock; > + > /* TCP Params */ > __be32 dst_addr[4]; /* In network order */ > __be32 src_addr[4]; /* In network order */ > @@ -268,6 +289,12 @@ struct qedn_ctrl { > atomic_t host_num_active_conns; > }; > > +struct qedn_icreq_padding { > + u32 *buffer; > + dma_addr_t pa; > + struct nvmetcp_sge sge; > +}; > + > /* Connection level struct */ > struct qedn_conn_ctx { > /* IO path */ > @@ -329,6 +356,11 @@ struct qedn_conn_ctx { > > size_t sq_depth; > > + struct qedn_negotiation_params required_params; > + struct qedn_negotiation_params pdu_params; > + struct nvmetcp_icresp_hdr_psh icresp; > + struct qedn_icreq_padding *icreq_pad; > + > /* "dummy" socket */ > struct socket *sock; > }; > @@ -337,6 +369,7 @@ enum qedn_conn_resources_state { > QEDN_CONN_RESRC_FW_SQ, > QEDN_CONN_RESRC_ACQUIRE_CONN, > QEDN_CONN_RESRC_TASKS, > + QEDN_CONN_RESRC_ICREQ_PAD, > QEDN_CONN_RESRC_CCCID_ITID_MAP, > QEDN_CONN_RESRC_TCP_PORT, > QEDN_CONN_RESRC_MAX = 64 > @@ -375,5 +408,8 @@ void qedn_common_clear_fw_sgl(struct storage_sgl_task_params *sgl_task_params); > void qedn_return_active_tasks(struct qedn_conn_ctx *conn_ctx); > void qedn_destroy_free_tasks(struct qedn_fp_queue *fp_q, > struct qedn_io_resources *io_resrc); > +void qedn_swap_bytes(u32 *p, int size); > +void qedn_prep_icresp(struct qedn_conn_ctx *conn_ctx, struct nvmetcp_fw_cqe *cqe); > +void qedn_ring_doorbell(struct qedn_conn_ctx *conn_ctx); > > #endif /* _QEDN_H_ */ > diff --git a/drivers/nvme/hw/qedn/qedn_conn.c b/drivers/nvme/hw/qedn/qedn_conn.c > index 10a80fbeac43..5679354aa0e0 100644 > --- a/drivers/nvme/hw/qedn/qedn_conn.c > +++ b/drivers/nvme/hw/qedn/qedn_conn.c > @@ -34,6 +34,25 @@ inline int qedn_qid(struct nvme_tcp_ofld_queue *queue) > return queue - queue->ctrl->queues; > } > > +void qedn_ring_doorbell(struct qedn_conn_ctx *conn_ctx) > +{ > + struct nvmetcp_db_data dbell = { 0 }; > + u16 prod_idx; > + > + dbell.agg_flags = 0; > + dbell.params |= DB_DEST_XCM << NVMETCP_DB_DATA_DEST_SHIFT; > + dbell.params |= DB_AGG_CMD_SET << NVMETCP_DB_DATA_AGG_CMD_SHIFT; > + dbell.params |= > + DQ_XCM_ISCSI_SQ_PROD_CMD << NVMETCP_DB_DATA_AGG_VAL_SEL_SHIFT; > + dbell.params |= 1 << NVMETCP_DB_DATA_BYPASS_EN_SHIFT; > + prod_idx = qed_chain_get_prod_idx(&conn_ctx->ep.fw_sq_chain); > + dbell.sq_prod = cpu_to_le16(prod_idx); > + > + /* wmb - Make sure fw idx is coherent */ > + wmb(); > + writel(*(u32 *)&dbell, conn_ctx->ep.p_doorbell); > +} > + > int qedn_set_con_state(struct qedn_conn_ctx *conn_ctx, enum qedn_conn_state new_state) > { > spin_lock_bh(&conn_ctx->conn_state_lock); > @@ -130,6 +149,71 @@ int qedn_initialize_endpoint(struct qedn_endpoint *ep, u8 *local_mac_addr, > return -1; > } > > +static int qedn_alloc_icreq_pad(struct qedn_conn_ctx *conn_ctx) > +{ > + struct qedn_ctx *qedn = conn_ctx->qedn; > + struct qedn_icreq_padding *icreq_pad; > + u32 *buffer; > + int rc = 0; > + > + icreq_pad = kzalloc(sizeof(*icreq_pad), GFP_KERNEL); > + if (!icreq_pad) > + return -ENOMEM; > + > + conn_ctx->icreq_pad = icreq_pad; > + memset(&icreq_pad->sge, 0, sizeof(icreq_pad->sge)); > + buffer = dma_alloc_coherent(&qedn->pdev->dev, > + QEDN_ICREQ_FW_PAYLOAD, > + &icreq_pad->pa, > + GFP_KERNEL); > + if (!buffer) { > + pr_err("Could not allocate icreq_padding SGE buffer.\n"); > + rc = -ENOMEM; > + goto release_icreq_pad; > + } > + > + DMA_REGPAIR_LE(icreq_pad->sge.sge_addr, icreq_pad->pa); > + icreq_pad->sge.sge_len = cpu_to_le32(QEDN_ICREQ_FW_PAYLOAD); > + icreq_pad->buffer = buffer; > + set_bit(QEDN_CONN_RESRC_ICREQ_PAD, &conn_ctx->resrc_state); > + > + return 0; > + > +release_icreq_pad: > + kfree(icreq_pad); > + conn_ctx->icreq_pad = NULL; > + > + return rc; > +} > + > +static void qedn_free_icreq_pad(struct qedn_conn_ctx *conn_ctx) > +{ > + struct qedn_ctx *qedn = conn_ctx->qedn; > + struct qedn_icreq_padding *icreq_pad; > + u32 *buffer; > + > + icreq_pad = conn_ctx->icreq_pad; > + if (unlikely(!icreq_pad)) { > + pr_err("null ptr in icreq_pad in conn_ctx\n"); > + goto finally; > + } > + > + buffer = icreq_pad->buffer; > + if (buffer) { > + dma_free_coherent(&qedn->pdev->dev, > + QEDN_ICREQ_FW_PAYLOAD, > + (void *)buffer, > + icreq_pad->pa); > + icreq_pad->buffer = NULL; > + } > + > + kfree(icreq_pad); > + conn_ctx->icreq_pad = NULL; > + > +finally: > + clear_bit(QEDN_CONN_RESRC_ICREQ_PAD, &conn_ctx->resrc_state); > +} > + > static void qedn_release_conn_ctx(struct qedn_conn_ctx *conn_ctx) > { > struct qedn_ctx *qedn = conn_ctx->qedn; > @@ -151,6 +235,9 @@ static void qedn_release_conn_ctx(struct qedn_conn_ctx *conn_ctx) > clear_bit(QEDN_CONN_RESRC_ACQUIRE_CONN, &conn_ctx->resrc_state); > } > > + if (test_bit(QEDN_CONN_RESRC_ICREQ_PAD, &conn_ctx->resrc_state)) > + qedn_free_icreq_pad(conn_ctx); > + > if (test_bit(QEDN_CONN_RESRC_TASKS, &conn_ctx->resrc_state)) { > clear_bit(QEDN_CONN_RESRC_TASKS, &conn_ctx->resrc_state); > qedn_return_active_tasks(conn_ctx); > @@ -309,6 +396,194 @@ void qedn_terminate_connection(struct qedn_conn_ctx *conn_ctx, int abrt_flag) > queue_work(qctrl->sp_wq, &conn_ctx->sp_wq_entry); > } > > +static int qedn_nvmetcp_update_conn(struct qedn_ctx *qedn, struct qedn_conn_ctx *conn_ctx) > +{ > + struct qedn_negotiation_params *pdu_params = &conn_ctx->pdu_params; > + struct qed_nvmetcp_params_update *conn_info; > + int rc; > + > + conn_info = kzalloc(sizeof(*conn_info), GFP_KERNEL); > + if (!conn_info) > + return -ENOMEM; > + > + conn_info->hdr_digest_en = pdu_params->hdr_digest; > + conn_info->data_digest_en = pdu_params->data_digest; > + conn_info->max_recv_pdu_length = QEDN_MAX_PDU_SIZE; > + conn_info->max_io_size = QEDN_MAX_IO_SIZE; > + conn_info->max_send_pdu_length = pdu_params->maxh2cdata; > + > + rc = qed_ops->update_conn(qedn->cdev, conn_ctx->conn_handle, conn_info); > + if (rc) { > + pr_err("Could not update connection\n"); > + rc = -ENXIO; > + } > + > + kfree(conn_info); > + > + return rc; > +} > + > +static int qedn_update_ramrod(struct qedn_conn_ctx *conn_ctx) > +{ > + struct qedn_ctx *qedn = conn_ctx->qedn; > + int rc = 0; > + > + rc = qedn_set_con_state(conn_ctx, CONN_STATE_WAIT_FOR_UPDATE_EQE); > + if (rc) > + return rc; > + > + rc = qedn_nvmetcp_update_conn(qedn, conn_ctx); > + if (rc) > + return rc; > + > + if (conn_ctx->state != CONN_STATE_WAIT_FOR_UPDATE_EQE) { > + pr_err("cid 0x%x: Unexpected state 0x%x after update ramrod\n", > + conn_ctx->fw_cid, conn_ctx->state); > + > + return -EINVAL; > + } > + > + return rc; > +} > + > +static int qedn_send_icreq(struct qedn_conn_ctx *conn_ctx) > +{ > + struct nvmetcp_init_conn_req_hdr *icreq_ptr = NULL; > + struct storage_sgl_task_params *sgl_task_params; > + struct nvmetcp_task_params task_params; > + struct qedn_task_ctx *qedn_task = NULL; > + struct nvme_tcp_icreq_pdu icreq; > + struct nvmetcp_wqe *chain_sqe; > + struct nvmetcp_wqe local_sqe; > + > + qedn_task = qedn_get_task_from_pool_insist(conn_ctx, QEDN_ICREQ_CCCID); > + if (!qedn_task) > + return -EINVAL; > + > + memset(&icreq, 0, sizeof(icreq)); > + memset(&local_sqe, 0, sizeof(local_sqe)); > + > + /* Initialize ICReq */ > + icreq.hdr.type = nvme_tcp_icreq; > + icreq.hdr.hlen = sizeof(icreq); > + icreq.hdr.pdo = 0; > + icreq.hdr.plen = cpu_to_le32(icreq.hdr.hlen); > + icreq.pfv = cpu_to_le16(conn_ctx->required_params.pfv); > + icreq.maxr2t = cpu_to_le32(conn_ctx->required_params.maxr2t); > + icreq.hpda = conn_ctx->required_params.hpda; > + if (conn_ctx->required_params.hdr_digest) > + icreq.digest |= NVME_TCP_HDR_DIGEST_ENABLE; > + if (conn_ctx->required_params.data_digest) > + icreq.digest |= NVME_TCP_DATA_DIGEST_ENABLE; > + > + qedn_swap_bytes((u32 *)&icreq, > + (sizeof(icreq) - QEDN_ICREQ_FW_PAYLOAD) / > + sizeof(u32)); > + > + /* Initialize task params */ > + task_params.opq.lo = cpu_to_le32(((u64)(qedn_task)) & 0xffffffff); > + task_params.opq.hi = cpu_to_le32(((u64)(qedn_task)) >> 32); > + task_params.context = qedn_task->fw_task_ctx; > + task_params.sqe = &local_sqe; > + task_params.conn_icid = (u16)conn_ctx->conn_handle; > + task_params.itid = qedn_task->itid; > + task_params.cq_rss_number = conn_ctx->default_cq; > + task_params.tx_io_size = QEDN_ICREQ_FW_PAYLOAD; > + task_params.rx_io_size = 0; /* Rx doesn't use SGL for icresp */ > + > + /* Init SGE for ICReq padding */ > + sgl_task_params = &qedn_task->sgl_task_params; > + sgl_task_params->total_buffer_size = task_params.tx_io_size; > + sgl_task_params->small_mid_sge = false; > + sgl_task_params->num_sges = 1; > + memcpy(sgl_task_params->sgl, &conn_ctx->icreq_pad->sge, > + sizeof(conn_ctx->icreq_pad->sge)); > + icreq_ptr = (struct nvmetcp_init_conn_req_hdr *)&icreq; > + > + qed_ops->init_icreq_exchange(&task_params, icreq_ptr, sgl_task_params, NULL); > + > + qedn_set_con_state(conn_ctx, CONN_STATE_WAIT_FOR_IC_COMP); > + atomic_inc(&conn_ctx->num_active_fw_tasks); > + > + /* spin_lock - doorbell is accessed both Rx flow and response flow */ > + spin_lock(&conn_ctx->ep.doorbell_lock); > + chain_sqe = qed_chain_produce(&conn_ctx->ep.fw_sq_chain); > + memcpy(chain_sqe, &local_sqe, sizeof(local_sqe)); > + qedn_ring_doorbell(conn_ctx); > + spin_unlock(&conn_ctx->ep.doorbell_lock); > + > + return 0; > +} > + And this is what I meant. You _do_ swab bytes before sending it off to the HW, _and_ you use the standard nvme-tcp PDU definitions. So why do you have your own, byte-swapped versions of the PDUs? > +void qedn_prep_icresp(struct qedn_conn_ctx *conn_ctx, struct nvmetcp_fw_cqe *cqe) > +{ > + struct nvmetcp_icresp_hdr_psh *icresp_from_cqe = > + (struct nvmetcp_icresp_hdr_psh *)&cqe->nvme_cqe; > + struct nvme_tcp_ofld_ctrl *ctrl = conn_ctx->ctrl; > + struct qedn_ctrl *qctrl = NULL; > + > + qctrl = (struct qedn_ctrl *)ctrl->private_data; > + > + memcpy(&conn_ctx->icresp, icresp_from_cqe, sizeof(conn_ctx->icresp)); > + qedn_set_sp_wa(conn_ctx, HANDLE_ICRESP); > + queue_work(qctrl->sp_wq, &conn_ctx->sp_wq_entry); > +} > + > +static int qedn_handle_icresp(struct qedn_conn_ctx *conn_ctx) > +{ > + struct nvmetcp_icresp_hdr_psh *icresp = &conn_ctx->icresp; > + u16 pfv = __swab16(le16_to_cpu(icresp->pfv_swapped)); > + int rc = 0; > + Again here; you could treat the received icresp as a binaray blob. byteswap it, and then cast is to the standard icresp structure. Hmm? > + qedn_free_icreq_pad(conn_ctx); > + > + /* Validate ICResp */ > + if (pfv != conn_ctx->required_params.pfv) { > + pr_err("cid %u: unsupported pfv %u\n", conn_ctx->fw_cid, pfv); > + > + return -EINVAL; > + } > + > + if (icresp->cpda > conn_ctx->required_params.cpda) { > + pr_err("cid %u: unsupported cpda %u\n", conn_ctx->fw_cid, icresp->cpda); > + > + return -EINVAL; > + } > + > + if ((NVME_TCP_HDR_DIGEST_ENABLE & icresp->digest) != > + conn_ctx->required_params.hdr_digest) { > + if ((NVME_TCP_HDR_DIGEST_ENABLE & icresp->digest) > > + conn_ctx->required_params.hdr_digest) { > + pr_err("cid 0x%x: invalid header digest bit\n", conn_ctx->fw_cid); > + } > + } > + > + if ((NVME_TCP_DATA_DIGEST_ENABLE & icresp->digest) != > + conn_ctx->required_params.data_digest) { > + if ((NVME_TCP_DATA_DIGEST_ENABLE & icresp->digest) > > + conn_ctx->required_params.data_digest) { > + pr_err("cid 0x%x: invalid data digest bit\n", conn_ctx->fw_cid); > + } > + } > + > + memset(&conn_ctx->pdu_params, 0, sizeof(conn_ctx->pdu_params)); > + conn_ctx->pdu_params.maxh2cdata = > + __swab32(le32_to_cpu(icresp->maxdata_swapped)); > + conn_ctx->pdu_params.maxh2cdata = QEDN_MAX_PDU_SIZE; > + if (conn_ctx->pdu_params.maxh2cdata > QEDN_MAX_PDU_SIZE) > + conn_ctx->pdu_params.maxh2cdata = QEDN_MAX_PDU_SIZE; > + > + conn_ctx->pdu_params.pfv = pfv; > + conn_ctx->pdu_params.cpda = icresp->cpda; > + conn_ctx->pdu_params.hpda = conn_ctx->required_params.hpda; > + conn_ctx->pdu_params.hdr_digest = NVME_TCP_HDR_DIGEST_ENABLE & icresp->digest; > + conn_ctx->pdu_params.data_digest = NVME_TCP_DATA_DIGEST_ENABLE & icresp->digest; > + conn_ctx->pdu_params.maxr2t = conn_ctx->required_params.maxr2t; > + rc = qedn_update_ramrod(conn_ctx); > + > + return rc; > +} > + > /* Slowpath EQ Callback */ > int qedn_event_cb(void *context, u8 fw_event_code, void *event_ring_data) > { > @@ -363,7 +638,8 @@ int qedn_event_cb(void *context, u8 fw_event_code, void *event_ring_data) > if (rc) > return rc; > > - /* Placeholder - for ICReq flow */ > + qedn_set_sp_wa(conn_ctx, SEND_ICREQ); > + queue_work(qctrl->sp_wq, &conn_ctx->sp_wq_entry); > } > > break; > @@ -399,6 +675,7 @@ static int qedn_prep_and_offload_queue(struct qedn_conn_ctx *conn_ctx) > } > > set_bit(QEDN_CONN_RESRC_FW_SQ, &conn_ctx->resrc_state); > + spin_lock_init(&conn_ctx->ep.doorbell_lock); > INIT_LIST_HEAD(&conn_ctx->host_pend_req_list); > spin_lock_init(&conn_ctx->nvme_req_lock); > atomic_set(&conn_ctx->num_active_tasks, 0); > @@ -463,6 +740,11 @@ static int qedn_prep_and_offload_queue(struct qedn_conn_ctx *conn_ctx) > > memset(conn_ctx->host_cccid_itid, 0xFF, dma_size); > set_bit(QEDN_CONN_RESRC_CCCID_ITID_MAP, &conn_ctx->resrc_state); > + > + rc = qedn_alloc_icreq_pad(conn_ctx); > + if (rc) > + goto rel_conn; > + > rc = qedn_set_con_state(conn_ctx, CONN_STATE_WAIT_FOR_CONNECT_DONE); > if (rc) > goto rel_conn; > @@ -523,6 +805,9 @@ void qedn_sp_wq_handler(struct work_struct *work) > > qedn = conn_ctx->qedn; > if (test_bit(DESTROY_CONNECTION, &conn_ctx->agg_work_action)) { > + if (test_bit(HANDLE_ICRESP, &conn_ctx->agg_work_action)) > + qedn_clr_sp_wa(conn_ctx, HANDLE_ICRESP); > + > qedn_destroy_connection(conn_ctx); > > return; > @@ -537,6 +822,36 @@ void qedn_sp_wq_handler(struct work_struct *work) > return; > } > } > + > + if (test_bit(SEND_ICREQ, &conn_ctx->agg_work_action)) { > + qedn_clr_sp_wa(conn_ctx, SEND_ICREQ); > + rc = qedn_send_icreq(conn_ctx); > + if (rc) > + return; > + > + return; > + } > + > + if (test_bit(HANDLE_ICRESP, &conn_ctx->agg_work_action)) { > + rc = qedn_handle_icresp(conn_ctx); > + > + qedn_clr_sp_wa(conn_ctx, HANDLE_ICRESP); > + if (rc) { > + pr_err("IC handling returned with 0x%x\n", rc); > + if (test_and_set_bit(DESTROY_CONNECTION, &conn_ctx->agg_work_action)) > + return; > + > + qedn_destroy_connection(conn_ctx); > + > + return; > + } > + > + atomic_inc(&conn_ctx->est_conn_indicator); > + qedn_set_con_state(conn_ctx, CONN_STATE_NVMETCP_CONN_ESTABLISHED); > + wake_up_interruptible(&conn_ctx->conn_waitq); > + > + return; > + } > } > > /* Clear connection aggregative slowpath work action */ > diff --git a/drivers/nvme/hw/qedn/qedn_main.c b/drivers/nvme/hw/qedn/qedn_main.c > index 8d9c19d63480..a6756d7250b7 100644 > --- a/drivers/nvme/hw/qedn/qedn_main.c > +++ b/drivers/nvme/hw/qedn/qedn_main.c > @@ -285,6 +285,19 @@ static void qedn_set_ctrl_io_cpus(struct qedn_conn_ctx *conn_ctx, int qid) > conn_ctx->cpu = fp_q->cpu; > } > > +static void qedn_set_pdu_params(struct qedn_conn_ctx *conn_ctx) > +{ > + /* Enable digest once supported */ > + conn_ctx->required_params.hdr_digest = 0; > + conn_ctx->required_params.data_digest = 0; > + > + conn_ctx->required_params.maxr2t = QEDN_MAX_OUTSTANDING_R2T_PDUS; > + conn_ctx->required_params.pfv = NVME_TCP_PFV_1_0; > + conn_ctx->required_params.cpda = 0; > + conn_ctx->required_params.hpda = 0; > + conn_ctx->required_params.maxh2cdata = QEDN_MAX_PDU_SIZE; > +} > + > static int qedn_create_queue(struct nvme_tcp_ofld_queue *queue, int qid, size_t q_size) > { > struct nvme_tcp_ofld_ctrl *ctrl = queue->ctrl; > @@ -307,6 +320,7 @@ static int qedn_create_queue(struct nvme_tcp_ofld_queue *queue, int qid, size_t > conn_ctx->ctrl = ctrl; > conn_ctx->sq_depth = q_size; > qedn_set_ctrl_io_cpus(conn_ctx, qid); > + qedn_set_pdu_params(conn_ctx); > > init_waitqueue_head(&conn_ctx->conn_waitq); > atomic_set(&conn_ctx->est_conn_indicator, 0); > @@ -1073,6 +1087,14 @@ static int qedn_probe(struct pci_dev *pdev, const struct pci_device_id *id) > return __qedn_probe(pdev); > } > > +void qedn_swap_bytes(u32 *p, int size) > +{ > + int i; > + > + for (i = 0; i < size; ++i, ++p) > + *p = __swab32(*p); > +} > + > static struct pci_driver qedn_pci_driver = { > .name = QEDN_MODULE_NAME, > .id_table = qedn_pci_tbl, > diff --git a/drivers/nvme/hw/qedn/qedn_task.c b/drivers/nvme/hw/qedn/qedn_task.c > index 54f2f4cba6ea..9cb84883e95e 100644 > --- a/drivers/nvme/hw/qedn/qedn_task.c > +++ b/drivers/nvme/hw/qedn/qedn_task.c > @@ -536,9 +536,11 @@ void qedn_io_work_cq(struct qedn_ctx *qedn, struct nvmetcp_fw_cqe *cqe) > break; > > case NVMETCP_TASK_TYPE_INIT_CONN_REQUEST: > - > - /* Placeholder - ICReq flow */ > - > + /* Clear ICReq-padding SGE from SGL */ > + qedn_common_clear_fw_sgl(&qedn_task->sgl_task_params); > + /* Task is not required for icresp processing */ > + qedn_return_task_to_pool(conn_ctx, qedn_task); > + qedn_prep_icresp(conn_ctx, cqe); > break; > default: > pr_info("Could not identify task type\n"); > Cheers, Hannes -- Dr. Hannes Reinecke Kernel Storage Architect hare@suse.de +49 911 74053 688 SUSE Software Solutions GmbH, Maxfeldstr. 5, 90409 Nürnberg HRB 36809 (AG Nürnberg), Geschäftsführer: Felix Imendörffer 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=-15.9 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER, INCLUDES_PATCH,MAILING_LIST_MULTI,NICE_REPLY_A,SPF_HELO_NONE,SPF_PASS, USER_AGENT_SANE_1 autolearn=ham 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 AE7CEC43603 for ; Sun, 2 May 2021 11:53:49 +0000 (UTC) Received: from desiato.infradead.org (desiato.infradead.org [90.155.92.199]) (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 E61E8611AC for ; Sun, 2 May 2021 11:53:48 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E61E8611AC Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-nvme-bounces+linux-nvme=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=desiato.20200630; h=Sender:Content-Type: Content-Transfer-Encoding:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:In-Reply-To:MIME-Version:Date:Message-ID:From: References:Cc:To:Subject:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=+gAhO98zTJvSL2Dppq1ZY3evb08KGPQAnfOYGAeZ7uw=; b=mXLDghXlLCaDOuBPkKUExUuCm Dfm4jBqwlf7fWEjDlmNO1e9n2mNqBtlEbc9SwY4RC6ihrTmUbnktkihvqo8WdZCCnTj5PyApyuPXQ 9a/JcG0jfAi0H0q8iEEXBbAM3vCg04uzBFPjQfvdgXdo0kto6h0/F9OyDLeuR7v0QOpt30RrYTmzX bVK63TlFtT9ZEnq0MkaMGUiDkcKBEDsScMDBFyGvr1BVoLQEx/4FF3imfP372yNVotRGOjfoe+g1I WGHCnuztH9TrcnNLm/Bn9ss5vXEKaD+cwaF1sS45AxxXgw0qNTP/1Q+lUCio7/cMPGoURfRttuFzw OgUgieFpQ==; Received: from localhost ([::1] helo=desiato.infradead.org) by desiato.infradead.org with esmtp (Exim 4.94 #2 (Red Hat Linux)) id 1ldAfO-00BiCn-9Z; Sun, 02 May 2021 11:53:42 +0000 Received: from bombadil.infradead.org ([2607:7c80:54:e::133]) by desiato.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1ldAfJ-00BiC6-H4 for linux-nvme@desiato.infradead.org; Sun, 02 May 2021 11:53:38 +0000 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=infradead.org; s=bombadil.20210309; h=Content-Transfer-Encoding: Content-Type:In-Reply-To:MIME-Version:Date:Message-ID:From:References:Cc:To: Subject:Sender:Reply-To:Content-ID:Content-Description; bh=lISw1wwP1Izy3kbuojmDqgNISdilRH+R+Gsa24ny2N4=; b=qdzwSSc2FgYHXv04VtWg1JaA/U zMgp2Q4SOdtJQO/iXlF61lOxkvvFWExOiO0jugTgqLrc+7M7uzVqpi6Kh4+gaA/y5ixl11wbyYHLK AX8btmgQxVU4o11ygnBBWePOdvvvTo7pcWJcTWJrF9yqMSPGVOLLs/EkVA2E9fTTIGUvhs09Z5V8w mNDNUCSzlTQ3rm8ZaHw5bbVo5IucLya0WC36/LWHfK5weMyP6KQiNRhYx0gjDms0zo0S5wQu8X9Sq W346JOV0PKicQm5w/jj45h8whfoahyynEzwcozWwkyLoljsJ/bCLQnLoEN6j25Eb5DmExIq1SJDLF SPcF/WeA==; Received: from mx2.suse.de ([195.135.220.15]) by bombadil.infradead.org with esmtps (Exim 4.94 #2 (Red Hat Linux)) id 1ldAfF-002Vv3-FV for linux-nvme@lists.infradead.org; Sun, 02 May 2021 11:53:36 +0000 X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 103AFB1B9; Sun, 2 May 2021 11:53:32 +0000 (UTC) Subject: Re: [RFC PATCH v4 24/27] qedn: Add support of NVME ICReq & ICResp To: Shai Malin , netdev@vger.kernel.org, linux-nvme@lists.infradead.org, sagi@grimberg.me, hch@lst.de, axboe@fb.com, kbusch@kernel.org Cc: "David S . Miller davem @ davemloft . net --cc=Jakub Kicinski" , aelior@marvell.com, mkalderon@marvell.com, okulkarni@marvell.com, pkushwaha@marvell.com, malin1024@gmail.com References: <20210429190926.5086-1-smalin@marvell.com> <20210429190926.5086-25-smalin@marvell.com> From: Hannes Reinecke Message-ID: <0114e63f-bea8-cd9f-2fe8-7f8f46fa26bd@suse.de> Date: Sun, 2 May 2021 13:53:31 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:78.0) Gecko/20100101 Thunderbird/78.8.0 MIME-Version: 1.0 In-Reply-To: <20210429190926.5086-25-smalin@marvell.com> Content-Language: en-US X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20210502_045333_855839_1F07A3AD X-CRM114-Status: GOOD ( 33.19 ) X-BeenThere: linux-nvme@lists.infradead.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Content-Transfer-Encoding: base64 Content-Type: text/plain; charset="utf-8"; Format="flowed" Sender: "Linux-nvme" Errors-To: linux-nvme-bounces+linux-nvme=archiver.kernel.org@lists.infradead.org T24gNC8yOS8yMSA5OjA5IFBNLCBTaGFpIE1hbGluIHdyb3RlOgo+IEZyb206IFByYWJoYWthciBL dXNod2FoYSA8cGt1c2h3YWhhQG1hcnZlbGwuY29tPgo+IAo+IE9uY2UgYSBUQ1AgY29ubmVjdGlv biBlc3RhYmxpc2hlZCwgdGhlIGhvc3Qgc2VuZHMgYW4gSW5pdGlhbGl6ZQo+IENvbm5lY3Rpb24g UmVxdWVzdCAoSUNSZXEpIFBEVSB0byB0aGUgY29udHJvbGxlci4KPiBGdXJ0aGVyIEluaXRpYWxp emUgQ29ubmVjdGlvbiBSZXNwb25zZSAoSUNSZXNwKSBQRFUgcmVjZWl2ZWQgZnJvbQo+IGNvbnRy b2xsZXIgaXMgcHJvY2Vzc2VkIGJ5IGhvc3QgdG8gZXN0YWJsaXNoIGEgY29ubmVjdGlvbiBhbmQK PiBleGNoYW5nZSBjb25uZWN0aW9uIGNvbmZpZ3VyYXRpb24gcGFyYW1ldGVycy4KPiAKPiBUaGlz IHBhdGNoIHByZXNlbnQgc3VwcG9ydCBvZiBnZW5lcmF0aW9uIG9mIElDUmVxIGFuZCBwcm9jZXNz aW5nIG9mCj4gSUNSZXNwLiBJdCBhbHNvIHVwZGF0ZSBob3N0IGNvbmZpZ3VyYXRpb24gYmFzZWQg b24gZXhjaGFuZ2VkIHBhcmFtZXRlcnMuCj4gCj4gQWNrZWQtYnk6IElnb3IgUnVzc2tpa2ggPGly dXNza2lraEBtYXJ2ZWxsLmNvbT4KPiBTaWduZWQtb2ZmLWJ5OiBQcmFiaGFrYXIgS3VzaHdhaGEg PHBrdXNod2FoYUBtYXJ2ZWxsLmNvbT4KPiBTaWduZWQtb2ZmLWJ5OiBPbWthciBLdWxrYXJuaSA8 b2t1bGthcm5pQG1hcnZlbGwuY29tPgo+IFNpZ25lZC1vZmYtYnk6IE1pY2hhbCBLYWxkZXJvbiA8 bWthbGRlcm9uQG1hcnZlbGwuY29tPgo+IFNpZ25lZC1vZmYtYnk6IEFyaWVsIEVsaW9yIDxhZWxp b3JAbWFydmVsbC5jb20+Cj4gU2lnbmVkLW9mZi1ieTogU2hhaSBNYWxpbiA8c21hbGluQG1hcnZl bGwuY29tPgo+IC0tLQo+ICAgZHJpdmVycy9udm1lL2h3L3FlZG4vcWVkbi5oICAgICAgfCAgMzYg KysrKwo+ICAgZHJpdmVycy9udm1lL2h3L3FlZG4vcWVkbl9jb25uLmMgfCAzMTcgKysrKysrKysr KysrKysrKysrKysrKysrKysrKysrLQo+ICAgZHJpdmVycy9udm1lL2h3L3FlZG4vcWVkbl9tYWlu LmMgfCAgMjIgKysrCj4gICBkcml2ZXJzL252bWUvaHcvcWVkbi9xZWRuX3Rhc2suYyB8ICAgOCAr LQo+ICAgNCBmaWxlcyBjaGFuZ2VkLCAzNzkgaW5zZXJ0aW9ucygrKSwgNCBkZWxldGlvbnMoLSkK PiAKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9udm1lL2h3L3FlZG4vcWVkbi5oIGIvZHJpdmVycy9u dm1lL2h3L3FlZG4vcWVkbi5oCj4gaW5kZXggODgwY2EyNDViMDJjLi43NzNhNTc5OTQxNDggMTAw NjQ0Cj4gLS0tIGEvZHJpdmVycy9udm1lL2h3L3FlZG4vcWVkbi5oCj4gKysrIGIvZHJpdmVycy9u dm1lL2h3L3FlZG4vcWVkbi5oCj4gQEAgLTE2LDYgKzE2LDcgQEAKPiAgIAo+ICAgLyogRHJpdmVy IGluY2x1ZGVzICovCj4gICAjaW5jbHVkZSAiLi4vLi4vaG9zdC90Y3Atb2ZmbG9hZC5oIgo+ICsj aW5jbHVkZSA8bGludXgvbnZtZS10Y3AuaD4KPiAgIAo+ICAgI2RlZmluZSBRRUROX01BSk9SX1ZF UlNJT04JCTgKPiAgICNkZWZpbmUgUUVETl9NSU5PUl9WRVJTSU9OCQk2Mgo+IEBAIC01Miw2ICs1 Myw4IEBACj4gICAKPiAgIC8qIFByb3RvY29sIGRlZmluZXMgKi8KPiAgICNkZWZpbmUgUUVETl9N QVhfSU9fU0laRSBRRURfTlZNRVRDUF9NQVhfSU9fU0laRQo+ICsjZGVmaW5lIFFFRE5fTUFYX1BE VV9TSVpFIDB4ODAwMDAgLyogNTEyS0IgKi8KPiArI2RlZmluZSBRRUROX01BWF9PVVRTVEFORElO R19SMlRfUERVUyAwIC8qIDAgQmFzZWQgPT0gMSBtYXggUjJUICovCj4gICAKPiAgICNkZWZpbmUg UUVETl9TR0VfQlVGRl9TSVpFIDQwOTYKPiAgICNkZWZpbmUgUUVETl9NQVhfU0dFU19QRVJfVEFT SyBESVZfUk9VTkRfVVAoUUVETl9NQVhfSU9fU0laRSwgUUVETl9TR0VfQlVGRl9TSVpFKQo+IEBA IC02NSw2ICs2OCwxMSBAQAo+ICAgI2RlZmluZSBRRUROX1RBU0tfSU5TSVNUX1RNTyAxMDAwIC8q IDEgc2VjICovCj4gICAjZGVmaW5lIFFFRE5fSU5WQUxJRF9JVElEIDB4RkZGRgo+ICAgCj4gKyNk ZWZpbmUgUUVETl9JQ1JFUV9GV19QQVlMT0FEIChzaXplb2Yoc3RydWN0IG52bWVfdGNwX2ljcmVx X3BkdSkgLSBcCj4gKwkJCSAgICAgICBzaXplb2Yoc3RydWN0IG52bWV0Y3BfaW5pdF9jb25uX3Jl cV9oZHIpKQo+ICsvKiBUaGUgRlcgd2lsbCBoYW5kbGUgdGhlIElDUmVxIGFzIENDQ0lEIDAgKEZX IGludGVybmFsIGRlc2lnbikgKi8KPiArI2RlZmluZSBRRUROX0lDUkVRX0NDQ0lEIDAKPiArCj4g ICAvKgo+ICAgICogVENQIG9mZmxvYWQgc3RhY2sgZGVmYXVsdCBjb25maWd1cmF0aW9ucyBhbmQg ZGVmaW5lcy4KPiAgICAqIEZ1dHVyZSBlbmhhbmNlbWVudHMgd2lsbCBhbGxvdyBjb250cm9sbGlu ZyB0aGUgY29uZmlndXJhYmxlCj4gQEAgLTEzNiw2ICsxNDQsMTYgQEAgc3RydWN0IHFlZG5fZnBf cXVldWUgewo+ICAgCWNoYXIgaXJxbmFtZVtRRUROX0lSUV9OQU1FX0xFTl07Cj4gICB9Owo+ICAg Cj4gK3N0cnVjdCBxZWRuX25lZ290aWF0aW9uX3BhcmFtcyB7Cj4gKwl1MzIgbWF4aDJjZGF0YTsg LyogTmVnb3RpYXRpb24gKi8KPiArCXUzMiBtYXhyMnQ7IC8qIFZhbGlkYXRpb24gKi8KPiArCXUx NiBwZnY7IC8qIFZhbGlkYXRpb24gKi8KPiArCWJvb2wgaGRyX2RpZ2VzdDsgLyogTmVnb3RpYXRp b24gKi8KPiArCWJvb2wgZGF0YV9kaWdlc3Q7IC8qIE5lZ290aWF0aW9uICovCj4gKwl1OCBjcGRh OyAvKiBOZWdvdGlhdGlvbiAqLwo+ICsJdTggaHBkYTsgLyogVmFsaWRhdGlvbiAqLwo+ICt9Owo+ ICsKPiAgIHN0cnVjdCBxZWRuX2N0eCB7Cj4gICAJc3RydWN0IHBjaV9kZXYgKnBkZXY7Cj4gICAJ c3RydWN0IHFlZF9kZXYgKmNkZXY7Cj4gQEAgLTE5NSw2ICsyMTMsOSBAQCBzdHJ1Y3QgcWVkbl9l bmRwb2ludCB7Cj4gICAJc3RydWN0IHFlZF9jaGFpbiBmd19zcV9jaGFpbjsKPiAgIAl2b2lkIF9f aW9tZW0gKnBfZG9vcmJlbGw7Cj4gICAKPiArCS8qIFNwaW5sb2NrIGZvciBhY2Nlc3NpbmcgRlcg cXVldWUgKi8KPiArCXNwaW5sb2NrX3QgZG9vcmJlbGxfbG9jazsKPiArCj4gICAJLyogVENQIFBh cmFtcyAqLwo+ICAgCV9fYmUzMiBkc3RfYWRkcls0XTsgLyogSW4gbmV0d29yayBvcmRlciAqLwo+ ICAgCV9fYmUzMiBzcmNfYWRkcls0XTsgLyogSW4gbmV0d29yayBvcmRlciAqLwo+IEBAIC0yNjgs NiArMjg5LDEyIEBAIHN0cnVjdCBxZWRuX2N0cmwgewo+ICAgCWF0b21pY190IGhvc3RfbnVtX2Fj dGl2ZV9jb25uczsKPiAgIH07Cj4gICAKPiArc3RydWN0IHFlZG5faWNyZXFfcGFkZGluZyB7Cj4g Kwl1MzIgKmJ1ZmZlcjsKPiArCWRtYV9hZGRyX3QgcGE7Cj4gKwlzdHJ1Y3QgbnZtZXRjcF9zZ2Ug c2dlOwo+ICt9Owo+ICsKPiAgIC8qIENvbm5lY3Rpb24gbGV2ZWwgc3RydWN0ICovCj4gICBzdHJ1 Y3QgcWVkbl9jb25uX2N0eCB7Cj4gICAJLyogSU8gcGF0aCAqLwo+IEBAIC0zMjksNiArMzU2LDEx IEBAIHN0cnVjdCBxZWRuX2Nvbm5fY3R4IHsKPiAgIAo+ICAgCXNpemVfdCBzcV9kZXB0aDsKPiAg IAo+ICsJc3RydWN0IHFlZG5fbmVnb3RpYXRpb25fcGFyYW1zIHJlcXVpcmVkX3BhcmFtczsKPiAr CXN0cnVjdCBxZWRuX25lZ290aWF0aW9uX3BhcmFtcyBwZHVfcGFyYW1zOwo+ICsJc3RydWN0IG52 bWV0Y3BfaWNyZXNwX2hkcl9wc2ggaWNyZXNwOwo+ICsJc3RydWN0IHFlZG5faWNyZXFfcGFkZGlu ZyAqaWNyZXFfcGFkOwo+ICsKPiAgIAkvKiAiZHVtbXkiIHNvY2tldCAqLwo+ICAgCXN0cnVjdCBz b2NrZXQgKnNvY2s7Cj4gICB9Owo+IEBAIC0zMzcsNiArMzY5LDcgQEAgZW51bSBxZWRuX2Nvbm5f cmVzb3VyY2VzX3N0YXRlIHsKPiAgIAlRRUROX0NPTk5fUkVTUkNfRldfU1EsCj4gICAJUUVETl9D T05OX1JFU1JDX0FDUVVJUkVfQ09OTiwKPiAgIAlRRUROX0NPTk5fUkVTUkNfVEFTS1MsCj4gKwlR RUROX0NPTk5fUkVTUkNfSUNSRVFfUEFELAo+ICAgCVFFRE5fQ09OTl9SRVNSQ19DQ0NJRF9JVElE X01BUCwKPiAgIAlRRUROX0NPTk5fUkVTUkNfVENQX1BPUlQsCj4gICAJUUVETl9DT05OX1JFU1JD X01BWCA9IDY0Cj4gQEAgLTM3NSw1ICs0MDgsOCBAQCB2b2lkIHFlZG5fY29tbW9uX2NsZWFyX2Z3 X3NnbChzdHJ1Y3Qgc3RvcmFnZV9zZ2xfdGFza19wYXJhbXMgKnNnbF90YXNrX3BhcmFtcyk7Cj4g ICB2b2lkIHFlZG5fcmV0dXJuX2FjdGl2ZV90YXNrcyhzdHJ1Y3QgcWVkbl9jb25uX2N0eCAqY29u bl9jdHgpOwo+ICAgdm9pZCBxZWRuX2Rlc3Ryb3lfZnJlZV90YXNrcyhzdHJ1Y3QgcWVkbl9mcF9x dWV1ZSAqZnBfcSwKPiAgIAkJCSAgICAgc3RydWN0IHFlZG5faW9fcmVzb3VyY2VzICppb19yZXNy Yyk7Cj4gK3ZvaWQgcWVkbl9zd2FwX2J5dGVzKHUzMiAqcCwgaW50IHNpemUpOwo+ICt2b2lkIHFl ZG5fcHJlcF9pY3Jlc3Aoc3RydWN0IHFlZG5fY29ubl9jdHggKmNvbm5fY3R4LCBzdHJ1Y3QgbnZt ZXRjcF9md19jcWUgKmNxZSk7Cj4gK3ZvaWQgcWVkbl9yaW5nX2Rvb3JiZWxsKHN0cnVjdCBxZWRu X2Nvbm5fY3R4ICpjb25uX2N0eCk7Cj4gICAKPiAgICNlbmRpZiAvKiBfUUVETl9IXyAqLwo+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL252bWUvaHcvcWVkbi9xZWRuX2Nvbm4uYyBiL2RyaXZlcnMvbnZt ZS9ody9xZWRuL3FlZG5fY29ubi5jCj4gaW5kZXggMTBhODBmYmVhYzQzLi41Njc5MzU0YWEwZTAg MTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9udm1lL2h3L3FlZG4vcWVkbl9jb25uLmMKPiArKysgYi9k cml2ZXJzL252bWUvaHcvcWVkbi9xZWRuX2Nvbm4uYwo+IEBAIC0zNCw2ICszNCwyNSBAQCBpbmxp bmUgaW50IHFlZG5fcWlkKHN0cnVjdCBudm1lX3RjcF9vZmxkX3F1ZXVlICpxdWV1ZSkKPiAgIAly ZXR1cm4gcXVldWUgLSBxdWV1ZS0+Y3RybC0+cXVldWVzOwo+ICAgfQo+ICAgCj4gK3ZvaWQgcWVk bl9yaW5nX2Rvb3JiZWxsKHN0cnVjdCBxZWRuX2Nvbm5fY3R4ICpjb25uX2N0eCkKPiArewo+ICsJ c3RydWN0IG52bWV0Y3BfZGJfZGF0YSBkYmVsbCA9IHsgMCB9Owo+ICsJdTE2IHByb2RfaWR4Owo+ ICsKPiArCWRiZWxsLmFnZ19mbGFncyA9IDA7Cj4gKwlkYmVsbC5wYXJhbXMgfD0gREJfREVTVF9Y Q00gPDwgTlZNRVRDUF9EQl9EQVRBX0RFU1RfU0hJRlQ7Cj4gKwlkYmVsbC5wYXJhbXMgfD0gREJf QUdHX0NNRF9TRVQgPDwgTlZNRVRDUF9EQl9EQVRBX0FHR19DTURfU0hJRlQ7Cj4gKwlkYmVsbC5w YXJhbXMgfD0KPiArCQlEUV9YQ01fSVNDU0lfU1FfUFJPRF9DTUQgPDwgTlZNRVRDUF9EQl9EQVRB X0FHR19WQUxfU0VMX1NISUZUOwo+ICsJZGJlbGwucGFyYW1zIHw9IDEgPDwgTlZNRVRDUF9EQl9E QVRBX0JZUEFTU19FTl9TSElGVDsKPiArCXByb2RfaWR4ID0gcWVkX2NoYWluX2dldF9wcm9kX2lk eCgmY29ubl9jdHgtPmVwLmZ3X3NxX2NoYWluKTsKPiArCWRiZWxsLnNxX3Byb2QgPSBjcHVfdG9f bGUxNihwcm9kX2lkeCk7Cj4gKwo+ICsJLyogd21iIC0gTWFrZSBzdXJlIGZ3IGlkeCBpcyBjb2hl cmVudCAqLwo+ICsJd21iKCk7Cj4gKwl3cml0ZWwoKih1MzIgKikmZGJlbGwsIGNvbm5fY3R4LT5l cC5wX2Rvb3JiZWxsKTsKPiArfQo+ICsKPiAgIGludCBxZWRuX3NldF9jb25fc3RhdGUoc3RydWN0 IHFlZG5fY29ubl9jdHggKmNvbm5fY3R4LCBlbnVtIHFlZG5fY29ubl9zdGF0ZSBuZXdfc3RhdGUp Cj4gICB7Cj4gICAJc3Bpbl9sb2NrX2JoKCZjb25uX2N0eC0+Y29ubl9zdGF0ZV9sb2NrKTsKPiBA QCAtMTMwLDYgKzE0OSw3MSBAQCBpbnQgcWVkbl9pbml0aWFsaXplX2VuZHBvaW50KHN0cnVjdCBx ZWRuX2VuZHBvaW50ICplcCwgdTggKmxvY2FsX21hY19hZGRyLAo+ICAgCXJldHVybiAtMTsKPiAg IH0KPiAgIAo+ICtzdGF0aWMgaW50IHFlZG5fYWxsb2NfaWNyZXFfcGFkKHN0cnVjdCBxZWRuX2Nv bm5fY3R4ICpjb25uX2N0eCkKPiArewo+ICsJc3RydWN0IHFlZG5fY3R4ICpxZWRuID0gY29ubl9j dHgtPnFlZG47Cj4gKwlzdHJ1Y3QgcWVkbl9pY3JlcV9wYWRkaW5nICppY3JlcV9wYWQ7Cj4gKwl1 MzIgKmJ1ZmZlcjsKPiArCWludCByYyA9IDA7Cj4gKwo+ICsJaWNyZXFfcGFkID0ga3phbGxvYyhz aXplb2YoKmljcmVxX3BhZCksIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFpY3JlcV9wYWQpCj4gKwkJ cmV0dXJuIC1FTk9NRU07Cj4gKwo+ICsJY29ubl9jdHgtPmljcmVxX3BhZCA9IGljcmVxX3BhZDsK PiArCW1lbXNldCgmaWNyZXFfcGFkLT5zZ2UsIDAsIHNpemVvZihpY3JlcV9wYWQtPnNnZSkpOwo+ ICsJYnVmZmVyID0gZG1hX2FsbG9jX2NvaGVyZW50KCZxZWRuLT5wZGV2LT5kZXYsCj4gKwkJCQkg ICAgUUVETl9JQ1JFUV9GV19QQVlMT0FELAo+ICsJCQkJICAgICZpY3JlcV9wYWQtPnBhLAo+ICsJ CQkJICAgIEdGUF9LRVJORUwpOwo+ICsJaWYgKCFidWZmZXIpIHsKPiArCQlwcl9lcnIoIkNvdWxk IG5vdCBhbGxvY2F0ZSBpY3JlcV9wYWRkaW5nIFNHRSBidWZmZXIuXG4iKTsKPiArCQlyYyA9ICAt RU5PTUVNOwo+ICsJCWdvdG8gcmVsZWFzZV9pY3JlcV9wYWQ7Cj4gKwl9Cj4gKwo+ICsJRE1BX1JF R1BBSVJfTEUoaWNyZXFfcGFkLT5zZ2Uuc2dlX2FkZHIsIGljcmVxX3BhZC0+cGEpOwo+ICsJaWNy ZXFfcGFkLT5zZ2Uuc2dlX2xlbiA9IGNwdV90b19sZTMyKFFFRE5fSUNSRVFfRldfUEFZTE9BRCk7 Cj4gKwlpY3JlcV9wYWQtPmJ1ZmZlciA9IGJ1ZmZlcjsKPiArCXNldF9iaXQoUUVETl9DT05OX1JF U1JDX0lDUkVRX1BBRCwgJmNvbm5fY3R4LT5yZXNyY19zdGF0ZSk7Cj4gKwo+ICsJcmV0dXJuIDA7 Cj4gKwo+ICtyZWxlYXNlX2ljcmVxX3BhZDoKPiArCWtmcmVlKGljcmVxX3BhZCk7Cj4gKwljb25u X2N0eC0+aWNyZXFfcGFkID0gTlVMTDsKPiArCj4gKwlyZXR1cm4gcmM7Cj4gK30KPiArCj4gK3N0 YXRpYyB2b2lkIHFlZG5fZnJlZV9pY3JlcV9wYWQoc3RydWN0IHFlZG5fY29ubl9jdHggKmNvbm5f Y3R4KQo+ICt7Cj4gKwlzdHJ1Y3QgcWVkbl9jdHggKnFlZG4gPSBjb25uX2N0eC0+cWVkbjsKPiAr CXN0cnVjdCBxZWRuX2ljcmVxX3BhZGRpbmcgKmljcmVxX3BhZDsKPiArCXUzMiAqYnVmZmVyOwo+ ICsKPiArCWljcmVxX3BhZCA9IGNvbm5fY3R4LT5pY3JlcV9wYWQ7Cj4gKwlpZiAodW5saWtlbHko IWljcmVxX3BhZCkpIHsKPiArCQlwcl9lcnIoIm51bGwgcHRyIGluIGljcmVxX3BhZCBpbiBjb25u X2N0eFxuIik7Cj4gKwkJZ290byBmaW5hbGx5Owo+ICsJfQo+ICsKPiArCWJ1ZmZlciA9IGljcmVx X3BhZC0+YnVmZmVyOwo+ICsJaWYgKGJ1ZmZlcikgewo+ICsJCWRtYV9mcmVlX2NvaGVyZW50KCZx ZWRuLT5wZGV2LT5kZXYsCj4gKwkJCQkgIFFFRE5fSUNSRVFfRldfUEFZTE9BRCwKPiArCQkJCSAg KHZvaWQgKilidWZmZXIsCj4gKwkJCQkgIGljcmVxX3BhZC0+cGEpOwo+ICsJCWljcmVxX3BhZC0+ YnVmZmVyID0gTlVMTDsKPiArCX0KPiArCj4gKwlrZnJlZShpY3JlcV9wYWQpOwo+ICsJY29ubl9j dHgtPmljcmVxX3BhZCA9IE5VTEw7Cj4gKwo+ICtmaW5hbGx5Ogo+ICsJY2xlYXJfYml0KFFFRE5f Q09OTl9SRVNSQ19JQ1JFUV9QQUQsICZjb25uX2N0eC0+cmVzcmNfc3RhdGUpOwo+ICt9Cj4gKwo+ ICAgc3RhdGljIHZvaWQgcWVkbl9yZWxlYXNlX2Nvbm5fY3R4KHN0cnVjdCBxZWRuX2Nvbm5fY3R4 ICpjb25uX2N0eCkKPiAgIHsKPiAgIAlzdHJ1Y3QgcWVkbl9jdHggKnFlZG4gPSBjb25uX2N0eC0+ cWVkbjsKPiBAQCAtMTUxLDYgKzIzNSw5IEBAIHN0YXRpYyB2b2lkIHFlZG5fcmVsZWFzZV9jb25u X2N0eChzdHJ1Y3QgcWVkbl9jb25uX2N0eCAqY29ubl9jdHgpCj4gICAJCWNsZWFyX2JpdChRRURO X0NPTk5fUkVTUkNfQUNRVUlSRV9DT05OLCAmY29ubl9jdHgtPnJlc3JjX3N0YXRlKTsKPiAgIAl9 Cj4gICAKPiArCWlmICh0ZXN0X2JpdChRRUROX0NPTk5fUkVTUkNfSUNSRVFfUEFELCAmY29ubl9j dHgtPnJlc3JjX3N0YXRlKSkKPiArCQlxZWRuX2ZyZWVfaWNyZXFfcGFkKGNvbm5fY3R4KTsKPiAr Cj4gICAJaWYgKHRlc3RfYml0KFFFRE5fQ09OTl9SRVNSQ19UQVNLUywgJmNvbm5fY3R4LT5yZXNy Y19zdGF0ZSkpIHsKPiAgIAkJY2xlYXJfYml0KFFFRE5fQ09OTl9SRVNSQ19UQVNLUywgJmNvbm5f Y3R4LT5yZXNyY19zdGF0ZSk7Cj4gICAJCQlxZWRuX3JldHVybl9hY3RpdmVfdGFza3MoY29ubl9j dHgpOwo+IEBAIC0zMDksNiArMzk2LDE5NCBAQCB2b2lkIHFlZG5fdGVybWluYXRlX2Nvbm5lY3Rp b24oc3RydWN0IHFlZG5fY29ubl9jdHggKmNvbm5fY3R4LCBpbnQgYWJydF9mbGFnKQo+ICAgCXF1 ZXVlX3dvcmsocWN0cmwtPnNwX3dxLCAmY29ubl9jdHgtPnNwX3dxX2VudHJ5KTsKPiAgIH0KPiAg IAo+ICtzdGF0aWMgaW50IHFlZG5fbnZtZXRjcF91cGRhdGVfY29ubihzdHJ1Y3QgcWVkbl9jdHgg KnFlZG4sIHN0cnVjdCBxZWRuX2Nvbm5fY3R4ICpjb25uX2N0eCkKPiArewo+ICsJc3RydWN0IHFl ZG5fbmVnb3RpYXRpb25fcGFyYW1zICpwZHVfcGFyYW1zID0gJmNvbm5fY3R4LT5wZHVfcGFyYW1z Owo+ICsJc3RydWN0IHFlZF9udm1ldGNwX3BhcmFtc191cGRhdGUgKmNvbm5faW5mbzsKPiArCWlu dCByYzsKPiArCj4gKwljb25uX2luZm8gPSBremFsbG9jKHNpemVvZigqY29ubl9pbmZvKSwgR0ZQ X0tFUk5FTCk7Cj4gKwlpZiAoIWNvbm5faW5mbykKPiArCQlyZXR1cm4gLUVOT01FTTsKPiArCj4g Kwljb25uX2luZm8tPmhkcl9kaWdlc3RfZW4gPSBwZHVfcGFyYW1zLT5oZHJfZGlnZXN0Owo+ICsJ Y29ubl9pbmZvLT5kYXRhX2RpZ2VzdF9lbiA9IHBkdV9wYXJhbXMtPmRhdGFfZGlnZXN0Owo+ICsJ Y29ubl9pbmZvLT5tYXhfcmVjdl9wZHVfbGVuZ3RoID0gUUVETl9NQVhfUERVX1NJWkU7Cj4gKwlj b25uX2luZm8tPm1heF9pb19zaXplID0gUUVETl9NQVhfSU9fU0laRTsKPiArCWNvbm5faW5mby0+ bWF4X3NlbmRfcGR1X2xlbmd0aCA9IHBkdV9wYXJhbXMtPm1heGgyY2RhdGE7Cj4gKwo+ICsJcmMg PSBxZWRfb3BzLT51cGRhdGVfY29ubihxZWRuLT5jZGV2LCBjb25uX2N0eC0+Y29ubl9oYW5kbGUs IGNvbm5faW5mbyk7Cj4gKwlpZiAocmMpIHsKPiArCQlwcl9lcnIoIkNvdWxkIG5vdCB1cGRhdGUg Y29ubmVjdGlvblxuIik7Cj4gKwkJcmMgPSAtRU5YSU87Cj4gKwl9Cj4gKwo+ICsJa2ZyZWUoY29u bl9pbmZvKTsKPiArCj4gKwlyZXR1cm4gcmM7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgcWVkbl91 cGRhdGVfcmFtcm9kKHN0cnVjdCBxZWRuX2Nvbm5fY3R4ICpjb25uX2N0eCkKPiArewo+ICsJc3Ry dWN0IHFlZG5fY3R4ICpxZWRuID0gY29ubl9jdHgtPnFlZG47Cj4gKwlpbnQgcmMgPSAwOwo+ICsK PiArCXJjID0gcWVkbl9zZXRfY29uX3N0YXRlKGNvbm5fY3R4LCBDT05OX1NUQVRFX1dBSVRfRk9S X1VQREFURV9FUUUpOwo+ICsJaWYgKHJjKQo+ICsJCXJldHVybiByYzsKPiArCj4gKwlyYyA9IHFl ZG5fbnZtZXRjcF91cGRhdGVfY29ubihxZWRuLCBjb25uX2N0eCk7Cj4gKwlpZiAocmMpCj4gKwkJ cmV0dXJuIHJjOwo+ICsKPiArCWlmIChjb25uX2N0eC0+c3RhdGUgIT0gQ09OTl9TVEFURV9XQUlU X0ZPUl9VUERBVEVfRVFFKSB7Cj4gKwkJcHJfZXJyKCJjaWQgMHgleDogVW5leHBlY3RlZCBzdGF0 ZSAweCV4IGFmdGVyIHVwZGF0ZSByYW1yb2RcbiIsCj4gKwkJICAgICAgIGNvbm5fY3R4LT5md19j aWQsIGNvbm5fY3R4LT5zdGF0ZSk7Cj4gKwo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsJfQo+ICsK PiArCXJldHVybiByYzsKPiArfQo+ICsKPiArc3RhdGljIGludCBxZWRuX3NlbmRfaWNyZXEoc3Ry dWN0IHFlZG5fY29ubl9jdHggKmNvbm5fY3R4KQo+ICt7Cj4gKwlzdHJ1Y3QgbnZtZXRjcF9pbml0 X2Nvbm5fcmVxX2hkciAqaWNyZXFfcHRyID0gTlVMTDsKPiArCXN0cnVjdCBzdG9yYWdlX3NnbF90 YXNrX3BhcmFtcyAqc2dsX3Rhc2tfcGFyYW1zOwo+ICsJc3RydWN0IG52bWV0Y3BfdGFza19wYXJh bXMgdGFza19wYXJhbXM7Cj4gKwlzdHJ1Y3QgcWVkbl90YXNrX2N0eCAqcWVkbl90YXNrID0gTlVM TDsKPiArCXN0cnVjdCBudm1lX3RjcF9pY3JlcV9wZHUgaWNyZXE7Cj4gKwlzdHJ1Y3QgbnZtZXRj cF93cWUgKmNoYWluX3NxZTsKPiArCXN0cnVjdCBudm1ldGNwX3dxZSBsb2NhbF9zcWU7Cj4gKwo+ ICsJcWVkbl90YXNrID0gcWVkbl9nZXRfdGFza19mcm9tX3Bvb2xfaW5zaXN0KGNvbm5fY3R4LCBR RUROX0lDUkVRX0NDQ0lEKTsKPiArCWlmICghcWVkbl90YXNrKQo+ICsJCXJldHVybiAtRUlOVkFM Owo+ICsKPiArCW1lbXNldCgmaWNyZXEsIDAsIHNpemVvZihpY3JlcSkpOwo+ICsJbWVtc2V0KCZs b2NhbF9zcWUsIDAsIHNpemVvZihsb2NhbF9zcWUpKTsKPiArCj4gKwkvKiBJbml0aWFsaXplIElD UmVxICovCj4gKwlpY3JlcS5oZHIudHlwZSA9IG52bWVfdGNwX2ljcmVxOwo+ICsJaWNyZXEuaGRy LmhsZW4gPSBzaXplb2YoaWNyZXEpOwo+ICsJaWNyZXEuaGRyLnBkbyA9IDA7Cj4gKwlpY3JlcS5o ZHIucGxlbiA9IGNwdV90b19sZTMyKGljcmVxLmhkci5obGVuKTsKPiArCWljcmVxLnBmdiA9IGNw dV90b19sZTE2KGNvbm5fY3R4LT5yZXF1aXJlZF9wYXJhbXMucGZ2KTsKPiArCWljcmVxLm1heHIy dCA9IGNwdV90b19sZTMyKGNvbm5fY3R4LT5yZXF1aXJlZF9wYXJhbXMubWF4cjJ0KTsKPiArCWlj cmVxLmhwZGEgPSBjb25uX2N0eC0+cmVxdWlyZWRfcGFyYW1zLmhwZGE7Cj4gKwlpZiAoY29ubl9j dHgtPnJlcXVpcmVkX3BhcmFtcy5oZHJfZGlnZXN0KQo+ICsJCWljcmVxLmRpZ2VzdCB8PSBOVk1F X1RDUF9IRFJfRElHRVNUX0VOQUJMRTsKPiArCWlmIChjb25uX2N0eC0+cmVxdWlyZWRfcGFyYW1z LmRhdGFfZGlnZXN0KQo+ICsJCWljcmVxLmRpZ2VzdCB8PSBOVk1FX1RDUF9EQVRBX0RJR0VTVF9F TkFCTEU7Cj4gKwo+ICsJcWVkbl9zd2FwX2J5dGVzKCh1MzIgKikmaWNyZXEsCj4gKwkJCShzaXpl b2YoaWNyZXEpIC0gUUVETl9JQ1JFUV9GV19QQVlMT0FEKSAvCj4gKwkJCSBzaXplb2YodTMyKSk7 Cj4gKwo+ICsJLyogSW5pdGlhbGl6ZSB0YXNrIHBhcmFtcyAqLwo+ICsJdGFza19wYXJhbXMub3Bx LmxvID0gY3B1X3RvX2xlMzIoKCh1NjQpKHFlZG5fdGFzaykpICYgMHhmZmZmZmZmZik7Cj4gKwl0 YXNrX3BhcmFtcy5vcHEuaGkgPSBjcHVfdG9fbGUzMigoKHU2NCkocWVkbl90YXNrKSkgPj4gMzIp Owo+ICsJdGFza19wYXJhbXMuY29udGV4dCA9IHFlZG5fdGFzay0+ZndfdGFza19jdHg7Cj4gKwl0 YXNrX3BhcmFtcy5zcWUgPSAmbG9jYWxfc3FlOwo+ICsJdGFza19wYXJhbXMuY29ubl9pY2lkID0g KHUxNiljb25uX2N0eC0+Y29ubl9oYW5kbGU7Cj4gKwl0YXNrX3BhcmFtcy5pdGlkID0gcWVkbl90 YXNrLT5pdGlkOwo+ICsJdGFza19wYXJhbXMuY3FfcnNzX251bWJlciA9IGNvbm5fY3R4LT5kZWZh dWx0X2NxOwo+ICsJdGFza19wYXJhbXMudHhfaW9fc2l6ZSA9IFFFRE5fSUNSRVFfRldfUEFZTE9B RDsKPiArCXRhc2tfcGFyYW1zLnJ4X2lvX3NpemUgPSAwOyAvKiBSeCBkb2Vzbid0IHVzZSBTR0wg Zm9yIGljcmVzcCAqLwo+ICsKPiArCS8qIEluaXQgU0dFIGZvciBJQ1JlcSBwYWRkaW5nICovCj4g KwlzZ2xfdGFza19wYXJhbXMgPSAmcWVkbl90YXNrLT5zZ2xfdGFza19wYXJhbXM7Cj4gKwlzZ2xf dGFza19wYXJhbXMtPnRvdGFsX2J1ZmZlcl9zaXplID0gdGFza19wYXJhbXMudHhfaW9fc2l6ZTsK PiArCXNnbF90YXNrX3BhcmFtcy0+c21hbGxfbWlkX3NnZSA9IGZhbHNlOwo+ICsJc2dsX3Rhc2tf cGFyYW1zLT5udW1fc2dlcyA9IDE7Cj4gKwltZW1jcHkoc2dsX3Rhc2tfcGFyYW1zLT5zZ2wsICZj b25uX2N0eC0+aWNyZXFfcGFkLT5zZ2UsCj4gKwkgICAgICAgc2l6ZW9mKGNvbm5fY3R4LT5pY3Jl cV9wYWQtPnNnZSkpOwo+ICsJaWNyZXFfcHRyID0gKHN0cnVjdCBudm1ldGNwX2luaXRfY29ubl9y ZXFfaGRyICopJmljcmVxOwo+ICsKPiArCXFlZF9vcHMtPmluaXRfaWNyZXFfZXhjaGFuZ2UoJnRh c2tfcGFyYW1zLCBpY3JlcV9wdHIsIHNnbF90YXNrX3BhcmFtcywgIE5VTEwpOwo+ICsKPiArCXFl ZG5fc2V0X2Nvbl9zdGF0ZShjb25uX2N0eCwgQ09OTl9TVEFURV9XQUlUX0ZPUl9JQ19DT01QKTsK PiArCWF0b21pY19pbmMoJmNvbm5fY3R4LT5udW1fYWN0aXZlX2Z3X3Rhc2tzKTsKPiArCj4gKwkv KiBzcGluX2xvY2sgLSBkb29yYmVsbCBpcyBhY2Nlc3NlZCAgYm90aCBSeCBmbG93IGFuZCByZXNw b25zZSBmbG93ICovCj4gKwlzcGluX2xvY2soJmNvbm5fY3R4LT5lcC5kb29yYmVsbF9sb2NrKTsK PiArCWNoYWluX3NxZSA9IHFlZF9jaGFpbl9wcm9kdWNlKCZjb25uX2N0eC0+ZXAuZndfc3FfY2hh aW4pOwo+ICsJbWVtY3B5KGNoYWluX3NxZSwgJmxvY2FsX3NxZSwgc2l6ZW9mKGxvY2FsX3NxZSkp Owo+ICsJcWVkbl9yaW5nX2Rvb3JiZWxsKGNvbm5fY3R4KTsKPiArCXNwaW5fdW5sb2NrKCZjb25u X2N0eC0+ZXAuZG9vcmJlbGxfbG9jayk7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCgpBbmQg dGhpcyBpcyB3aGF0IEkgbWVhbnQuIFlvdSBfZG9fIHN3YWIgYnl0ZXMgYmVmb3JlIHNlbmRpbmcg aXQgb2ZmIHRvIAp0aGUgSFcsIF9hbmRfIHlvdSB1c2UgdGhlIHN0YW5kYXJkIG52bWUtdGNwIFBE VSBkZWZpbml0aW9ucy4KU28gd2h5IGRvIHlvdSBoYXZlIHlvdXIgb3duLCBieXRlLXN3YXBwZWQg dmVyc2lvbnMgb2YgdGhlIFBEVXM/Cgo+ICt2b2lkIHFlZG5fcHJlcF9pY3Jlc3Aoc3RydWN0IHFl ZG5fY29ubl9jdHggKmNvbm5fY3R4LCBzdHJ1Y3QgbnZtZXRjcF9md19jcWUgKmNxZSkKPiArewo+ ICsJc3RydWN0IG52bWV0Y3BfaWNyZXNwX2hkcl9wc2ggKmljcmVzcF9mcm9tX2NxZSA9Cj4gKwkJ KHN0cnVjdCBudm1ldGNwX2ljcmVzcF9oZHJfcHNoICopJmNxZS0+bnZtZV9jcWU7Cj4gKwlzdHJ1 Y3QgbnZtZV90Y3Bfb2ZsZF9jdHJsICpjdHJsID0gY29ubl9jdHgtPmN0cmw7Cj4gKwlzdHJ1Y3Qg cWVkbl9jdHJsICpxY3RybCA9IE5VTEw7Cj4gKwo+ICsJcWN0cmwgPSAoc3RydWN0IHFlZG5fY3Ry bCAqKWN0cmwtPnByaXZhdGVfZGF0YTsKPiArCj4gKwltZW1jcHkoJmNvbm5fY3R4LT5pY3Jlc3As IGljcmVzcF9mcm9tX2NxZSwgc2l6ZW9mKGNvbm5fY3R4LT5pY3Jlc3ApKTsKPiArCXFlZG5fc2V0 X3NwX3dhKGNvbm5fY3R4LCBIQU5ETEVfSUNSRVNQKTsKPiArCXF1ZXVlX3dvcmsocWN0cmwtPnNw X3dxLCAmY29ubl9jdHgtPnNwX3dxX2VudHJ5KTsKPiArfQo+ICsKPiArc3RhdGljIGludCBxZWRu X2hhbmRsZV9pY3Jlc3Aoc3RydWN0IHFlZG5fY29ubl9jdHggKmNvbm5fY3R4KQo+ICt7Cj4gKwlz dHJ1Y3QgbnZtZXRjcF9pY3Jlc3BfaGRyX3BzaCAqaWNyZXNwID0gJmNvbm5fY3R4LT5pY3Jlc3A7 Cj4gKwl1MTYgcGZ2ID0gX19zd2FiMTYobGUxNl90b19jcHUoaWNyZXNwLT5wZnZfc3dhcHBlZCkp Owo+ICsJaW50IHJjID0gMDsKPiArCgpBZ2FpbiBoZXJlOyB5b3UgY291bGQgdHJlYXQgdGhlIHJl Y2VpdmVkIGljcmVzcCBhcyBhIGJpbmFyYXkgYmxvYi4gCmJ5dGVzd2FwIGl0LCBhbmQgdGhlbiBj YXN0IGlzIHRvIHRoZSBzdGFuZGFyZCBpY3Jlc3Agc3RydWN0dXJlLgpIbW0/Cgo+ICsJcWVkbl9m cmVlX2ljcmVxX3BhZChjb25uX2N0eCk7Cj4gKwo+ICsJLyogVmFsaWRhdGUgSUNSZXNwICovCj4g KwlpZiAocGZ2ICE9IGNvbm5fY3R4LT5yZXF1aXJlZF9wYXJhbXMucGZ2KSB7Cj4gKwkJcHJfZXJy KCJjaWQgJXU6IHVuc3VwcG9ydGVkIHBmdiAldVxuIiwgY29ubl9jdHgtPmZ3X2NpZCwgcGZ2KTsK PiArCj4gKwkJcmV0dXJuIC1FSU5WQUw7Cj4gKwl9Cj4gKwo+ICsJaWYgKGljcmVzcC0+Y3BkYSA+ IGNvbm5fY3R4LT5yZXF1aXJlZF9wYXJhbXMuY3BkYSkgewo+ICsJCXByX2VycigiY2lkICV1OiB1 bnN1cHBvcnRlZCBjcGRhICV1XG4iLCBjb25uX2N0eC0+ZndfY2lkLCBpY3Jlc3AtPmNwZGEpOwo+ ICsKPiArCQlyZXR1cm4gLUVJTlZBTDsKPiArCX0KPiArCj4gKwlpZiAoKE5WTUVfVENQX0hEUl9E SUdFU1RfRU5BQkxFICYgaWNyZXNwLT5kaWdlc3QpICE9Cj4gKwkgICAgY29ubl9jdHgtPnJlcXVp cmVkX3BhcmFtcy5oZHJfZGlnZXN0KSB7Cj4gKwkJaWYgKChOVk1FX1RDUF9IRFJfRElHRVNUX0VO QUJMRSAmIGljcmVzcC0+ZGlnZXN0KSA+Cj4gKwkJICAgIGNvbm5fY3R4LT5yZXF1aXJlZF9wYXJh bXMuaGRyX2RpZ2VzdCkgewo+ICsJCQlwcl9lcnIoImNpZCAweCV4OiBpbnZhbGlkIGhlYWRlciBk aWdlc3QgYml0XG4iLCBjb25uX2N0eC0+ZndfY2lkKTsKPiArCQl9Cj4gKwl9Cj4gKwo+ICsJaWYg KChOVk1FX1RDUF9EQVRBX0RJR0VTVF9FTkFCTEUgJiBpY3Jlc3AtPmRpZ2VzdCkgIT0KPiArCSAg ICBjb25uX2N0eC0+cmVxdWlyZWRfcGFyYW1zLmRhdGFfZGlnZXN0KSB7Cj4gKwkJaWYgKChOVk1F X1RDUF9EQVRBX0RJR0VTVF9FTkFCTEUgJiBpY3Jlc3AtPmRpZ2VzdCkgPgo+ICsJCSAgICBjb25u X2N0eC0+cmVxdWlyZWRfcGFyYW1zLmRhdGFfZGlnZXN0KSB7Cj4gKwkJCXByX2VycigiY2lkIDB4 JXg6IGludmFsaWQgZGF0YSBkaWdlc3QgYml0XG4iLCBjb25uX2N0eC0+ZndfY2lkKTsKPiArCX0K PiArCX0KPiArCj4gKwltZW1zZXQoJmNvbm5fY3R4LT5wZHVfcGFyYW1zLCAwLCBzaXplb2YoY29u bl9jdHgtPnBkdV9wYXJhbXMpKTsKPiArCWNvbm5fY3R4LT5wZHVfcGFyYW1zLm1heGgyY2RhdGEg PQo+ICsJCV9fc3dhYjMyKGxlMzJfdG9fY3B1KGljcmVzcC0+bWF4ZGF0YV9zd2FwcGVkKSk7Cj4g Kwljb25uX2N0eC0+cGR1X3BhcmFtcy5tYXhoMmNkYXRhID0gUUVETl9NQVhfUERVX1NJWkU7Cj4g KwlpZiAoY29ubl9jdHgtPnBkdV9wYXJhbXMubWF4aDJjZGF0YSA+IFFFRE5fTUFYX1BEVV9TSVpF KQo+ICsJCWNvbm5fY3R4LT5wZHVfcGFyYW1zLm1heGgyY2RhdGEgPSBRRUROX01BWF9QRFVfU0la RTsKPiArCj4gKwljb25uX2N0eC0+cGR1X3BhcmFtcy5wZnYgPSBwZnY7Cj4gKwljb25uX2N0eC0+ cGR1X3BhcmFtcy5jcGRhID0gaWNyZXNwLT5jcGRhOwo+ICsJY29ubl9jdHgtPnBkdV9wYXJhbXMu aHBkYSA9IGNvbm5fY3R4LT5yZXF1aXJlZF9wYXJhbXMuaHBkYTsKPiArCWNvbm5fY3R4LT5wZHVf cGFyYW1zLmhkcl9kaWdlc3QgPSBOVk1FX1RDUF9IRFJfRElHRVNUX0VOQUJMRSAmIGljcmVzcC0+ ZGlnZXN0Owo+ICsJY29ubl9jdHgtPnBkdV9wYXJhbXMuZGF0YV9kaWdlc3QgPSBOVk1FX1RDUF9E QVRBX0RJR0VTVF9FTkFCTEUgJiBpY3Jlc3AtPmRpZ2VzdDsKPiArCWNvbm5fY3R4LT5wZHVfcGFy YW1zLm1heHIydCA9IGNvbm5fY3R4LT5yZXF1aXJlZF9wYXJhbXMubWF4cjJ0Owo+ICsJcmMgPSBx ZWRuX3VwZGF0ZV9yYW1yb2QoY29ubl9jdHgpOwo+ICsKPiArCXJldHVybiByYzsKPiArfQo+ICsK PiAgIC8qIFNsb3dwYXRoIEVRIENhbGxiYWNrICovCj4gICBpbnQgcWVkbl9ldmVudF9jYih2b2lk ICpjb250ZXh0LCB1OCBmd19ldmVudF9jb2RlLCB2b2lkICpldmVudF9yaW5nX2RhdGEpCj4gICB7 Cj4gQEAgLTM2Myw3ICs2MzgsOCBAQCBpbnQgcWVkbl9ldmVudF9jYih2b2lkICpjb250ZXh0LCB1 OCBmd19ldmVudF9jb2RlLCB2b2lkICpldmVudF9yaW5nX2RhdGEpCj4gICAJCQlpZiAocmMpCj4g ICAJCQkJcmV0dXJuIHJjOwo+ICAgCj4gLQkJCS8qIFBsYWNlaG9sZGVyIC0gZm9yIElDUmVxIGZs b3cgKi8KPiArCQkJcWVkbl9zZXRfc3Bfd2EoY29ubl9jdHgsIFNFTkRfSUNSRVEpOwo+ICsJCQlx dWV1ZV93b3JrKHFjdHJsLT5zcF93cSwgJmNvbm5fY3R4LT5zcF93cV9lbnRyeSk7Cj4gICAJCX0K PiAgIAo+ICAgCQlicmVhazsKPiBAQCAtMzk5LDYgKzY3NSw3IEBAIHN0YXRpYyBpbnQgcWVkbl9w cmVwX2FuZF9vZmZsb2FkX3F1ZXVlKHN0cnVjdCBxZWRuX2Nvbm5fY3R4ICpjb25uX2N0eCkKPiAg IAl9Cj4gICAKPiAgIAlzZXRfYml0KFFFRE5fQ09OTl9SRVNSQ19GV19TUSwgJmNvbm5fY3R4LT5y ZXNyY19zdGF0ZSk7Cj4gKwlzcGluX2xvY2tfaW5pdCgmY29ubl9jdHgtPmVwLmRvb3JiZWxsX2xv Y2spOwo+ICAgCUlOSVRfTElTVF9IRUFEKCZjb25uX2N0eC0+aG9zdF9wZW5kX3JlcV9saXN0KTsK PiAgIAlzcGluX2xvY2tfaW5pdCgmY29ubl9jdHgtPm52bWVfcmVxX2xvY2spOwo+ICAgCWF0b21p Y19zZXQoJmNvbm5fY3R4LT5udW1fYWN0aXZlX3Rhc2tzLCAwKTsKPiBAQCAtNDYzLDYgKzc0MCwx MSBAQCBzdGF0aWMgaW50IHFlZG5fcHJlcF9hbmRfb2ZmbG9hZF9xdWV1ZShzdHJ1Y3QgcWVkbl9j b25uX2N0eCAqY29ubl9jdHgpCj4gICAKPiAgIAltZW1zZXQoY29ubl9jdHgtPmhvc3RfY2NjaWRf aXRpZCwgMHhGRiwgZG1hX3NpemUpOwo+ICAgCXNldF9iaXQoUUVETl9DT05OX1JFU1JDX0NDQ0lE X0lUSURfTUFQLCAmY29ubl9jdHgtPnJlc3JjX3N0YXRlKTsKPiArCj4gKwlyYyA9IHFlZG5fYWxs b2NfaWNyZXFfcGFkKGNvbm5fY3R4KTsKPiArCQlpZiAocmMpCj4gKwkJCWdvdG8gcmVsX2Nvbm47 Cj4gKwo+ICAgCXJjID0gcWVkbl9zZXRfY29uX3N0YXRlKGNvbm5fY3R4LCBDT05OX1NUQVRFX1dB SVRfRk9SX0NPTk5FQ1RfRE9ORSk7Cj4gICAJaWYgKHJjKQo+ICAgCQlnb3RvIHJlbF9jb25uOwo+ IEBAIC01MjMsNiArODA1LDkgQEAgdm9pZCBxZWRuX3NwX3dxX2hhbmRsZXIoc3RydWN0IHdvcmtf c3RydWN0ICp3b3JrKQo+ICAgCj4gICAJcWVkbiA9IGNvbm5fY3R4LT5xZWRuOwo+ICAgCWlmICh0 ZXN0X2JpdChERVNUUk9ZX0NPTk5FQ1RJT04sICZjb25uX2N0eC0+YWdnX3dvcmtfYWN0aW9uKSkg ewo+ICsJCWlmICh0ZXN0X2JpdChIQU5ETEVfSUNSRVNQLCAmY29ubl9jdHgtPmFnZ193b3JrX2Fj dGlvbikpCj4gKwkJCXFlZG5fY2xyX3NwX3dhKGNvbm5fY3R4LCBIQU5ETEVfSUNSRVNQKTsKPiAr Cj4gICAJCXFlZG5fZGVzdHJveV9jb25uZWN0aW9uKGNvbm5fY3R4KTsKPiAgIAo+ICAgCQlyZXR1 cm47Cj4gQEAgLTUzNyw2ICs4MjIsMzYgQEAgdm9pZCBxZWRuX3NwX3dxX2hhbmRsZXIoc3RydWN0 IHdvcmtfc3RydWN0ICp3b3JrKQo+ICAgCQkJcmV0dXJuOwo+ICAgCQl9Cj4gICAJfQo+ICsKPiAr CWlmICh0ZXN0X2JpdChTRU5EX0lDUkVRLCAmY29ubl9jdHgtPmFnZ193b3JrX2FjdGlvbikpIHsK PiArCQlxZWRuX2Nscl9zcF93YShjb25uX2N0eCwgU0VORF9JQ1JFUSk7Cj4gKwkJcmMgPSBxZWRu X3NlbmRfaWNyZXEoY29ubl9jdHgpOwo+ICsJCWlmIChyYykKPiArCQkJcmV0dXJuOwo+ICsKPiAr CQlyZXR1cm47Cj4gKwl9Cj4gKwo+ICsJaWYgKHRlc3RfYml0KEhBTkRMRV9JQ1JFU1AsICZjb25u X2N0eC0+YWdnX3dvcmtfYWN0aW9uKSkgewo+ICsJCXJjID0gcWVkbl9oYW5kbGVfaWNyZXNwKGNv bm5fY3R4KTsKPiArCj4gKwkJcWVkbl9jbHJfc3Bfd2EoY29ubl9jdHgsIEhBTkRMRV9JQ1JFU1Ap Owo+ICsJCWlmIChyYykgewo+ICsJCQlwcl9lcnIoIklDIGhhbmRsaW5nIHJldHVybmVkIHdpdGgg MHgleFxuIiwgcmMpOwo+ICsJCQlpZiAodGVzdF9hbmRfc2V0X2JpdChERVNUUk9ZX0NPTk5FQ1RJ T04sICZjb25uX2N0eC0+YWdnX3dvcmtfYWN0aW9uKSkKPiArCQkJCXJldHVybjsKPiArCj4gKwkJ CXFlZG5fZGVzdHJveV9jb25uZWN0aW9uKGNvbm5fY3R4KTsKPiArCj4gKwkJCXJldHVybjsKPiAr CQl9Cj4gKwo+ICsJCWF0b21pY19pbmMoJmNvbm5fY3R4LT5lc3RfY29ubl9pbmRpY2F0b3IpOwo+ ICsJCXFlZG5fc2V0X2Nvbl9zdGF0ZShjb25uX2N0eCwgQ09OTl9TVEFURV9OVk1FVENQX0NPTk5f RVNUQUJMSVNIRUQpOwo+ICsJCXdha2VfdXBfaW50ZXJydXB0aWJsZSgmY29ubl9jdHgtPmNvbm5f d2FpdHEpOwo+ICsKPiArCQlyZXR1cm47Cj4gKwl9Cj4gICB9Cj4gICAKPiAgIC8qIENsZWFyIGNv bm5lY3Rpb24gYWdncmVnYXRpdmUgc2xvd3BhdGggd29yayBhY3Rpb24gKi8KPiBkaWZmIC0tZ2l0 IGEvZHJpdmVycy9udm1lL2h3L3FlZG4vcWVkbl9tYWluLmMgYi9kcml2ZXJzL252bWUvaHcvcWVk bi9xZWRuX21haW4uYwo+IGluZGV4IDhkOWMxOWQ2MzQ4MC4uYTY3NTZkNzI1MGI3IDEwMDY0NAo+ IC0tLSBhL2RyaXZlcnMvbnZtZS9ody9xZWRuL3FlZG5fbWFpbi5jCj4gKysrIGIvZHJpdmVycy9u dm1lL2h3L3FlZG4vcWVkbl9tYWluLmMKPiBAQCAtMjg1LDYgKzI4NSwxOSBAQCBzdGF0aWMgdm9p ZCBxZWRuX3NldF9jdHJsX2lvX2NwdXMoc3RydWN0IHFlZG5fY29ubl9jdHggKmNvbm5fY3R4LCBp bnQgcWlkKQo+ICAgCWNvbm5fY3R4LT5jcHUgPSBmcF9xLT5jcHU7Cj4gICB9Cj4gICAKPiArc3Rh dGljIHZvaWQgcWVkbl9zZXRfcGR1X3BhcmFtcyhzdHJ1Y3QgcWVkbl9jb25uX2N0eCAqY29ubl9j dHgpCj4gK3sKPiArCS8qIEVuYWJsZSBkaWdlc3Qgb25jZSBzdXBwb3J0ZWQgKi8KPiArCWNvbm5f Y3R4LT5yZXF1aXJlZF9wYXJhbXMuaGRyX2RpZ2VzdCA9IDA7Cj4gKwljb25uX2N0eC0+cmVxdWly ZWRfcGFyYW1zLmRhdGFfZGlnZXN0ID0gMDsKPiArCj4gKwljb25uX2N0eC0+cmVxdWlyZWRfcGFy YW1zLm1heHIydCA9IFFFRE5fTUFYX09VVFNUQU5ESU5HX1IyVF9QRFVTOwo+ICsJY29ubl9jdHgt PnJlcXVpcmVkX3BhcmFtcy5wZnYgPSBOVk1FX1RDUF9QRlZfMV8wOwo+ICsJY29ubl9jdHgtPnJl cXVpcmVkX3BhcmFtcy5jcGRhID0gMDsKPiArCWNvbm5fY3R4LT5yZXF1aXJlZF9wYXJhbXMuaHBk YSA9IDA7Cj4gKwljb25uX2N0eC0+cmVxdWlyZWRfcGFyYW1zLm1heGgyY2RhdGEgPSBRRUROX01B WF9QRFVfU0laRTsKPiArfQo+ICsKPiAgIHN0YXRpYyBpbnQgcWVkbl9jcmVhdGVfcXVldWUoc3Ry dWN0IG52bWVfdGNwX29mbGRfcXVldWUgKnF1ZXVlLCBpbnQgcWlkLCBzaXplX3QgcV9zaXplKQo+ ICAgewo+ICAgCXN0cnVjdCBudm1lX3RjcF9vZmxkX2N0cmwgKmN0cmwgPSBxdWV1ZS0+Y3RybDsK PiBAQCAtMzA3LDYgKzMyMCw3IEBAIHN0YXRpYyBpbnQgcWVkbl9jcmVhdGVfcXVldWUoc3RydWN0 IG52bWVfdGNwX29mbGRfcXVldWUgKnF1ZXVlLCBpbnQgcWlkLCBzaXplX3QKPiAgIAljb25uX2N0 eC0+Y3RybCA9IGN0cmw7Cj4gICAJY29ubl9jdHgtPnNxX2RlcHRoID0gcV9zaXplOwo+ICAgCXFl ZG5fc2V0X2N0cmxfaW9fY3B1cyhjb25uX2N0eCwgcWlkKTsKPiArCXFlZG5fc2V0X3BkdV9wYXJh bXMoY29ubl9jdHgpOwo+ICAgCj4gICAJaW5pdF93YWl0cXVldWVfaGVhZCgmY29ubl9jdHgtPmNv bm5fd2FpdHEpOwo+ICAgCWF0b21pY19zZXQoJmNvbm5fY3R4LT5lc3RfY29ubl9pbmRpY2F0b3Is IDApOwo+IEBAIC0xMDczLDYgKzEwODcsMTQgQEAgc3RhdGljIGludCBxZWRuX3Byb2JlKHN0cnVj dCBwY2lfZGV2ICpwZGV2LCBjb25zdCBzdHJ1Y3QgcGNpX2RldmljZV9pZCAqaWQpCj4gICAJcmV0 dXJuIF9fcWVkbl9wcm9iZShwZGV2KTsKPiAgIH0KPiAgIAo+ICt2b2lkIHFlZG5fc3dhcF9ieXRl cyh1MzIgKnAsIGludCBzaXplKQo+ICt7Cj4gKwlpbnQgaTsKPiArCj4gKwlmb3IgKGkgPSAwOyBp IDwgc2l6ZTsgKytpLCArK3ApCj4gKwkJKnAgPSBfX3N3YWIzMigqcCk7Cj4gK30KPiArCj4gICBz dGF0aWMgc3RydWN0IHBjaV9kcml2ZXIgcWVkbl9wY2lfZHJpdmVyID0gewo+ICAgCS5uYW1lICAg ICA9IFFFRE5fTU9EVUxFX05BTUUsCj4gICAJLmlkX3RhYmxlID0gcWVkbl9wY2lfdGJsLAo+IGRp ZmYgLS1naXQgYS9kcml2ZXJzL252bWUvaHcvcWVkbi9xZWRuX3Rhc2suYyBiL2RyaXZlcnMvbnZt ZS9ody9xZWRuL3FlZG5fdGFzay5jCj4gaW5kZXggNTRmMmY0Y2JhNmVhLi45Y2I4NDg4M2U5NWUg MTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9udm1lL2h3L3FlZG4vcWVkbl90YXNrLmMKPiArKysgYi9k cml2ZXJzL252bWUvaHcvcWVkbi9xZWRuX3Rhc2suYwo+IEBAIC01MzYsOSArNTM2LDExIEBAIHZv aWQgcWVkbl9pb193b3JrX2NxKHN0cnVjdCBxZWRuX2N0eCAqcWVkbiwgc3RydWN0IG52bWV0Y3Bf ZndfY3FlICpjcWUpCj4gICAJCQlicmVhazsKPiAgIAo+ICAgCQljYXNlIE5WTUVUQ1BfVEFTS19U WVBFX0lOSVRfQ09OTl9SRVFVRVNUOgo+IC0KPiAtCQkJLyogUGxhY2Vob2xkZXIgLSBJQ1JlcSBm bG93ICovCj4gLQo+ICsJCQkvKiBDbGVhciBJQ1JlcS1wYWRkaW5nIFNHRSBmcm9tIFNHTCAqLwo+ ICsJCQlxZWRuX2NvbW1vbl9jbGVhcl9md19zZ2woJnFlZG5fdGFzay0+c2dsX3Rhc2tfcGFyYW1z KTsKPiArCQkJLyogVGFzayBpcyBub3QgcmVxdWlyZWQgZm9yIGljcmVzcCBwcm9jZXNzaW5nICov Cj4gKwkJCXFlZG5fcmV0dXJuX3Rhc2tfdG9fcG9vbChjb25uX2N0eCwgcWVkbl90YXNrKTsKPiAr CQkJcWVkbl9wcmVwX2ljcmVzcChjb25uX2N0eCwgY3FlKTsKPiAgIAkJCWJyZWFrOwo+ICAgCQlk ZWZhdWx0Ogo+ICAgCQkJcHJfaW5mbygiQ291bGQgbm90IGlkZW50aWZ5IHRhc2sgdHlwZVxuIik7 Cj4gCkNoZWVycywKCkhhbm5lcwotLSAKRHIuIEhhbm5lcyBSZWluZWNrZSAgICAgICAgICAgICAg ICBLZXJuZWwgU3RvcmFnZSBBcmNoaXRlY3QKaGFyZUBzdXNlLmRlICAgICAgICAgICAgICAgICAg ICAgICAgICAgICAgKzQ5IDkxMSA3NDA1MyA2ODgKU1VTRSBTb2Z0d2FyZSBTb2x1dGlvbnMgR21i SCwgTWF4ZmVsZHN0ci4gNSwgOTA0MDkgTsO8cm5iZXJnCkhSQiAzNjgwOSAoQUcgTsO8cm5iZXJn KSwgR2VzY2jDpGZ0c2bDvGhyZXI6IEZlbGl4IEltZW5kw7ZyZmZlcgoKX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX18KTGludXgtbnZtZSBtYWlsaW5nIGxpc3QK TGludXgtbnZtZUBsaXN0cy5pbmZyYWRlYWQub3JnCmh0dHA6Ly9saXN0cy5pbmZyYWRlYWQub3Jn L21haWxtYW4vbGlzdGluZm8vbGludXgtbnZtZQo=