From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752812AbdLERAh (ORCPT ); Tue, 5 Dec 2017 12:00:37 -0500 Received: from mail-wm0-f68.google.com ([74.125.82.68]:40577 "EHLO mail-wm0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752283AbdLERAb (ORCPT ); Tue, 5 Dec 2017 12:00:31 -0500 X-Google-Smtp-Source: AGs4zMb7bogi6Yg5PoSznI70lu3bRmCgMnoImn9QZ5DGuXrY+gjIzGEBn6r15pvA0dHsmY5JNt6RjQ== Date: Tue, 5 Dec 2017 18:00:25 +0100 From: Daniel Vetter To: Sean Paul Cc: dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, seanpaul@google.com, David Airlie , Joonas Lahtinen , linux-kernel@vger.kernel.org, Rodrigo Vivi , daniel.vetter@intel.com Subject: Re: [PATCH v3 5/9] drm/i915: Add HDCP framework + base implementation Message-ID: <20171205170025.cwd5xgh5yzhhedj4@phenom.ffwll.local> Mail-Followup-To: Sean Paul , dri-devel@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, seanpaul@google.com, David Airlie , Joonas Lahtinen , linux-kernel@vger.kernel.org, Rodrigo Vivi , daniel.vetter@intel.com References: <20171205051513.8603-1-seanpaul@chromium.org> <20171205051513.8603-6-seanpaul@chromium.org> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20171205051513.8603-6-seanpaul@chromium.org> X-Operating-System: Linux phenom 4.13.0-1-amd64 User-Agent: NeoMutt/20170609 (1.8.3) Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Tue, Dec 05, 2017 at 12:15:04AM -0500, Sean Paul wrote: > This patch adds the framework required to add HDCP support to intel > connectors. It implements Aksv loading from fuse, and parts 1/2/3 > of the HDCP authentication scheme. > > Note that without shim implementations, this does not actually implement > HDCP. That will come in subsequent patches. > > Changes in v2: > - Don't open code wait_fors (Chris) > - drm_hdcp.c under MIT license (Daniel) > - Move intel_hdcp_disable() call above ddi_disable (Ram) > - Fix // comments (I wore a cone of shame for 12 hours to atone) (Daniel) > - Justify intel_hdcp_shim with comments (Daniel) > - Fixed async locking issues by adding hdcp_mutex (Daniel) > - Don't alter connector_state in enable/disable (Daniel) > Changes in v3: > - Added hdcp_mutex/hdcp_value to make async reasonable > - Added hdcp_prop_work to separate link checking & property setting > - Added new helper for atomic_check state tracking (Daniel) > - Moved enable/disable into atomic_commit with matching helpers > - Moved intel_hdcp_check_link out of all locks when called from dp > - Bumped up ksv_fifo timeout (noticed failure on one of my dongles) > > Cc: Chris Wilson > Cc: Daniel Vetter > Cc: Ramalingam C > Signed-off-by: Sean Paul > --- > drivers/gpu/drm/i915/Makefile | 1 + > drivers/gpu/drm/i915/i915_reg.h | 83 ++++ > drivers/gpu/drm/i915/intel_atomic.c | 2 + > drivers/gpu/drm/i915/intel_display.c | 14 + > drivers/gpu/drm/i915/intel_drv.h | 88 +++++ > drivers/gpu/drm/i915/intel_hdcp.c | 731 +++++++++++++++++++++++++++++++++++ > 6 files changed, 919 insertions(+) > create mode 100644 drivers/gpu/drm/i915/intel_hdcp.c > > diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile > index 42bc8bd4ff06..3facea4eefdb 100644 > --- a/drivers/gpu/drm/i915/Makefile > +++ b/drivers/gpu/drm/i915/Makefile > @@ -107,6 +107,7 @@ i915-y += intel_audio.o \ > intel_fbc.o \ > intel_fifo_underrun.o \ > intel_frontbuffer.o \ > + intel_hdcp.o \ > intel_hotplug.o \ > intel_modes.o \ > intel_overlay.o \ > diff --git a/drivers/gpu/drm/i915/i915_reg.h b/drivers/gpu/drm/i915/i915_reg.h > index 09bf043c1c2e..2bd2cc8441d4 100644 > --- a/drivers/gpu/drm/i915/i915_reg.h > +++ b/drivers/gpu/drm/i915/i915_reg.h > @@ -8034,6 +8034,7 @@ enum { > #define GEN9_MEM_LATENCY_LEVEL_1_5_SHIFT 8 > #define GEN9_MEM_LATENCY_LEVEL_2_6_SHIFT 16 > #define GEN9_MEM_LATENCY_LEVEL_3_7_SHIFT 24 > +#define SKL_PCODE_LOAD_HDCP_KEYS 0x5 SKL_ prefix feels right here, since this is for skl, kbl, ... only, and doesn't apply to bxt. So not gen9 stuff. > #define SKL_PCODE_CDCLK_CONTROL 0x7 > #define SKL_CDCLK_PREPARE_FOR_CHANGE 0x3 > #define SKL_CDCLK_READY_FOR_CHANGE 0x1 > @@ -8335,6 +8336,88 @@ enum skl_power_gate { > #define SKL_PW_TO_PG(pw) ((pw) - SKL_DISP_PW_1 + SKL_PG1) > #define SKL_FUSE_PG_DIST_STATUS(pg) (1 << (27 - (pg))) > > + > +/* HDCP Key Registers */ > +#define SKL_HDCP_KEY_CONF _MMIO(0x66c00) > +#define SKL_HDCP_AKSV_SEND_TRIGGER BIT(31) > +#define SKL_HDCP_CLEAR_KEYS_TRIGGER BIT(30) > +#define SKL_HDCP_KEY_STATUS _MMIO(0x66c04) > +#define SKL_HDCP_FUSE_IN_PROGRESS BIT(7) > +#define SKL_HDCP_FUSE_ERROR BIT(6) > +#define SKL_HDCP_FUSE_DONE BIT(5) > +#define SKL_HDCP_KEY_LOAD_STATUS BIT(1) > +#define SKL_HDCP_KEY_LOAD_DONE BIT(0) > +#define SKL_HDCP_AKSV_LO _MMIO(0x66c10) > +#define SKL_HDCP_AKSV_HI _MMIO(0x66c14) > + > +/* HDCP Repeater Registers */ > +#define SKL_HDCP_REP_CTL _MMIO(0x66d00) > +#define SKL_HDCP_DDIB_REP_PRESENT BIT(30) > +#define SKL_HDCP_DDIB_REP_PRESENT BIT(30) > +#define SKL_HDCP_DDIA_REP_PRESENT BIT(29) > +#define SKL_HDCP_DDIC_REP_PRESENT BIT(28) > +#define SKL_HDCP_DDID_REP_PRESENT BIT(27) > +#define SKL_HDCP_DDIF_REP_PRESENT BIT(26) > +#define SKL_HDCP_DDIE_REP_PRESENT BIT(25) > +#define SKL_HDCP_DDIB_SHA1_M0 (1 << 20) > +#define SKL_HDCP_DDIA_SHA1_M0 (2 << 20) > +#define SKL_HDCP_DDIC_SHA1_M0 (3 << 20) > +#define SKL_HDCP_DDID_SHA1_M0 (4 << 20) > +#define SKL_HDCP_DDIF_SHA1_M0 (5 << 20) > +#define SKL_HDCP_DDIE_SHA1_M0 (6 << 20) /* Bspec says 5? */ Yeah that's one good wtf :-) > +#define SKL_HDCP_SHA1_BUSY BIT(16) > +#define SKL_HDCP_SHA1_READY BIT(17) > +#define SKL_HDCP_SHA1_COMPLETE BIT(18) > +#define SKL_HDCP_SHA1_V_MATCH BIT(19) > +#define SKL_HDCP_SHA1_TEXT_32 (1 << 1) > +#define SKL_HDCP_SHA1_COMPLETE_HASH (2 << 1) > +#define SKL_HDCP_SHA1_TEXT_24 (4 << 1) > +#define SKL_HDCP_SHA1_TEXT_16 (5 << 1) > +#define SKL_HDCP_SHA1_TEXT_8 (6 << 1) > +#define SKL_HDCP_SHA1_TEXT_0 (7 << 1) > +#define SKL_HDCP_SHA_V_PRIME_H0 _MMIO(0x66d04) > +#define SKL_HDCP_SHA_V_PRIME_H1 _MMIO(0x66d08) > +#define SKL_HDCP_SHA_V_PRIME_H2 _MMIO(0x66d0C) > +#define SKL_HDCP_SHA_V_PRIME_H3 _MMIO(0x66d10) > +#define SKL_HDCP_SHA_V_PRIME_H4 _MMIO(0x66d14) > +#define SKL_HDCP_SHA_V_PRIME(h) _MMIO((0x66d04 + h * 4)) > +#define SKL_HDCP_SHA_TEXT _MMIO(0x66d18) > + > +/* HDCP Auth Registers */ > +#define _SKL_PORTA_HDCP_AUTHENC 0x66800 > +#define _SKL_PORTB_HDCP_AUTHENC 0x66500 > +#define _SKL_PORTC_HDCP_AUTHENC 0x66600 > +#define _SKL_PORTD_HDCP_AUTHENC 0x66700 > +#define _SKL_PORTE_HDCP_AUTHENC 0x66A00 > +#define _SKL_PORTF_HDCP_AUTHENC 0x66900 > +#define _SKL_PORT_HDCP_AUTHENC(port, x) _MMIO(_PICK(port, \ > + _SKL_PORTA_HDCP_AUTHENC, \ > + _SKL_PORTB_HDCP_AUTHENC, \ > + _SKL_PORTC_HDCP_AUTHENC, \ > + _SKL_PORTD_HDCP_AUTHENC, \ > + _SKL_PORTE_HDCP_AUTHENC, \ > + _SKL_PORTF_HDCP_AUTHENC) + x) > +#define SKL_PORT_HDCP_CONF(port) _SKL_PORT_HDCP_AUTHENC(port, 0x0) > +#define SKL_HDCP_CONF_CAPTURE_AN BIT(0) > +#define SKL_HDCP_CONF_AUTH_AND_ENC (BIT(1) | BIT(0)) > +#define SKL_PORT_HDCP_ANINIT(port) _SKL_PORT_HDCP_AUTHENC(port, 0x4) > +#define SKL_PORT_HDCP_ANLO(port) _SKL_PORT_HDCP_AUTHENC(port, 0x8) > +#define SKL_PORT_HDCP_ANHI(port) _SKL_PORT_HDCP_AUTHENC(port, 0xC) > +#define SKL_PORT_HDCP_BKSVLO(port) _SKL_PORT_HDCP_AUTHENC(port, 0x10) > +#define SKL_PORT_HDCP_BKSVHI(port) _SKL_PORT_HDCP_AUTHENC(port, 0x14) > +#define SKL_PORT_HDCP_RPRIME(port) _SKL_PORT_HDCP_AUTHENC(port, 0x18) > +#define SKL_PORT_HDCP_STATUS(port) _SKL_PORT_HDCP_AUTHENC(port, 0x1C) > +#define SKL_HDCP_STATUS_STREAM_A_ENC BIT(31) > +#define SKL_HDCP_STATUS_STREAM_B_ENC BIT(30) > +#define SKL_HDCP_STATUS_STREAM_C_ENC BIT(29) > +#define SKL_HDCP_STATUS_STREAM_D_ENC BIT(28) > +#define SKL_HDCP_STATUS_AUTH BIT(21) > +#define SKL_HDCP_STATUS_ENC BIT(20) > +#define SKL_HDCP_STATUS_RI_MATCH BIT(19) > +#define SKL_HDCP_STATUS_R0_READY BIT(18) > +#define SKL_HDCP_STATUS_AN_READY BIT(17) > +#define SKL_HDCP_STATUS_CIPHER BIT(16) > +#define SKL_HDCP_STATUS_FRAME_CNT(x) ((x >> 8) & 0xff) Except for the SKL+ specific GT mailbox bit all the above registers are generic (except the 3 bits in KEY_STATUS I highlighted). Can you pls sed the entire patch and drop the SKL_ prefix from all of them? I know it's a bit busywork, but given how the bits move around between platforms in funny ways it's good prep for enabling hdcp on more platforms I think. If it's too messy feel free to apply the bikeshed in a follow-up patch. Either way all the above looks correct. > + > /* Per-pipe DDI Function Control */ > #define _TRANS_DDI_FUNC_CTL_A 0x60400 > #define _TRANS_DDI_FUNC_CTL_B 0x61400 > diff --git a/drivers/gpu/drm/i915/intel_atomic.c b/drivers/gpu/drm/i915/intel_atomic.c > index 36d4e635e4ce..d452c327dc1d 100644 > --- a/drivers/gpu/drm/i915/intel_atomic.c > +++ b/drivers/gpu/drm/i915/intel_atomic.c > @@ -110,6 +110,8 @@ int intel_digital_connector_atomic_check(struct drm_connector *conn, > to_intel_digital_connector_state(old_state); > struct drm_crtc_state *crtc_state; > > + intel_hdcp_atomic_check(conn, old_state, new_state); > + > if (!new_state->crtc) > return 0; > > diff --git a/drivers/gpu/drm/i915/intel_display.c b/drivers/gpu/drm/i915/intel_display.c > index 601c23be8264..f45c468abf98 100644 > --- a/drivers/gpu/drm/i915/intel_display.c > +++ b/drivers/gpu/drm/i915/intel_display.c > @@ -12319,6 +12319,8 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) > struct drm_i915_private *dev_priv = to_i915(dev); > struct drm_crtc_state *old_crtc_state, *new_crtc_state; > struct drm_crtc *crtc; > + struct drm_connector_state *old_conn_state, *new_conn_state; > + struct drm_connector *connector; > struct intel_crtc_state *intel_cstate; > u64 put_domains[I915_MAX_PIPES] = {}; > int i; > @@ -12408,9 +12410,17 @@ static void intel_atomic_commit_tail(struct drm_atomic_state *state) > } > } > > + for_each_oldnew_connector_in_state(state, connector, old_conn_state, > + new_conn_state, i) > + intel_hdcp_atomic_pre_commit(connector, old_conn_state, > + new_conn_state); > + > /* Now enable the clocks, plane, pipe, and connectors that we set up. */ > dev_priv->display.update_crtcs(state); > > + for_each_new_connector_in_state(state, connector, new_conn_state, i) > + intel_hdcp_atomic_commit(connector, new_conn_state); Hm, I liked the old place where this was called from ddi enable/disable hooks much better. HDCP very much is a connector thing, leaking that through the entire layer-cake that is atomic to the highest level feels a bit wrong. Why? Filling in after an irc chat with Sean: It's leftovers from an attempt at trying to implement HDCP state changes without a full modeset. Imo that should be undone again to the old version, for a few reasons: - Atomic is damn hard to understand already, leaking a connector thing through all layers makes it worse. And we're probably already over the limit of complexity that can be understood, so making abstractions more leaky needs some real good reasons. - Ville is working on a slightly different approach to allow connectors/encoders to fix up stuff if no modeset happened (new separate callback). This here doesn't align with that plan. > + > /* FIXME: We should call drm_atomic_helper_commit_hw_done() here > * already, but still need the state for the delayed optimization. To > * fix this: > @@ -15322,6 +15332,10 @@ static void intel_hpd_poll_fini(struct drm_device *dev) > for_each_intel_connector_iter(connector, &conn_iter) { > if (connector->modeset_retry_work.func) > cancel_work_sync(&connector->modeset_retry_work); > + if (connector->hdcp_shim) { > + cancel_delayed_work_sync(&connector->hdcp_check_work); > + cancel_work_sync(&connector->hdcp_prop_work); > + } > } > drm_connector_list_iter_end(&conn_iter); > } > diff --git a/drivers/gpu/drm/i915/intel_drv.h b/drivers/gpu/drm/i915/intel_drv.h > index 852b3d161754..6f47a4227f5f 100644 > --- a/drivers/gpu/drm/i915/intel_drv.h > +++ b/drivers/gpu/drm/i915/intel_drv.h > @@ -301,6 +301,76 @@ struct intel_panel { > } backlight; > }; > > +/* > + * This structure serves as a translation layer between the generic HDCP code > + * and the bus-specific code. What that means is that HDCP over HDMI differs > + * from HDCP over DP, so to account for these differences, we need to > + * communicate with the receiver through this shim. > + * > + * For completeness, the 2 buses differ in the following ways: > + * - DP AUX vs. DDC > + * HDCP registers on the receiver are set via DP AUX for DP, and > + * they are set via DDC for HDMI. > + * - Receiver register offsets > + * The offsets of the registers are different for DP vs. HDMI > + * - Receiver register masks/offsets > + * For instance, the ready bit for the KSV fifo is in a different > + * place on DP vs HDMI > + * - Receiver register names > + * Seriously. In the DP spec, the 16-bit register containing > + * downstream information is called BINFO, on HDMI it's called > + * BSTATUS. To confuse matters further, DP has a BSTATUS register > + * with a completely different definition. > + * - KSV FIFO > + * On HDMI, the ksv fifo is read all at once, whereas on DP it must > + * be read 3 keys at a time > + * - Aksv output > + * Since Aksv is hidden in hardware, there's different procedures > + * to send it over DP AUX vs DDC > + */ > +struct intel_hdcp_shim { > + /* Outputs the transmitter's An and Aksv values to the receiver. */ > + int (*write_an_aksv)(struct intel_digital_port *intel_dig_port, u8 *an); > + > + /* Reads the receiver's key selection vector */ > + int (*read_bksv)(struct intel_digital_port *intel_dig_port, u8 *bksv); > + > + /* > + * Reads BINFO from DP receivers and BSTATUS from HDMI receivers. The > + * definitions are the same in the respective specs, but the names are > + * different. Call it BSTATUS since that's the name the HDMI spec > + * uses and it was there first. > + */ > + int (*read_bstatus)(struct intel_digital_port *intel_dig_port, > + u8 *bstatus); > + > + /* Determines whether a repeater is present downstream */ > + int (*repeater_present)(struct intel_digital_port *intel_dig_port, > + bool *repeater_present); > + > + /* Reads the receiver's Ri' value */ > + int (*read_ri_prime)(struct intel_digital_port *intel_dig_port, u8 *ri); > + > + /* Determines if the receiver's KSV FIFO is ready for consumption */ > + int (*read_ksv_ready)(struct intel_digital_port *intel_dig_port, > + bool *ksv_ready); > + > + /* Reads the ksv fifo for num_downstream devices */ > + int (*read_ksv_fifo)(struct intel_digital_port *intel_dig_port, > + int num_downstream, u8 *ksv_fifo); > + > + /* Reads a 32-bit part of V' from the receiver */ > + int (*read_v_prime_part)(struct intel_digital_port *intel_dig_port, > + int i, u32 *part); > + > + /* Enables HDCP signalling on the port */ > + int (*toggle_signalling)(struct intel_digital_port *intel_dig_port, > + bool enable); > + > + /* Ensures the link is still protected */ > + bool (*check_link)(struct intel_digital_port *intel_dig_port); > +}; > + > struct intel_connector { > struct drm_connector base; > /* > @@ -332,6 +402,12 @@ struct intel_connector { > > /* Work struct to schedule a uevent on link train failure */ > struct work_struct modeset_retry_work; > + > + const struct intel_hdcp_shim *hdcp_shim; > + struct mutex hdcp_mutex; > + uint64_t hdcp_value; /* protected by hdcp_mutex */ > + struct delayed_work hdcp_check_work; > + struct work_struct hdcp_prop_work; > }; > > struct intel_digital_connector_state { > @@ -1763,6 +1839,18 @@ static inline void intel_backlight_device_unregister(struct intel_connector *con > } > #endif /* CONFIG_BACKLIGHT_CLASS_DEVICE */ > > +/* intel_hdcp.c */ > +void intel_hdcp_atomic_check(struct drm_connector *connector, > + struct drm_connector_state *old_state, > + struct drm_connector_state *new_state); > +void intel_hdcp_atomic_pre_commit(struct drm_connector *connector, > + struct drm_connector_state *old_state, > + struct drm_connector_state *new_state); > +void intel_hdcp_atomic_commit(struct drm_connector *connector, > + struct drm_connector_state *new_state); > +int intel_hdcp_check_link(struct intel_connector *connector); > +void intel_hdcp_check_work(struct work_struct *work); > +void intel_hdcp_prop_work(struct work_struct *work); > > /* intel_psr.c */ > void intel_psr_enable(struct intel_dp *intel_dp, > diff --git a/drivers/gpu/drm/i915/intel_hdcp.c b/drivers/gpu/drm/i915/intel_hdcp.c > new file mode 100644 > index 000000000000..4eef9505410f > --- /dev/null > +++ b/drivers/gpu/drm/i915/intel_hdcp.c > @@ -0,0 +1,731 @@ > +/* > + * Copyright (C) 2017 Google, Inc. > + * > + * Permission is hereby granted, free of charge, to any person obtaining a > + * copy of this software and associated documentation files (the "Software"), > + * to deal in the Software without restriction, including without limitation > + * the rights to use, copy, modify, merge, publish, distribute, sublicense, > + * and/or sell copies of the Software, and to permit persons to whom the > + * Software is furnished to do so, subject to the following conditions: > + * > + * The above copyright notice and this permission notice shall be included in > + * all copies or substantial portions of the Software. > + * > + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR > + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, > + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL > + * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR > + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, > + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR > + * OTHER DEALINGS IN THE SOFTWARE. > + * > + * Authors: > + * Sean Paul > + */ > + > +#include > +#include > +#include > +#include > + > +#include "intel_drv.h" > +#include "i915_reg.h" > + > +#define KEY_LOAD_TRIES 5 > + > +static int intel_hdcp_poll_ksv_fifo(struct intel_digital_port *intel_dig_port, > + const struct intel_hdcp_shim *shim) > +{ > + int ret, read_ret; > + bool ksv_ready; > + > + ret = __wait_for(read_ret = shim->read_ksv_ready(intel_dig_port, > + &ksv_ready), > + read_ret || ksv_ready, 1500 * 1000, 1000, 100 * 1000); > + if (ret) > + return ret; > + if (read_ret) > + return read_ret; > + if (!ksv_ready) > + return -ETIMEDOUT; > + > + return 0; > +} > + > +static void intel_hdcp_clear_keys(struct drm_i915_private *dev_priv) > +{ > + I915_WRITE(SKL_HDCP_KEY_CONF, SKL_HDCP_CLEAR_KEYS_TRIGGER); > + I915_WRITE(SKL_HDCP_KEY_STATUS, > + SKL_HDCP_KEY_LOAD_DONE | SKL_HDCP_KEY_LOAD_STATUS | > + SKL_HDCP_FUSE_IN_PROGRESS | SKL_HDCP_FUSE_ERROR | > + SKL_HDCP_FUSE_DONE); > +} > + > +static int intel_hdcp_load_keys(struct drm_i915_private *dev_priv) > +{ > + int ret; > + u32 val; > + > + /* Initiate loading the HDCP key from fuses */ > + mutex_lock(&dev_priv->pcu_lock); > + ret = sandybridge_pcode_write(dev_priv, SKL_PCODE_LOAD_HDCP_KEYS, 1); > + mutex_unlock(&dev_priv->pcu_lock); > + if (ret) { > + DRM_ERROR("Failed to initiate HDCP key load (%d)\n", ret); > + return ret; > + } > + > + /* Wait for the keys to load (500us) */ > + ret = __intel_wait_for_register(dev_priv, SKL_HDCP_KEY_STATUS, > + SKL_HDCP_KEY_LOAD_DONE, > + SKL_HDCP_KEY_LOAD_DONE, > + 10, 1, &val); > + if (ret) > + return ret; > + else if (!(val & SKL_HDCP_KEY_LOAD_STATUS)) > + return -ENXIO; > + > + /* Send Aksv over to PCH display for use in authentication */ > + I915_WRITE(SKL_HDCP_KEY_CONF, SKL_HDCP_AKSV_SEND_TRIGGER); > + > + return 0; > +} > + > +/* Returns updated SHA-1 index */ > +static int intel_write_sha_text(struct drm_i915_private *dev_priv, u32 sha_text) > +{ > + I915_WRITE(SKL_HDCP_SHA_TEXT, sha_text); > + if (intel_wait_for_register(dev_priv, SKL_HDCP_REP_CTL, > + SKL_HDCP_SHA1_READY, > + SKL_HDCP_SHA1_READY, 1)) { > + DRM_ERROR("Timed out waiting for SHA1 ready\n"); > + return -ETIMEDOUT; > + } > + return 0; > +} > + > +static > +u32 intel_hdcp_get_repeater_ctl(struct intel_digital_port *intel_dig_port) > +{ > + enum port port = intel_dig_port->base.port; > + switch(port) { > + case PORT_A: > + return SKL_HDCP_DDIA_REP_PRESENT | SKL_HDCP_DDIA_SHA1_M0; > + case PORT_B: > + return SKL_HDCP_DDIB_REP_PRESENT | SKL_HDCP_DDIB_SHA1_M0; > + case PORT_C: > + return SKL_HDCP_DDIC_REP_PRESENT | SKL_HDCP_DDIC_SHA1_M0; > + case PORT_D: > + return SKL_HDCP_DDID_REP_PRESENT | SKL_HDCP_DDID_SHA1_M0; > + case PORT_E: > + return SKL_HDCP_DDIE_REP_PRESENT | SKL_HDCP_DDIE_SHA1_M0; > + default: > + break; > + } > + DRM_ERROR("Unknown port %d\n", port); > + return -EINVAL; > +} > + > +/* Implements Part 2 of the HDCP authorization procedure */ > +static > +int intel_hdcp_auth_downstream(struct intel_digital_port *intel_dig_port, > + const struct intel_hdcp_shim *shim) > +{ > + struct drm_i915_private *dev_priv; > + u32 vprime, sha_text, sha_leftovers, rep_ctl; > + u8 bstatus[2], num_downstream, *ksv_fifo; > + int ret, i, j, sha_idx; > + > + dev_priv = intel_dig_port->base.base.dev->dev_private; > + > + ret = shim->read_bstatus(intel_dig_port, bstatus); > + if (ret) > + return ret; > + > + /* If there are no downstream devices, we're all done. */ > + num_downstream = DRM_HDCP_NUM_DOWNSTREAM(bstatus[0]); > + if (num_downstream == 0) { > + DRM_INFO("HDCP is enabled (no downstream devices)\n"); > + return 0; > + } > + > + /* Poll for ksv list ready (spec says max time allowed is 5s) */ > + ret = intel_hdcp_poll_ksv_fifo(intel_dig_port, shim); > + if (ret) { > + DRM_ERROR("KSV list failed to become ready (%d)\n", ret); > + return ret; > + } > + > + ksv_fifo = kzalloc(num_downstream * DRM_HDCP_KSV_LEN, GFP_KERNEL); > + if (!ksv_fifo) > + return -ENOMEM; > + > + ret = shim->read_ksv_fifo(intel_dig_port, num_downstream, ksv_fifo); > + if (ret) > + return ret; > + > + /* Process V' values from the receiver */ > + for (i = 0; i < DRM_HDCP_V_PRIME_NUM_PARTS; i++) { > + ret = shim->read_v_prime_part(intel_dig_port, i, &vprime); > + if (ret) > + return ret; > + I915_WRITE(SKL_HDCP_SHA_V_PRIME(i), vprime); > + } > + > + /* > + * We need to write the concatenation of all device KSVs, BINFO (DP) || > + * BSTATUS (HDMI), and M0 (which is added via HDCP_REP_CTL). This byte > + * stream is written via the HDCP_SHA_TEXT register in 32-bit > + * increments. Every 64 bytes, we need to write HDCP_REP_CTL again. This > + * index will keep track of our progress through the 64 bytes as well as > + * helping us work the 40-bit KSVs through our 32-bit register. > + * > + * NOTE: data passed via HDCP_SHA_TEXT should be big-endian > + */ > + sha_idx = 0; > + sha_text = 0; > + sha_leftovers = 0; > + rep_ctl = intel_hdcp_get_repeater_ctl(intel_dig_port); > + I915_WRITE(SKL_HDCP_REP_CTL, rep_ctl | SKL_HDCP_SHA1_TEXT_32); > + for (i = 0; i < num_downstream; i++) { > + unsigned sha_empty; > + u8 *ksv = &ksv_fifo[i * DRM_HDCP_KSV_LEN]; > + > + /* Fill up the empty slots in sha_text and write it out */ > + sha_empty = sizeof(sha_text) - sha_leftovers; > + for (j = 0; j < sha_empty; j++) > + sha_text |= ksv[j] << ((sizeof(sha_text) - j - 1) * 8); > + > + ret = intel_write_sha_text(dev_priv, sha_text); > + if (ret < 0) > + return ret; > + > + /* Programming guide writes this every 64 bytes */ > + sha_idx += sizeof(sha_text); > + if (!(sha_idx % 64)) > + I915_WRITE(SKL_HDCP_REP_CTL, > + rep_ctl | SKL_HDCP_SHA1_TEXT_32); > + > + /* Store the leftover bytes from the ksv in sha_text */ > + sha_leftovers = DRM_HDCP_KSV_LEN - sha_empty; > + sha_text = 0; > + for (j = 0; j < sha_leftovers; j++) > + sha_text |= ksv[sha_empty + j] << > + ((sizeof(sha_text) - j - 1) * 8); > + > + /* > + * If we still have room in sha_text for more data, continue. > + * Otherwise, write it out immediately. > + */ > + if (sizeof(sha_text) > sha_leftovers) > + continue; > + > + ret = intel_write_sha_text(dev_priv, sha_text); > + if (ret < 0) > + return ret; > + sha_leftovers = 0; > + sha_text = 0; > + sha_idx += sizeof(sha_text); > + } > + > + /* > + * We need to write BINFO/BSTATUS, and M0 now. Depending on how many > + * bytes are leftover from the last ksv, we might be able to fit them > + * all in sha_text (first 2 cases), or we might need to split them up > + * into 2 writes (last 2 cases). > + */ > + if (sha_leftovers == 0) { > + /* Write 16 bits of text, 16 bits of M0 */ > + I915_WRITE(SKL_HDCP_REP_CTL, rep_ctl | SKL_HDCP_SHA1_TEXT_16); > + ret = intel_write_sha_text(dev_priv, > + bstatus[0] << 8 | bstatus[1]); > + if (ret < 0) > + return ret; > + sha_idx += sizeof(sha_text); > + > + /* Write 32 bits of M0 */ > + I915_WRITE(SKL_HDCP_REP_CTL, rep_ctl | SKL_HDCP_SHA1_TEXT_0); > + ret = intel_write_sha_text(dev_priv, 0); > + if (ret < 0) > + return ret; > + sha_idx += sizeof(sha_text); > + > + /* Write 16 bits of M0 */ > + I915_WRITE(SKL_HDCP_REP_CTL, rep_ctl | SKL_HDCP_SHA1_TEXT_16); > + ret = intel_write_sha_text(dev_priv, 0); > + if (ret < 0) > + return ret; > + sha_idx += sizeof(sha_text); > + > + } else if (sha_leftovers == 1) { > + /* Write 24 bits of text, 8 bits of M0 */ > + I915_WRITE(SKL_HDCP_REP_CTL, rep_ctl | SKL_HDCP_SHA1_TEXT_24); > + sha_text |= bstatus[0] << 16 | bstatus[1] << 8; > + /* Only 24-bits of data, must be in the LSB */ > + sha_text = (sha_text & 0xffffff00) >> 8; > + ret = intel_write_sha_text(dev_priv, sha_text); > + if (ret < 0) > + return ret; > + sha_idx += sizeof(sha_text); > + > + /* Write 32 bits of M0 */ > + I915_WRITE(SKL_HDCP_REP_CTL, rep_ctl | SKL_HDCP_SHA1_TEXT_0); > + ret = intel_write_sha_text(dev_priv, 0); > + if (ret < 0) > + return ret; > + sha_idx += sizeof(sha_text); > + > + /* Write 24 bits of M0 */ > + I915_WRITE(SKL_HDCP_REP_CTL, rep_ctl | SKL_HDCP_SHA1_TEXT_8); > + ret = intel_write_sha_text(dev_priv, 0); > + if (ret < 0) > + return ret; > + sha_idx += sizeof(sha_text); > + > + } else if (sha_leftovers == 2) { > + /* Write 32 bits of text */ > + I915_WRITE(SKL_HDCP_REP_CTL, rep_ctl | SKL_HDCP_SHA1_TEXT_32); > + sha_text |= bstatus[0] << 24 | bstatus[1] << 16; > + ret = intel_write_sha_text(dev_priv, sha_text); > + if (ret < 0) > + return ret; > + sha_idx += sizeof(sha_text); > + > + /* Write 64 bits of M0 */ > + I915_WRITE(SKL_HDCP_REP_CTL, rep_ctl | SKL_HDCP_SHA1_TEXT_0); > + for (i = 0; i < 2; i++) { > + ret = intel_write_sha_text(dev_priv, 0); > + if (ret < 0) > + return ret; > + sha_idx += sizeof(sha_text); > + } > + } else if (sha_leftovers == 3) { > + /* Write 32 bits of text */ > + I915_WRITE(SKL_HDCP_REP_CTL, rep_ctl | SKL_HDCP_SHA1_TEXT_32); > + sha_text |= bstatus[0] << 24; > + ret = intel_write_sha_text(dev_priv, sha_text); > + if (ret < 0) > + return ret; > + sha_idx += sizeof(sha_text); > + > + /* Write 8 bits of text, 24 bits of M0 */ > + I915_WRITE(SKL_HDCP_REP_CTL, rep_ctl | SKL_HDCP_SHA1_TEXT_8); > + ret = intel_write_sha_text(dev_priv, bstatus[1]); > + if (ret < 0) > + return ret; > + sha_idx += sizeof(sha_text); > + > + /* Write 32 bits of M0 */ > + I915_WRITE(SKL_HDCP_REP_CTL, rep_ctl | SKL_HDCP_SHA1_TEXT_0); > + ret = intel_write_sha_text(dev_priv, 0); > + if (ret < 0) > + return ret; > + sha_idx += sizeof(sha_text); > + > + /* Write 8 bits of M0 */ > + I915_WRITE(SKL_HDCP_REP_CTL, rep_ctl | SKL_HDCP_SHA1_TEXT_24); > + ret = intel_write_sha_text(dev_priv, 0); > + if (ret < 0) > + return ret; > + sha_idx += sizeof(sha_text); > + } else { > + DRM_ERROR("Invalid number of leftovers %d\n", sha_leftovers); > + return -EINVAL; > + } I'd have extracted a little helper to write teh sha_text bytewise which internally accumulates it and pushes it out every 32 bytes. Would neatly separate what we write from how the sha machinery works. But this a bit more verbose style works too I guess, so just an idea in case we ever spot a bug in here (I didn't). > + > + I915_WRITE(SKL_HDCP_REP_CTL, rep_ctl | SKL_HDCP_SHA1_TEXT_32); > + /* Fill up to 64-4 bytes with zeros (leave the last write for length) */ > + while ((sha_idx % 64) < (64 - sizeof(sha_text))) { > + ret = intel_write_sha_text(dev_priv, 0); > + if (ret < 0) > + return ret; > + sha_idx += sizeof(sha_text); > + } > + > + /* > + * Last write gets the length of the concatenation in bits. That is: > + * - 5 bytes per device > + * - 10 bytes for BINFO/BSTATUS(2), M0(8) > + */ > + sha_text = (num_downstream * 5 + 10) * 8; > + ret = intel_write_sha_text(dev_priv, sha_text); > + if (ret < 0) > + return ret; > + > + /* Tell the HW we're done with the hash and wait for it to ACK */ > + I915_WRITE(SKL_HDCP_REP_CTL, rep_ctl | SKL_HDCP_SHA1_COMPLETE_HASH); > + if (intel_wait_for_register(dev_priv, SKL_HDCP_REP_CTL, > + SKL_HDCP_SHA1_COMPLETE, > + SKL_HDCP_SHA1_COMPLETE, 1)) { > + DRM_ERROR("Timed out waiting for SHA1 complete\n"); > + return -ETIMEDOUT; > + } > + if (!(I915_READ(SKL_HDCP_REP_CTL) & SKL_HDCP_SHA1_V_MATCH)) { > + DRM_ERROR("SHA-1 mismatch, HDCP failed\n"); > + return -ENXIO; > + } > + > + DRM_INFO("HDCP is enabled (%d downstream devices)\n", num_downstream); > + return 0; > +} > + > +/* Implements Part 1 of the HDCP authorization procedure */ > +static int intel_hdcp_auth(struct intel_digital_port *intel_dig_port, > + const struct intel_hdcp_shim *shim) > +{ > + struct drm_i915_private *dev_priv; > + enum port port; > + unsigned long r0_prime_gen_start; > + int ret, i; > + union { > + u32 reg[2]; > + u8 shim[DRM_HDCP_AN_LEN]; > + } an; > + union { > + u32 reg[2]; > + u8 shim[DRM_HDCP_KSV_LEN]; > + } bksv; > + union { > + u32 reg; > + u8 shim[DRM_HDCP_RI_LEN]; > + } ri; > + bool repeater_present; > + > + dev_priv = intel_dig_port->base.base.dev->dev_private; > + > + port = intel_dig_port->base.port; > + > + /* Initialize An with 2 random values and acquire it */ > + for (i = 0; i < 2; i++) > + I915_WRITE(SKL_PORT_HDCP_ANINIT(port), get_random_long()); nit: get_random_u32 instad of get_random_long? > + I915_WRITE(SKL_PORT_HDCP_CONF(port), SKL_HDCP_CONF_CAPTURE_AN); > + > + /* Wait for An to be acquired */ > + if (intel_wait_for_register(dev_priv, SKL_PORT_HDCP_STATUS(port), > + SKL_HDCP_STATUS_AN_READY, > + SKL_HDCP_STATUS_AN_READY, 1)) { > + DRM_ERROR("Timed out waiting for An\n"); > + return -ETIMEDOUT; > + } > + > + an.reg[0] = I915_READ(SKL_PORT_HDCP_ANLO(port)); > + an.reg[1] = I915_READ(SKL_PORT_HDCP_ANHI(port)); > + ret = shim->write_an_aksv(intel_dig_port, an.shim); > + if (ret) > + return ret; > + > + r0_prime_gen_start = jiffies; > + > + memset(&bksv, 0, sizeof(bksv)); > + ret = shim->read_bksv(intel_dig_port, bksv.shim); > + if (ret) > + return ret; > + > + I915_WRITE(SKL_PORT_HDCP_BKSVLO(port), bksv.reg[0]); > + I915_WRITE(SKL_PORT_HDCP_BKSVHI(port), bksv.reg[1]); > + > + ret = shim->repeater_present(intel_dig_port, &repeater_present); > + if (ret) > + return ret; > + if (repeater_present) > + I915_WRITE(SKL_HDCP_REP_CTL, > + intel_hdcp_get_repeater_ctl(intel_dig_port)); > + > + ret = shim->toggle_signalling(intel_dig_port, true); > + if (ret) > + return ret; > + > + I915_WRITE(SKL_PORT_HDCP_CONF(port), SKL_HDCP_CONF_AUTH_AND_ENC); > + > + /* Wait for R0 ready */ > + if (wait_for(I915_READ(SKL_PORT_HDCP_STATUS(port)) & > + (SKL_HDCP_STATUS_R0_READY | SKL_HDCP_STATUS_ENC), 1)) { > + DRM_ERROR("Timed out waiting for R0 ready\n"); > + return -ETIMEDOUT; > + } > + > + /* > + * Wait for R0' to become available, the spec says 100ms from Aksv > + * write. On DP, there's an R0_READY bit available but no such bit > + * exists on HDMI. Since the upper-bound is the same, we'll just do > + * the stupid thing instead of polling on one and not the other. > + */ > + wait_remaining_ms_from_jiffies(r0_prime_gen_start, 100); > + > + ri.reg = 0; > + ret = shim->read_ri_prime(intel_dig_port, ri.shim); > + if (ret) > + return ret; > + I915_WRITE(SKL_PORT_HDCP_RPRIME(port), ri.reg); > + > + /* Wait for Ri prime match */ > + if (wait_for(I915_READ(SKL_PORT_HDCP_STATUS(port)) & > + (SKL_HDCP_STATUS_RI_MATCH | SKL_HDCP_STATUS_ENC), 1)) { > + DRM_ERROR("Timed out waiting for Ri prime match (%x)\n", > + I915_READ(SKL_PORT_HDCP_STATUS(port))); > + return -ETIMEDOUT; > + } > + > + /* Wait for encryption confirmation */ > + if (intel_wait_for_register(dev_priv, SKL_PORT_HDCP_STATUS(port), > + SKL_HDCP_STATUS_ENC, > + SKL_HDCP_STATUS_ENC, 20)) { > + DRM_ERROR("Timed out waiting for encryption\n"); > + return -ETIMEDOUT; > + } > + > + /* > + * XXX: If we have MST-connected devices, we need to enable encryption > + * on those as well. > + */ Just an aside: I think we can stuff the DDI stream specific stuff into the toggle_signalling callback. But not entirely sure. > + > + return intel_hdcp_auth_downstream(intel_dig_port, shim); > +} > + > +static > +struct intel_digital_port *conn_to_dig_port(struct intel_connector *connector) > +{ > + return enc_to_dig_port(&intel_attached_encoder(&connector->base)->base); > +} > + > +static int _intel_hdcp_disable(struct intel_connector *connector) > +{ > + struct drm_i915_private *dev_priv = connector->base.dev->dev_private; > + struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector); > + enum port port = intel_dig_port->base.port; > + int ret; > + > + I915_WRITE(SKL_PORT_HDCP_CONF(port), 0); > + if (intel_wait_for_register(dev_priv, SKL_PORT_HDCP_STATUS(port), ~0, 0, > + 20)) { > + DRM_ERROR("Failed to disable HDCP, timeout clearing status\n"); > + return -ETIMEDOUT; > + } > + > + intel_hdcp_clear_keys(dev_priv); > + > + ret = connector->hdcp_shim->toggle_signalling(intel_dig_port, false); > + if (ret) { > + DRM_ERROR("Failed to disable HDCP signalling\n"); > + return ret; > + } > + > + DRM_INFO("HDCP is disabled\n"); > + return 0; > +} > + > +static int _intel_hdcp_enable(struct intel_connector *connector) > +{ > + struct drm_i915_private *dev_priv = connector->base.dev->dev_private; > + int i, ret; > + > + if (!(I915_READ(SKL_FUSE_STATUS) & SKL_FUSE_PG_DIST_STATUS(1))) { > + DRM_ERROR("PG1 is disabled, cannot load keys\n"); > + return -ENXIO; > + } > + > + for (i = 0; i < KEY_LOAD_TRIES; i++) { > + ret = intel_hdcp_load_keys(dev_priv); > + if (!ret) > + break; > + intel_hdcp_clear_keys(dev_priv); > + } > + if (ret) { > + DRM_ERROR("Could not load HDCP keys, (%d)\n", ret); > + return ret; > + } > + > + ret = intel_hdcp_auth(conn_to_dig_port(connector), > + connector->hdcp_shim); > + if (ret) { > + DRM_ERROR("Failed to authenticate HDCP (%d)\n", ret); > + return ret; > + } > + > + return 0; > +} > + > +void intel_hdcp_check_work(struct work_struct *work) > +{ > + struct intel_connector *connector = container_of(to_delayed_work(work), > + struct intel_connector, > + hdcp_check_work); > + if (!intel_hdcp_check_link(connector)) > + schedule_delayed_work(&connector->hdcp_check_work, > + DRM_HDCP_CHECK_PERIOD_MS); > +} > + > +void intel_hdcp_prop_work(struct work_struct *work) > +{ > + struct intel_connector *connector = container_of(work, > + struct intel_connector, > + hdcp_prop_work); > + struct drm_device *dev = connector->base.dev; > + struct drm_connector_state *state; > + > + mutex_lock(&dev->mode_config.mutex); You don't need this lock here. Only connection_mutex is needed to protect connector->status. > + drm_modeset_lock(&dev->mode_config.connection_mutex, NULL); > + mutex_lock(&connector->hdcp_mutex); > + > + /* > + * This worker is only used to flip between ENABLED/DESIRED. Either of > + * those to OFF is handled by core. If hdcp_value == OFF, we're running > + * just after hdcp has been disabled, so just exit > + */ > + if (connector->hdcp_value != DRM_MODE_CONTENT_PROTECTION_OFF) { > + state = connector->base.state; > + state->content_protection = connector->hdcp_value; > + } > + > + mutex_unlock(&connector->hdcp_mutex); > + drm_modeset_unlock(&dev->mode_config.connection_mutex); > + mutex_unlock(&dev->mode_config.mutex); > +} > + > +static int intel_hdcp_enable(struct intel_connector *connector) > +{ > + int ret; > + > + if (!connector->hdcp_shim) > + return -ENOENT; > + > + mutex_lock(&connector->hdcp_mutex); > + > + ret = _intel_hdcp_enable(connector); > + if (ret) > + goto out; > + > + connector->hdcp_value = DRM_MODE_CONTENT_PROTECTION_ENABLED; > + schedule_work(&connector->hdcp_prop_work); > + schedule_delayed_work(&connector->hdcp_check_work, > + DRM_HDCP_CHECK_PERIOD_MS); > +out: > + mutex_unlock(&connector->hdcp_mutex); > + return ret; > +} > + > +static int intel_hdcp_disable(struct intel_connector *connector) > +{ > + int ret; > + > + if (!connector->hdcp_shim) > + return -ENOENT; > + > + mutex_lock(&connector->hdcp_mutex); > + > + connector->hdcp_value = DRM_MODE_CONTENT_PROTECTION_OFF; > + ret = _intel_hdcp_disable(connector); > + > + mutex_unlock(&connector->hdcp_mutex); > + cancel_delayed_work_sync(&connector->hdcp_check_work); > + return ret; > +} > + > +void intel_hdcp_atomic_check(struct drm_connector *connector, > + struct drm_connector_state *old_state, > + struct drm_connector_state *new_state) > +{ > + uint64_t old_cp = old_state->content_protection; > + uint64_t new_cp = new_state->content_protection; > + > + if (!new_state->crtc) { > + /* > + * If the connector is being disabled with CP enabled, mark it > + * desired so it's re-enabled when the connector is brought back > + */ > + if (old_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED) > + new_state->content_protection = > + DRM_MODE_CONTENT_PROTECTION_DESIRED; > + return; > + } > + > + /* Only drivers can set content protection enabled */ > + if (old_cp != DRM_MODE_CONTENT_PROTECTION_ENABLED && > + new_cp == DRM_MODE_CONTENT_PROTECTION_ENABLED) > + new_state->content_protection = > + DRM_MODE_CONTENT_PROTECTION_DESIRED; > +} > + > +void intel_hdcp_atomic_pre_commit(struct drm_connector *connector, > + struct drm_connector_state *old_state, > + struct drm_connector_state *new_state) > +{ > + uint64_t old_cp = old_state->content_protection; > + uint64_t new_cp = new_state->content_protection; > + > + /* > + * Disable HDCP if the connector is becoming disabled, or if requested > + * via the property. > + */ > + if ((!new_state->crtc && old_cp != DRM_MODE_CONTENT_PROTECTION_OFF) || > + (new_state->crtc && old_cp != DRM_MODE_CONTENT_PROTECTION_OFF && > + new_cp == DRM_MODE_CONTENT_PROTECTION_OFF)) > + intel_hdcp_disable(to_intel_connector(connector)); > +} > + > +void intel_hdcp_atomic_commit(struct drm_connector *connector, > + struct drm_connector_state *new_state) > +{ > + uint64_t new_cp = new_state->content_protection; > + > + /* Enable hdcp if it's desired */ > + if (new_state->crtc && new_cp == DRM_MODE_CONTENT_PROTECTION_DESIRED) > + intel_hdcp_enable(to_intel_connector(connector)); > +} > + > +/* Implements Part 3 of the HDCP authorization procedure */ > +int intel_hdcp_check_link(struct intel_connector *connector) > +{ > + struct drm_i915_private *dev_priv = connector->base.dev->dev_private; > + struct intel_digital_port *intel_dig_port = conn_to_dig_port(connector); > + enum port port = intel_dig_port->base.port; > + int ret = 0; > + > + if (!connector->hdcp_shim) > + return -ENOENT; > + > + mutex_lock(&connector->hdcp_mutex); > + > + if (connector->hdcp_value == DRM_MODE_CONTENT_PROTECTION_OFF) > + goto out; > + > + if (!(I915_READ(SKL_PORT_HDCP_STATUS(port)) & SKL_HDCP_STATUS_ENC)) { > + DRM_ERROR("HDCP check failed: link is not encrypted, %x\n", > + I915_READ(SKL_PORT_HDCP_STATUS(port))); > + ret = -ENXIO; > + connector->hdcp_value = DRM_MODE_CONTENT_PROTECTION_DESIRED; > + schedule_work(&connector->hdcp_prop_work); > + goto out; > + } > + > + if (connector->hdcp_shim->check_link(intel_dig_port)) { > + if (connector->hdcp_value != DRM_MODE_CONTENT_PROTECTION_OFF) { > + connector->hdcp_value = > + DRM_MODE_CONTENT_PROTECTION_ENABLED; > + schedule_work(&connector->hdcp_prop_work); > + } > + goto out; > + } > + > + DRM_INFO("HDCP link failed, retrying authentication\n"); > + > + ret = _intel_hdcp_disable(connector); > + if (ret) { > + DRM_ERROR("Failed to disable hdcp (%d)\n", ret); > + connector->hdcp_value = DRM_MODE_CONTENT_PROTECTION_DESIRED; > + schedule_work(&connector->hdcp_prop_work); > + goto out; > + } > + > + ret = _intel_hdcp_enable(connector); > + if (ret) { > + DRM_ERROR("Failed to enable hdcp (%d)\n", ret); > + connector->hdcp_value = DRM_MODE_CONTENT_PROTECTION_DESIRED; > + schedule_work(&connector->hdcp_prop_work); > + goto out; > + } > + > +out: > + mutex_unlock(&connector->hdcp_mutex); > + return ret; > +} With the comments addressed: Reviewed-by: Daniel Vetter Also counts for the reg renaming patch if you want to do that as a follow-up in this series :-) -Daniel > -- > 2.15.0.531.g2ccb3012c9-goog > > _______________________________________________ > dri-devel mailing list > dri-devel@lists.freedesktop.org > https://lists.freedesktop.org/mailman/listinfo/dri-devel -- Daniel Vetter Software Engineer, Intel Corporation http://blog.ffwll.ch From mboxrd@z Thu Jan 1 00:00:00 1970 From: Daniel Vetter Subject: Re: [PATCH v3 5/9] drm/i915: Add HDCP framework + base implementation Date: Tue, 5 Dec 2017 18:00:25 +0100 Message-ID: <20171205170025.cwd5xgh5yzhhedj4@phenom.ffwll.local> References: <20171205051513.8603-1-seanpaul@chromium.org> <20171205051513.8603-6-seanpaul@chromium.org> Mime-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 Return-path: Received: from mail-wm0-x243.google.com (mail-wm0-x243.google.com [IPv6:2a00:1450:400c:c09::243]) by gabe.freedesktop.org (Postfix) with ESMTPS id 1BD186E5B7 for ; Tue, 5 Dec 2017 17:00:31 +0000 (UTC) Received: by mail-wm0-x243.google.com with SMTP id i11so2516680wmf.4 for ; Tue, 05 Dec 2017 09:00:31 -0800 (PST) Content-Disposition: inline In-Reply-To: <20171205051513.8603-6-seanpaul@chromium.org> List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: dri-devel-bounces@lists.freedesktop.org Sender: "dri-devel" To: Sean Paul Cc: seanpaul@google.com, David Airlie , intel-gfx@lists.freedesktop.org, Joonas Lahtinen , linux-kernel@vger.kernel.org, dri-devel@lists.freedesktop.org, Rodrigo Vivi , daniel.vetter@intel.com List-Id: dri-devel@lists.freedesktop.org T24gVHVlLCBEZWMgMDUsIDIwMTcgYXQgMTI6MTU6MDRBTSAtMDUwMCwgU2VhbiBQYXVsIHdyb3Rl Ogo+IFRoaXMgcGF0Y2ggYWRkcyB0aGUgZnJhbWV3b3JrIHJlcXVpcmVkIHRvIGFkZCBIRENQIHN1 cHBvcnQgdG8gaW50ZWwKPiBjb25uZWN0b3JzLiBJdCBpbXBsZW1lbnRzIEFrc3YgbG9hZGluZyBm cm9tIGZ1c2UsIGFuZCBwYXJ0cyAxLzIvMwo+IG9mIHRoZSBIRENQIGF1dGhlbnRpY2F0aW9uIHNj aGVtZS4KPiAKPiBOb3RlIHRoYXQgd2l0aG91dCBzaGltIGltcGxlbWVudGF0aW9ucywgdGhpcyBk b2VzIG5vdCBhY3R1YWxseSBpbXBsZW1lbnQKPiBIRENQLiBUaGF0IHdpbGwgY29tZSBpbiBzdWJz ZXF1ZW50IHBhdGNoZXMuCj4gCj4gQ2hhbmdlcyBpbiB2MjoKPiAtIERvbid0IG9wZW4gY29kZSB3 YWl0X2ZvcnMgKENocmlzKQo+IC0gZHJtX2hkY3AuYyB1bmRlciBNSVQgbGljZW5zZSAoRGFuaWVs KQo+IC0gTW92ZSBpbnRlbF9oZGNwX2Rpc2FibGUoKSBjYWxsIGFib3ZlIGRkaV9kaXNhYmxlIChS YW0pCj4gLSBGaXggLy8gY29tbWVudHMgKEkgd29yZSBhIGNvbmUgb2Ygc2hhbWUgZm9yIDEyIGhv dXJzIHRvIGF0b25lKSAoRGFuaWVsKQo+IC0gSnVzdGlmeSBpbnRlbF9oZGNwX3NoaW0gd2l0aCBj b21tZW50cyAoRGFuaWVsKQo+IC0gRml4ZWQgYXN5bmMgbG9ja2luZyBpc3N1ZXMgYnkgYWRkaW5n IGhkY3BfbXV0ZXggKERhbmllbCkKPiAtIERvbid0IGFsdGVyIGNvbm5lY3Rvcl9zdGF0ZSBpbiBl bmFibGUvZGlzYWJsZSAoRGFuaWVsKQo+IENoYW5nZXMgaW4gdjM6Cj4gLSBBZGRlZCBoZGNwX211 dGV4L2hkY3BfdmFsdWUgdG8gbWFrZSBhc3luYyByZWFzb25hYmxlCj4gLSBBZGRlZCBoZGNwX3By b3Bfd29yayB0byBzZXBhcmF0ZSBsaW5rIGNoZWNraW5nICYgcHJvcGVydHkgc2V0dGluZwo+IC0g QWRkZWQgbmV3IGhlbHBlciBmb3IgYXRvbWljX2NoZWNrIHN0YXRlIHRyYWNraW5nIChEYW5pZWwp Cj4gLSBNb3ZlZCBlbmFibGUvZGlzYWJsZSBpbnRvIGF0b21pY19jb21taXQgd2l0aCBtYXRjaGlu ZyBoZWxwZXJzCj4gLSBNb3ZlZCBpbnRlbF9oZGNwX2NoZWNrX2xpbmsgb3V0IG9mIGFsbCBsb2Nr cyB3aGVuIGNhbGxlZCBmcm9tIGRwCj4gLSBCdW1wZWQgdXAga3N2X2ZpZm8gdGltZW91dCAobm90 aWNlZCBmYWlsdXJlIG9uIG9uZSBvZiBteSBkb25nbGVzKQo+IAo+IENjOiBDaHJpcyBXaWxzb24g PGNocmlzQGNocmlzLXdpbHNvbi5jby51az4KPiBDYzogRGFuaWVsIFZldHRlciA8ZGFuaWVsLnZl dHRlckBpbnRlbC5jb20+Cj4gQ2M6IFJhbWFsaW5nYW0gQyA8cmFtYWxpbmdhbS5jQGludGVsLmNv bT4KPiBTaWduZWQtb2ZmLWJ5OiBTZWFuIFBhdWwgPHNlYW5wYXVsQGNocm9taXVtLm9yZz4KPiAt LS0KPiAgZHJpdmVycy9ncHUvZHJtL2k5MTUvTWFrZWZpbGUgICAgICAgIHwgICAxICsKPiAgZHJp dmVycy9ncHUvZHJtL2k5MTUvaTkxNV9yZWcuaCAgICAgIHwgIDgzICsrKysKPiAgZHJpdmVycy9n cHUvZHJtL2k5MTUvaW50ZWxfYXRvbWljLmMgIHwgICAyICsKPiAgZHJpdmVycy9ncHUvZHJtL2k5 MTUvaW50ZWxfZGlzcGxheS5jIHwgIDE0ICsKPiAgZHJpdmVycy9ncHUvZHJtL2k5MTUvaW50ZWxf ZHJ2LmggICAgIHwgIDg4ICsrKysrCj4gIGRyaXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX2hkY3Au YyAgICB8IDczMSArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKwo+ICA2IGZpbGVz IGNoYW5nZWQsIDkxOSBpbnNlcnRpb25zKCspCj4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJz L2dwdS9kcm0vaTkxNS9pbnRlbF9oZGNwLmMKPiAKPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUv ZHJtL2k5MTUvTWFrZWZpbGUgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9NYWtlZmlsZQo+IGluZGV4 IDQyYmM4YmQ0ZmYwNi4uM2ZhY2VhNGVlZmRiIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1L2Ry bS9pOTE1L01ha2VmaWxlCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvTWFrZWZpbGUKPiBA QCAtMTA3LDYgKzEwNyw3IEBAIGk5MTUteSArPSBpbnRlbF9hdWRpby5vIFwKPiAgCSAgaW50ZWxf ZmJjLm8gXAo+ICAJICBpbnRlbF9maWZvX3VuZGVycnVuLm8gXAo+ICAJICBpbnRlbF9mcm9udGJ1 ZmZlci5vIFwKPiArCSAgaW50ZWxfaGRjcC5vIFwKPiAgCSAgaW50ZWxfaG90cGx1Zy5vIFwKPiAg CSAgaW50ZWxfbW9kZXMubyBcCj4gIAkgIGludGVsX292ZXJsYXkubyBcCj4gZGlmZiAtLWdpdCBh L2RyaXZlcnMvZ3B1L2RybS9pOTE1L2k5MTVfcmVnLmggYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9p OTE1X3JlZy5oCj4gaW5kZXggMDliZjA0M2MxYzJlLi4yYmQyY2M4NDQxZDQgMTAwNjQ0Cj4gLS0t IGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvaTkxNV9yZWcuaAo+ICsrKyBiL2RyaXZlcnMvZ3B1L2Ry bS9pOTE1L2k5MTVfcmVnLmgKPiBAQCAtODAzNCw2ICs4MDM0LDcgQEAgZW51bSB7Cj4gICNkZWZp bmUgICAgIEdFTjlfTUVNX0xBVEVOQ1lfTEVWRUxfMV81X1NISUZUCTgKPiAgI2RlZmluZSAgICAg R0VOOV9NRU1fTEFURU5DWV9MRVZFTF8yXzZfU0hJRlQJMTYKPiAgI2RlZmluZSAgICAgR0VOOV9N RU1fTEFURU5DWV9MRVZFTF8zXzdfU0hJRlQJMjQKPiArI2RlZmluZSAgIFNLTF9QQ09ERV9MT0FE X0hEQ1BfS0VZUwkJMHg1CgpTS0xfIHByZWZpeCBmZWVscyByaWdodCBoZXJlLCBzaW5jZSB0aGlz IGlzIGZvciBza2wsIGtibCwgLi4uIG9ubHksIGFuZApkb2Vzbid0IGFwcGx5IHRvIGJ4dC4gU28g bm90IGdlbjkgc3R1ZmYuCgo+ICAjZGVmaW5lICAgU0tMX1BDT0RFX0NEQ0xLX0NPTlRST0wJCTB4 Nwo+ICAjZGVmaW5lICAgICBTS0xfQ0RDTEtfUFJFUEFSRV9GT1JfQ0hBTkdFCTB4Mwo+ICAjZGVm aW5lICAgICBTS0xfQ0RDTEtfUkVBRFlfRk9SX0NIQU5HRQkJMHgxCj4gQEAgLTgzMzUsNiArODMz Niw4OCBAQCBlbnVtIHNrbF9wb3dlcl9nYXRlIHsKPiAgI2RlZmluZSAgU0tMX1BXX1RPX1BHKHB3 KQkJCSgocHcpIC0gU0tMX0RJU1BfUFdfMSArIFNLTF9QRzEpCj4gICNkZWZpbmUgIFNLTF9GVVNF X1BHX0RJU1RfU1RBVFVTKHBnKQkJKDEgPDwgKDI3IC0gKHBnKSkpCj4gIAo+ICsKPiArLyogSERD UCBLZXkgUmVnaXN0ZXJzICovCj4gKyNkZWZpbmUgU0tMX0hEQ1BfS0VZX0NPTkYJCV9NTUlPKDB4 NjZjMDApCj4gKyNkZWZpbmUJIFNLTF9IRENQX0FLU1ZfU0VORF9UUklHR0VSCUJJVCgzMSkKPiAr I2RlZmluZSAgU0tMX0hEQ1BfQ0xFQVJfS0VZU19UUklHR0VSCUJJVCgzMCkKPiArI2RlZmluZSBT S0xfSERDUF9LRVlfU1RBVFVTCQlfTU1JTygweDY2YzA0KQo+ICsjZGVmaW5lICBTS0xfSERDUF9G VVNFX0lOX1BST0dSRVNTCUJJVCg3KQo+ICsjZGVmaW5lICBTS0xfSERDUF9GVVNFX0VSUk9SCQlC SVQoNikKPiArI2RlZmluZSAgU0tMX0hEQ1BfRlVTRV9ET05FCQlCSVQoNSkKPiArI2RlZmluZSAg U0tMX0hEQ1BfS0VZX0xPQURfU1RBVFVTCUJJVCgxKQo+ICsjZGVmaW5lICBTS0xfSERDUF9LRVlf TE9BRF9ET05FCQlCSVQoMCkKPiArI2RlZmluZSBTS0xfSERDUF9BS1NWX0xPCQlfTU1JTygweDY2 YzEwKQo+ICsjZGVmaW5lIFNLTF9IRENQX0FLU1ZfSEkJCV9NTUlPKDB4NjZjMTQpCj4gKwo+ICsv KiBIRENQIFJlcGVhdGVyIFJlZ2lzdGVycyAqLwo+ICsjZGVmaW5lIFNLTF9IRENQX1JFUF9DVEwJ CV9NTUlPKDB4NjZkMDApCj4gKyNkZWZpbmUgIFNLTF9IRENQX0RESUJfUkVQX1BSRVNFTlQJQklU KDMwKQo+ICsjZGVmaW5lICBTS0xfSERDUF9ERElCX1JFUF9QUkVTRU5UCUJJVCgzMCkKPiArI2Rl ZmluZSAgU0tMX0hEQ1BfRERJQV9SRVBfUFJFU0VOVAlCSVQoMjkpCj4gKyNkZWZpbmUgIFNLTF9I RENQX0RESUNfUkVQX1BSRVNFTlQJQklUKDI4KQo+ICsjZGVmaW5lICBTS0xfSERDUF9ERElEX1JF UF9QUkVTRU5UCUJJVCgyNykKPiArI2RlZmluZSAgU0tMX0hEQ1BfRERJRl9SRVBfUFJFU0VOVAlC SVQoMjYpCj4gKyNkZWZpbmUgIFNLTF9IRENQX0RESUVfUkVQX1BSRVNFTlQJQklUKDI1KQo+ICsj ZGVmaW5lICBTS0xfSERDUF9ERElCX1NIQTFfTTAJCSgxIDw8IDIwKQo+ICsjZGVmaW5lICBTS0xf SERDUF9ERElBX1NIQTFfTTAJCSgyIDw8IDIwKQo+ICsjZGVmaW5lICBTS0xfSERDUF9ERElDX1NI QTFfTTAJCSgzIDw8IDIwKQo+ICsjZGVmaW5lICBTS0xfSERDUF9ERElEX1NIQTFfTTAJCSg0IDw8 IDIwKQo+ICsjZGVmaW5lICBTS0xfSERDUF9ERElGX1NIQTFfTTAJCSg1IDw8IDIwKQo+ICsjZGVm aW5lICBTS0xfSERDUF9ERElFX1NIQTFfTTAJCSg2IDw8IDIwKSAvKiBCc3BlYyBzYXlzIDU/ICov CgpZZWFoIHRoYXQncyBvbmUgZ29vZCB3dGYgOi0pCgo+ICsjZGVmaW5lICBTS0xfSERDUF9TSEEx X0JVU1kJCUJJVCgxNikKPiArI2RlZmluZSAgU0tMX0hEQ1BfU0hBMV9SRUFEWQkJQklUKDE3KQo+ ICsjZGVmaW5lICBTS0xfSERDUF9TSEExX0NPTVBMRVRFCQlCSVQoMTgpCj4gKyNkZWZpbmUgIFNL TF9IRENQX1NIQTFfVl9NQVRDSAkJQklUKDE5KQo+ICsjZGVmaW5lICBTS0xfSERDUF9TSEExX1RF WFRfMzIJCSgxIDw8IDEpCj4gKyNkZWZpbmUgIFNLTF9IRENQX1NIQTFfQ09NUExFVEVfSEFTSAko MiA8PCAxKQo+ICsjZGVmaW5lICBTS0xfSERDUF9TSEExX1RFWFRfMjQJCSg0IDw8IDEpCj4gKyNk ZWZpbmUgIFNLTF9IRENQX1NIQTFfVEVYVF8xNgkJKDUgPDwgMSkKPiArI2RlZmluZSAgU0tMX0hE Q1BfU0hBMV9URVhUXzgJCSg2IDw8IDEpCj4gKyNkZWZpbmUgIFNLTF9IRENQX1NIQTFfVEVYVF8w CQkoNyA8PCAxKQo+ICsjZGVmaW5lIFNLTF9IRENQX1NIQV9WX1BSSU1FX0gwCQlfTU1JTygweDY2 ZDA0KQo+ICsjZGVmaW5lIFNLTF9IRENQX1NIQV9WX1BSSU1FX0gxCQlfTU1JTygweDY2ZDA4KQo+ ICsjZGVmaW5lIFNLTF9IRENQX1NIQV9WX1BSSU1FX0gyCQlfTU1JTygweDY2ZDBDKQo+ICsjZGVm aW5lIFNLTF9IRENQX1NIQV9WX1BSSU1FX0gzCQlfTU1JTygweDY2ZDEwKQo+ICsjZGVmaW5lIFNL TF9IRENQX1NIQV9WX1BSSU1FX0g0CQlfTU1JTygweDY2ZDE0KQo+ICsjZGVmaW5lIFNLTF9IRENQ X1NIQV9WX1BSSU1FKGgpCQlfTU1JTygoMHg2NmQwNCArIGggKiA0KSkKPiArI2RlZmluZSBTS0xf SERDUF9TSEFfVEVYVAkJX01NSU8oMHg2NmQxOCkKPiArCj4gKy8qIEhEQ1AgQXV0aCBSZWdpc3Rl cnMgKi8KPiArI2RlZmluZSBfU0tMX1BPUlRBX0hEQ1BfQVVUSEVOQwkJMHg2NjgwMAo+ICsjZGVm aW5lIF9TS0xfUE9SVEJfSERDUF9BVVRIRU5DCQkweDY2NTAwCj4gKyNkZWZpbmUgX1NLTF9QT1JU Q19IRENQX0FVVEhFTkMJCTB4NjY2MDAKPiArI2RlZmluZSBfU0tMX1BPUlREX0hEQ1BfQVVUSEVO QwkJMHg2NjcwMAo+ICsjZGVmaW5lIF9TS0xfUE9SVEVfSERDUF9BVVRIRU5DCQkweDY2QTAwCj4g KyNkZWZpbmUgX1NLTF9QT1JURl9IRENQX0FVVEhFTkMJCTB4NjY5MDAKPiArI2RlZmluZSBfU0tM X1BPUlRfSERDUF9BVVRIRU5DKHBvcnQsIHgpCV9NTUlPKF9QSUNLKHBvcnQsIFwKPiArCQkJCQkg IF9TS0xfUE9SVEFfSERDUF9BVVRIRU5DLCBcCj4gKwkJCQkJICBfU0tMX1BPUlRCX0hEQ1BfQVVU SEVOQywgXAo+ICsJCQkJCSAgX1NLTF9QT1JUQ19IRENQX0FVVEhFTkMsIFwKPiArCQkJCQkgIF9T S0xfUE9SVERfSERDUF9BVVRIRU5DLCBcCj4gKwkJCQkJICBfU0tMX1BPUlRFX0hEQ1BfQVVUSEVO QywgXAo+ICsJCQkJCSAgX1NLTF9QT1JURl9IRENQX0FVVEhFTkMpICsgeCkKPiArI2RlZmluZSBT S0xfUE9SVF9IRENQX0NPTkYocG9ydCkJX1NLTF9QT1JUX0hEQ1BfQVVUSEVOQyhwb3J0LCAweDAp Cj4gKyNkZWZpbmUgIFNLTF9IRENQX0NPTkZfQ0FQVFVSRV9BTglCSVQoMCkKPiArI2RlZmluZSAg U0tMX0hEQ1BfQ09ORl9BVVRIX0FORF9FTkMJKEJJVCgxKSB8IEJJVCgwKSkKPiArI2RlZmluZSBT S0xfUE9SVF9IRENQX0FOSU5JVChwb3J0KQlfU0tMX1BPUlRfSERDUF9BVVRIRU5DKHBvcnQsIDB4 NCkKPiArI2RlZmluZSBTS0xfUE9SVF9IRENQX0FOTE8ocG9ydCkJX1NLTF9QT1JUX0hEQ1BfQVVU SEVOQyhwb3J0LCAweDgpCj4gKyNkZWZpbmUgU0tMX1BPUlRfSERDUF9BTkhJKHBvcnQpCV9TS0xf UE9SVF9IRENQX0FVVEhFTkMocG9ydCwgMHhDKQo+ICsjZGVmaW5lIFNLTF9QT1JUX0hEQ1BfQktT VkxPKHBvcnQpCV9TS0xfUE9SVF9IRENQX0FVVEhFTkMocG9ydCwgMHgxMCkKPiArI2RlZmluZSBT S0xfUE9SVF9IRENQX0JLU1ZISShwb3J0KQlfU0tMX1BPUlRfSERDUF9BVVRIRU5DKHBvcnQsIDB4 MTQpCj4gKyNkZWZpbmUgU0tMX1BPUlRfSERDUF9SUFJJTUUocG9ydCkJX1NLTF9QT1JUX0hEQ1Bf QVVUSEVOQyhwb3J0LCAweDE4KQo+ICsjZGVmaW5lIFNLTF9QT1JUX0hEQ1BfU1RBVFVTKHBvcnQp CV9TS0xfUE9SVF9IRENQX0FVVEhFTkMocG9ydCwgMHgxQykKPiArI2RlZmluZSAgU0tMX0hEQ1Bf U1RBVFVTX1NUUkVBTV9BX0VOQwlCSVQoMzEpCj4gKyNkZWZpbmUgIFNLTF9IRENQX1NUQVRVU19T VFJFQU1fQl9FTkMJQklUKDMwKQo+ICsjZGVmaW5lICBTS0xfSERDUF9TVEFUVVNfU1RSRUFNX0Nf RU5DCUJJVCgyOSkKPiArI2RlZmluZSAgU0tMX0hEQ1BfU1RBVFVTX1NUUkVBTV9EX0VOQwlCSVQo MjgpCj4gKyNkZWZpbmUgIFNLTF9IRENQX1NUQVRVU19BVVRICQlCSVQoMjEpCj4gKyNkZWZpbmUg IFNLTF9IRENQX1NUQVRVU19FTkMJCUJJVCgyMCkKPiArI2RlZmluZSAgU0tMX0hEQ1BfU1RBVFVT X1JJX01BVENICUJJVCgxOSkKPiArI2RlZmluZSAgU0tMX0hEQ1BfU1RBVFVTX1IwX1JFQURZCUJJ VCgxOCkKPiArI2RlZmluZSAgU0tMX0hEQ1BfU1RBVFVTX0FOX1JFQURZCUJJVCgxNykKPiArI2Rl ZmluZSAgU0tMX0hEQ1BfU1RBVFVTX0NJUEhFUgkJQklUKDE2KQo+ICsjZGVmaW5lICBTS0xfSERD UF9TVEFUVVNfRlJBTUVfQ05UKHgpCSgoeCA+PiA4KSAmIDB4ZmYpCgpFeGNlcHQgZm9yIHRoZSBT S0wrIHNwZWNpZmljIEdUIG1haWxib3ggYml0IGFsbCB0aGUgYWJvdmUgcmVnaXN0ZXJzIGFyZQpn ZW5lcmljIChleGNlcHQgdGhlIDMgYml0cyBpbiBLRVlfU1RBVFVTIEkgaGlnaGxpZ2h0ZWQpLiBD YW4geW91IHBscyBzZWQKdGhlIGVudGlyZSBwYXRjaCBhbmQgZHJvcCB0aGUgU0tMXyBwcmVmaXgg ZnJvbSBhbGwgb2YgdGhlbT8KCkkga25vdyBpdCdzIGEgYml0IGJ1c3l3b3JrLCBidXQgZ2l2ZW4g aG93IHRoZSBiaXRzIG1vdmUgYXJvdW5kIGJldHdlZW4KcGxhdGZvcm1zIGluIGZ1bm55IHdheXMg aXQncyBnb29kIHByZXAgZm9yIGVuYWJsaW5nIGhkY3Agb24gbW9yZSBwbGF0Zm9ybXMKSSB0aGlu ay4KCklmIGl0J3MgdG9vIG1lc3N5IGZlZWwgZnJlZSB0byBhcHBseSB0aGUgYmlrZXNoZWQgaW4g YSBmb2xsb3ctdXAgcGF0Y2guCgpFaXRoZXIgd2F5IGFsbCB0aGUgYWJvdmUgbG9va3MgY29ycmVj dC4KCj4gKwo+ICAvKiBQZXItcGlwZSBEREkgRnVuY3Rpb24gQ29udHJvbCAqLwo+ICAjZGVmaW5l IF9UUkFOU19ERElfRlVOQ19DVExfQQkJMHg2MDQwMAo+ICAjZGVmaW5lIF9UUkFOU19ERElfRlVO Q19DVExfQgkJMHg2MTQwMAo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRl bF9hdG9taWMuYyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX2F0b21pYy5jCj4gaW5kZXgg MzZkNGU2MzVlNGNlLi5kNDUyYzMyN2RjMWQgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy9ncHUvZHJt L2k5MTUvaW50ZWxfYXRvbWljLmMKPiArKysgYi9kcml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9h dG9taWMuYwo+IEBAIC0xMTAsNiArMTEwLDggQEAgaW50IGludGVsX2RpZ2l0YWxfY29ubmVjdG9y X2F0b21pY19jaGVjayhzdHJ1Y3QgZHJtX2Nvbm5lY3RvciAqY29ubiwKPiAgCQl0b19pbnRlbF9k aWdpdGFsX2Nvbm5lY3Rvcl9zdGF0ZShvbGRfc3RhdGUpOwo+ICAJc3RydWN0IGRybV9jcnRjX3N0 YXRlICpjcnRjX3N0YXRlOwo+ICAKPiArCWludGVsX2hkY3BfYXRvbWljX2NoZWNrKGNvbm4sIG9s ZF9zdGF0ZSwgbmV3X3N0YXRlKTsKPiArCj4gIAlpZiAoIW5ld19zdGF0ZS0+Y3J0YykKPiAgCQly ZXR1cm4gMDsKPiAgCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX2Rp c3BsYXkuYyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX2Rpc3BsYXkuYwo+IGluZGV4IDYw MWMyM2JlODI2NC4uZjQ1YzQ2OGFiZjk4IDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9p OTE1L2ludGVsX2Rpc3BsYXkuYwo+ICsrKyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX2Rp c3BsYXkuYwo+IEBAIC0xMjMxOSw2ICsxMjMxOSw4IEBAIHN0YXRpYyB2b2lkIGludGVsX2F0b21p Y19jb21taXRfdGFpbChzdHJ1Y3QgZHJtX2F0b21pY19zdGF0ZSAqc3RhdGUpCj4gIAlzdHJ1Y3Qg ZHJtX2k5MTVfcHJpdmF0ZSAqZGV2X3ByaXYgPSB0b19pOTE1KGRldik7Cj4gIAlzdHJ1Y3QgZHJt X2NydGNfc3RhdGUgKm9sZF9jcnRjX3N0YXRlLCAqbmV3X2NydGNfc3RhdGU7Cj4gIAlzdHJ1Y3Qg ZHJtX2NydGMgKmNydGM7Cj4gKwlzdHJ1Y3QgZHJtX2Nvbm5lY3Rvcl9zdGF0ZSAqb2xkX2Nvbm5f c3RhdGUsICpuZXdfY29ubl9zdGF0ZTsKPiArCXN0cnVjdCBkcm1fY29ubmVjdG9yICpjb25uZWN0 b3I7Cj4gIAlzdHJ1Y3QgaW50ZWxfY3J0Y19zdGF0ZSAqaW50ZWxfY3N0YXRlOwo+ICAJdTY0IHB1 dF9kb21haW5zW0k5MTVfTUFYX1BJUEVTXSA9IHt9Owo+ICAJaW50IGk7Cj4gQEAgLTEyNDA4LDkg KzEyNDEwLDE3IEBAIHN0YXRpYyB2b2lkIGludGVsX2F0b21pY19jb21taXRfdGFpbChzdHJ1Y3Qg ZHJtX2F0b21pY19zdGF0ZSAqc3RhdGUpCj4gIAkJfQo+ICAJfQo+ICAKPiArCWZvcl9lYWNoX29s ZG5ld19jb25uZWN0b3JfaW5fc3RhdGUoc3RhdGUsIGNvbm5lY3Rvciwgb2xkX2Nvbm5fc3RhdGUs Cj4gKwkJCQkJICAgbmV3X2Nvbm5fc3RhdGUsIGkpCj4gKwkJaW50ZWxfaGRjcF9hdG9taWNfcHJl X2NvbW1pdChjb25uZWN0b3IsIG9sZF9jb25uX3N0YXRlLAo+ICsJCQkJCSAgICAgbmV3X2Nvbm5f c3RhdGUpOwo+ICsKPiAgCS8qIE5vdyBlbmFibGUgdGhlIGNsb2NrcywgcGxhbmUsIHBpcGUsIGFu ZCBjb25uZWN0b3JzIHRoYXQgd2Ugc2V0IHVwLiAqLwo+ICAJZGV2X3ByaXYtPmRpc3BsYXkudXBk YXRlX2NydGNzKHN0YXRlKTsKPiAgCj4gKwlmb3JfZWFjaF9uZXdfY29ubmVjdG9yX2luX3N0YXRl KHN0YXRlLCBjb25uZWN0b3IsIG5ld19jb25uX3N0YXRlLCBpKQo+ICsJCWludGVsX2hkY3BfYXRv bWljX2NvbW1pdChjb25uZWN0b3IsIG5ld19jb25uX3N0YXRlKTsKCkhtLCBJIGxpa2VkIHRoZSBv bGQgcGxhY2Ugd2hlcmUgdGhpcyB3YXMgY2FsbGVkIGZyb20gZGRpIGVuYWJsZS9kaXNhYmxlCmhv b2tzIG11Y2ggYmV0dGVyLiBIRENQIHZlcnkgbXVjaCBpcyBhIGNvbm5lY3RvciB0aGluZywgbGVh a2luZyB0aGF0CnRocm91Z2ggdGhlIGVudGlyZSBsYXllci1jYWtlIHRoYXQgaXMgYXRvbWljIHRv IHRoZSBoaWdoZXN0IGxldmVsIGZlZWxzIGEKYml0IHdyb25nLgoKV2h5PwoKRmlsbGluZyBpbiBh ZnRlciBhbiBpcmMgY2hhdCB3aXRoIFNlYW46IEl0J3MgbGVmdG92ZXJzIGZyb20gYW4gYXR0ZW1w dCBhdAp0cnlpbmcgdG8gaW1wbGVtZW50IEhEQ1Agc3RhdGUgY2hhbmdlcyB3aXRob3V0IGEgZnVs bCBtb2Rlc2V0LiBJbW8gdGhhdApzaG91bGQgYmUgdW5kb25lIGFnYWluIHRvIHRoZSBvbGQgdmVy c2lvbiwgZm9yIGEgZmV3IHJlYXNvbnM6CgotIEF0b21pYyBpcyBkYW1uIGhhcmQgdG8gdW5kZXJz dGFuZCBhbHJlYWR5LCBsZWFraW5nIGEgY29ubmVjdG9yIHRoaW5nCiAgdGhyb3VnaCBhbGwgbGF5 ZXJzIG1ha2VzIGl0IHdvcnNlLiBBbmQgd2UncmUgcHJvYmFibHkgYWxyZWFkeSBvdmVyIHRoZQog IGxpbWl0IG9mIGNvbXBsZXhpdHkgdGhhdCBjYW4gYmUgdW5kZXJzdG9vZCwgc28gbWFraW5nIGFi c3RyYWN0aW9ucyBtb3JlCiAgbGVha3kgbmVlZHMgc29tZSByZWFsIGdvb2QgcmVhc29ucy4KCi0g VmlsbGUgaXMgd29ya2luZyBvbiBhIHNsaWdodGx5IGRpZmZlcmVudCBhcHByb2FjaCB0byBhbGxv dwogIGNvbm5lY3RvcnMvZW5jb2RlcnMgdG8gZml4IHVwIHN0dWZmIGlmIG5vIG1vZGVzZXQgaGFw cGVuZWQgKG5ldyBzZXBhcmF0ZQogIGNhbGxiYWNrKS4gVGhpcyBoZXJlIGRvZXNuJ3QgYWxpZ24g d2l0aCB0aGF0IHBsYW4uCgo+ICsKPiAgCS8qIEZJWE1FOiBXZSBzaG91bGQgY2FsbCBkcm1fYXRv bWljX2hlbHBlcl9jb21taXRfaHdfZG9uZSgpIGhlcmUKPiAgCSAqIGFscmVhZHksIGJ1dCBzdGls bCBuZWVkIHRoZSBzdGF0ZSBmb3IgdGhlIGRlbGF5ZWQgb3B0aW1pemF0aW9uLiBUbwo+ICAJICog Zml4IHRoaXM6Cj4gQEAgLTE1MzIyLDYgKzE1MzMyLDEwIEBAIHN0YXRpYyB2b2lkIGludGVsX2hw ZF9wb2xsX2Zpbmkoc3RydWN0IGRybV9kZXZpY2UgKmRldikKPiAgCWZvcl9lYWNoX2ludGVsX2Nv bm5lY3Rvcl9pdGVyKGNvbm5lY3RvciwgJmNvbm5faXRlcikgewo+ICAJCWlmIChjb25uZWN0b3It Pm1vZGVzZXRfcmV0cnlfd29yay5mdW5jKQo+ICAJCQljYW5jZWxfd29ya19zeW5jKCZjb25uZWN0 b3ItPm1vZGVzZXRfcmV0cnlfd29yayk7Cj4gKwkJaWYgKGNvbm5lY3Rvci0+aGRjcF9zaGltKSB7 Cj4gKwkJCWNhbmNlbF9kZWxheWVkX3dvcmtfc3luYygmY29ubmVjdG9yLT5oZGNwX2NoZWNrX3dv cmspOwo+ICsJCQljYW5jZWxfd29ya19zeW5jKCZjb25uZWN0b3ItPmhkY3BfcHJvcF93b3JrKTsK PiArCQl9Cj4gIAl9Cj4gIAlkcm1fY29ubmVjdG9yX2xpc3RfaXRlcl9lbmQoJmNvbm5faXRlcik7 Cj4gIH0KPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9ncHUvZHJtL2k5MTUvaW50ZWxfZHJ2LmggYi9k cml2ZXJzL2dwdS9kcm0vaTkxNS9pbnRlbF9kcnYuaAo+IGluZGV4IDg1MmIzZDE2MTc1NC4uNmY0 N2E0MjI3ZjVmIDEwMDY0NAo+IC0tLSBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX2Rydi5o Cj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvaW50ZWxfZHJ2LmgKPiBAQCAtMzAxLDYgKzMw MSw3NiBAQCBzdHJ1Y3QgaW50ZWxfcGFuZWwgewo+ICAJfSBiYWNrbGlnaHQ7Cj4gIH07Cj4gIAo+ ICsvKgo+ICsgKiBUaGlzIHN0cnVjdHVyZSBzZXJ2ZXMgYXMgYSB0cmFuc2xhdGlvbiBsYXllciBi ZXR3ZWVuIHRoZSBnZW5lcmljIEhEQ1AgY29kZQo+ICsgKiBhbmQgdGhlIGJ1cy1zcGVjaWZpYyBj b2RlLiBXaGF0IHRoYXQgbWVhbnMgaXMgdGhhdCBIRENQIG92ZXIgSERNSSBkaWZmZXJzCj4gKyAq IGZyb20gSERDUCBvdmVyIERQLCBzbyB0byBhY2NvdW50IGZvciB0aGVzZSBkaWZmZXJlbmNlcywg d2UgbmVlZCB0bwo+ICsgKiBjb21tdW5pY2F0ZSB3aXRoIHRoZSByZWNlaXZlciB0aHJvdWdoIHRo aXMgc2hpbS4KPiArICoKPiArICogRm9yIGNvbXBsZXRlbmVzcywgdGhlIDIgYnVzZXMgZGlmZmVy IGluIHRoZSBmb2xsb3dpbmcgd2F5czoKPiArICoJLSBEUCBBVVggdnMuIEREQwo+ICsgKgkJSERD UCByZWdpc3RlcnMgb24gdGhlIHJlY2VpdmVyIGFyZSBzZXQgdmlhIERQIEFVWCBmb3IgRFAsIGFu ZAo+ICsgKgkJdGhleSBhcmUgc2V0IHZpYSBEREMgZm9yIEhETUkuCj4gKyAqCS0gUmVjZWl2ZXIg cmVnaXN0ZXIgb2Zmc2V0cwo+ICsgKgkJVGhlIG9mZnNldHMgb2YgdGhlIHJlZ2lzdGVycyBhcmUg ZGlmZmVyZW50IGZvciBEUCB2cy4gSERNSQo+ICsgKgktIFJlY2VpdmVyIHJlZ2lzdGVyIG1hc2tz L29mZnNldHMKPiArICoJCUZvciBpbnN0YW5jZSwgdGhlIHJlYWR5IGJpdCBmb3IgdGhlIEtTViBm aWZvIGlzIGluIGEgZGlmZmVyZW50Cj4gKyAqCQlwbGFjZSBvbiBEUCB2cyBIRE1JCj4gKyAqCS0g UmVjZWl2ZXIgcmVnaXN0ZXIgbmFtZXMKPiArICoJCVNlcmlvdXNseS4gSW4gdGhlIERQIHNwZWMs IHRoZSAxNi1iaXQgcmVnaXN0ZXIgY29udGFpbmluZwo+ICsgKgkJZG93bnN0cmVhbSBpbmZvcm1h dGlvbiBpcyBjYWxsZWQgQklORk8sIG9uIEhETUkgaXQncyBjYWxsZWQKPiArICoJCUJTVEFUVVMu IFRvIGNvbmZ1c2UgbWF0dGVycyBmdXJ0aGVyLCBEUCBoYXMgYSBCU1RBVFVTIHJlZ2lzdGVyCj4g KyAqCQl3aXRoIGEgY29tcGxldGVseSBkaWZmZXJlbnQgZGVmaW5pdGlvbi4KPiArICoJLSBLU1Yg RklGTwo+ICsgKgkJT24gSERNSSwgdGhlIGtzdiBmaWZvIGlzIHJlYWQgYWxsIGF0IG9uY2UsIHdo ZXJlYXMgb24gRFAgaXQgbXVzdAo+ICsgKgkJYmUgcmVhZCAzIGtleXMgYXQgYSB0aW1lCj4gKyAq CS0gQWtzdiBvdXRwdXQKPiArICoJCVNpbmNlIEFrc3YgaXMgaGlkZGVuIGluIGhhcmR3YXJlLCB0 aGVyZSdzIGRpZmZlcmVudCBwcm9jZWR1cmVzCj4gKyAqCQl0byBzZW5kIGl0IG92ZXIgRFAgQVVY IHZzIEREQwo+ICsgKi8KPiArc3RydWN0IGludGVsX2hkY3Bfc2hpbSB7Cj4gKwkvKiBPdXRwdXRz IHRoZSB0cmFuc21pdHRlcidzIEFuIGFuZCBBa3N2IHZhbHVlcyB0byB0aGUgcmVjZWl2ZXIuICov Cj4gKwlpbnQgKCp3cml0ZV9hbl9ha3N2KShzdHJ1Y3QgaW50ZWxfZGlnaXRhbF9wb3J0ICppbnRl bF9kaWdfcG9ydCwgdTggKmFuKTsKPiArCj4gKwkvKiBSZWFkcyB0aGUgcmVjZWl2ZXIncyBrZXkg c2VsZWN0aW9uIHZlY3RvciAqLwo+ICsJaW50ICgqcmVhZF9ia3N2KShzdHJ1Y3QgaW50ZWxfZGln aXRhbF9wb3J0ICppbnRlbF9kaWdfcG9ydCwgdTggKmJrc3YpOwo+ICsKPiArCS8qCj4gKwkgKiBS ZWFkcyBCSU5GTyBmcm9tIERQIHJlY2VpdmVycyBhbmQgQlNUQVRVUyBmcm9tIEhETUkgcmVjZWl2 ZXJzLiBUaGUKPiArCSAqIGRlZmluaXRpb25zIGFyZSB0aGUgc2FtZSBpbiB0aGUgcmVzcGVjdGl2 ZSBzcGVjcywgYnV0IHRoZSBuYW1lcyBhcmUKPiArCSAqIGRpZmZlcmVudC4gQ2FsbCBpdCBCU1RB VFVTIHNpbmNlIHRoYXQncyB0aGUgbmFtZSB0aGUgSERNSSBzcGVjCj4gKwkgKiB1c2VzIGFuZCBp dCB3YXMgdGhlcmUgZmlyc3QuCj4gKwkgKi8KPiArCWludCAoKnJlYWRfYnN0YXR1cykoc3RydWN0 IGludGVsX2RpZ2l0YWxfcG9ydCAqaW50ZWxfZGlnX3BvcnQsCj4gKwkJCSAgICB1OCAqYnN0YXR1 cyk7Cj4gKwo+ICsJLyogRGV0ZXJtaW5lcyB3aGV0aGVyIGEgcmVwZWF0ZXIgaXMgcHJlc2VudCBk b3duc3RyZWFtICovCj4gKwlpbnQgKCpyZXBlYXRlcl9wcmVzZW50KShzdHJ1Y3QgaW50ZWxfZGln aXRhbF9wb3J0ICppbnRlbF9kaWdfcG9ydCwKPiArCQkJCWJvb2wgKnJlcGVhdGVyX3ByZXNlbnQp Owo+ICsKPiArCS8qIFJlYWRzIHRoZSByZWNlaXZlcidzIFJpJyB2YWx1ZSAqLwo+ICsJaW50ICgq cmVhZF9yaV9wcmltZSkoc3RydWN0IGludGVsX2RpZ2l0YWxfcG9ydCAqaW50ZWxfZGlnX3BvcnQs IHU4ICpyaSk7Cj4gKwo+ICsJLyogRGV0ZXJtaW5lcyBpZiB0aGUgcmVjZWl2ZXIncyBLU1YgRklG TyBpcyByZWFkeSBmb3IgY29uc3VtcHRpb24gKi8KPiArCWludCAoKnJlYWRfa3N2X3JlYWR5KShz dHJ1Y3QgaW50ZWxfZGlnaXRhbF9wb3J0ICppbnRlbF9kaWdfcG9ydCwKPiArCQkJICAgICAgYm9v bCAqa3N2X3JlYWR5KTsKPiArCj4gKwkvKiBSZWFkcyB0aGUga3N2IGZpZm8gZm9yIG51bV9kb3du c3RyZWFtIGRldmljZXMgKi8KPiArCWludCAoKnJlYWRfa3N2X2ZpZm8pKHN0cnVjdCBpbnRlbF9k aWdpdGFsX3BvcnQgKmludGVsX2RpZ19wb3J0LAo+ICsJCQkgICAgIGludCBudW1fZG93bnN0cmVh bSwgdTggKmtzdl9maWZvKTsKPiArCj4gKwkvKiBSZWFkcyBhIDMyLWJpdCBwYXJ0IG9mIFYnIGZy b20gdGhlIHJlY2VpdmVyICovCj4gKwlpbnQgKCpyZWFkX3ZfcHJpbWVfcGFydCkoc3RydWN0IGlu dGVsX2RpZ2l0YWxfcG9ydCAqaW50ZWxfZGlnX3BvcnQsCj4gKwkJCQkgaW50IGksIHUzMiAqcGFy dCk7Cj4gKwo+ICsJLyogRW5hYmxlcyBIRENQIHNpZ25hbGxpbmcgb24gdGhlIHBvcnQgKi8KPiAr CWludCAoKnRvZ2dsZV9zaWduYWxsaW5nKShzdHJ1Y3QgaW50ZWxfZGlnaXRhbF9wb3J0ICppbnRl bF9kaWdfcG9ydCwKPiArCQkJCSBib29sIGVuYWJsZSk7Cj4gKwo+ICsJLyogRW5zdXJlcyB0aGUg bGluayBpcyBzdGlsbCBwcm90ZWN0ZWQgKi8KPiArCWJvb2wgKCpjaGVja19saW5rKShzdHJ1Y3Qg aW50ZWxfZGlnaXRhbF9wb3J0ICppbnRlbF9kaWdfcG9ydCk7Cj4gK307Cj4gKwo+ICBzdHJ1Y3Qg aW50ZWxfY29ubmVjdG9yIHsKPiAgCXN0cnVjdCBkcm1fY29ubmVjdG9yIGJhc2U7Cj4gIAkvKgo+ IEBAIC0zMzIsNiArNDAyLDEyIEBAIHN0cnVjdCBpbnRlbF9jb25uZWN0b3Igewo+ICAKPiAgCS8q IFdvcmsgc3RydWN0IHRvIHNjaGVkdWxlIGEgdWV2ZW50IG9uIGxpbmsgdHJhaW4gZmFpbHVyZSAq Lwo+ICAJc3RydWN0IHdvcmtfc3RydWN0IG1vZGVzZXRfcmV0cnlfd29yazsKPiArCj4gKwljb25z dCBzdHJ1Y3QgaW50ZWxfaGRjcF9zaGltICpoZGNwX3NoaW07Cj4gKwlzdHJ1Y3QgbXV0ZXggaGRj cF9tdXRleDsKPiArCXVpbnQ2NF90IGhkY3BfdmFsdWU7IC8qIHByb3RlY3RlZCBieSBoZGNwX211 dGV4ICovCj4gKwlzdHJ1Y3QgZGVsYXllZF93b3JrIGhkY3BfY2hlY2tfd29yazsKPiArCXN0cnVj dCB3b3JrX3N0cnVjdCBoZGNwX3Byb3Bfd29yazsKPiAgfTsKPiAgCj4gIHN0cnVjdCBpbnRlbF9k aWdpdGFsX2Nvbm5lY3Rvcl9zdGF0ZSB7Cj4gQEAgLTE3NjMsNiArMTgzOSwxOCBAQCBzdGF0aWMg aW5saW5lIHZvaWQgaW50ZWxfYmFja2xpZ2h0X2RldmljZV91bnJlZ2lzdGVyKHN0cnVjdCBpbnRl bF9jb25uZWN0b3IgKmNvbgo+ICB9Cj4gICNlbmRpZiAvKiBDT05GSUdfQkFDS0xJR0hUX0NMQVNT X0RFVklDRSAqLwo+ICAKPiArLyogaW50ZWxfaGRjcC5jICovCj4gK3ZvaWQgaW50ZWxfaGRjcF9h dG9taWNfY2hlY2soc3RydWN0IGRybV9jb25uZWN0b3IgKmNvbm5lY3RvciwKPiArCQkJICAgICBz dHJ1Y3QgZHJtX2Nvbm5lY3Rvcl9zdGF0ZSAqb2xkX3N0YXRlLAo+ICsJCQkgICAgIHN0cnVjdCBk cm1fY29ubmVjdG9yX3N0YXRlICpuZXdfc3RhdGUpOwo+ICt2b2lkIGludGVsX2hkY3BfYXRvbWlj X3ByZV9jb21taXQoc3RydWN0IGRybV9jb25uZWN0b3IgKmNvbm5lY3RvciwKPiArCQkJICAgICAg ICAgIHN0cnVjdCBkcm1fY29ubmVjdG9yX3N0YXRlICpvbGRfc3RhdGUsCj4gKwkJCSAgICAgICAg ICBzdHJ1Y3QgZHJtX2Nvbm5lY3Rvcl9zdGF0ZSAqbmV3X3N0YXRlKTsKPiArdm9pZCBpbnRlbF9o ZGNwX2F0b21pY19jb21taXQoc3RydWN0IGRybV9jb25uZWN0b3IgKmNvbm5lY3RvciwKPiArCQkJ ICAgICAgc3RydWN0IGRybV9jb25uZWN0b3Jfc3RhdGUgKm5ld19zdGF0ZSk7Cj4gK2ludCBpbnRl bF9oZGNwX2NoZWNrX2xpbmsoc3RydWN0IGludGVsX2Nvbm5lY3RvciAqY29ubmVjdG9yKTsKPiAr dm9pZCBpbnRlbF9oZGNwX2NoZWNrX3dvcmsoc3RydWN0IHdvcmtfc3RydWN0ICp3b3JrKTsKPiAr dm9pZCBpbnRlbF9oZGNwX3Byb3Bfd29yayhzdHJ1Y3Qgd29ya19zdHJ1Y3QgKndvcmspOwo+ICAK PiAgLyogaW50ZWxfcHNyLmMgKi8KPiAgdm9pZCBpbnRlbF9wc3JfZW5hYmxlKHN0cnVjdCBpbnRl bF9kcCAqaW50ZWxfZHAsCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2ludGVs X2hkY3AuYyBiL2RyaXZlcnMvZ3B1L2RybS9pOTE1L2ludGVsX2hkY3AuYwo+IG5ldyBmaWxlIG1v ZGUgMTAwNjQ0Cj4gaW5kZXggMDAwMDAwMDAwMDAwLi40ZWVmOTUwNTQxMGYKPiAtLS0gL2Rldi9u dWxsCj4gKysrIGIvZHJpdmVycy9ncHUvZHJtL2k5MTUvaW50ZWxfaGRjcC5jCj4gQEAgLTAsMCAr MSw3MzEgQEAKPiArLyoKPiArICogQ29weXJpZ2h0IChDKSAyMDE3IEdvb2dsZSwgSW5jLgo+ICsg Kgo+ICsgKiBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8g YW55IHBlcnNvbiBvYnRhaW5pbmcgYQo+ICsgKiBjb3B5IG9mIHRoaXMgc29mdHdhcmUgYW5kIGFz c29jaWF0ZWQgZG9jdW1lbnRhdGlvbiBmaWxlcyAodGhlICJTb2Z0d2FyZSIpLAo+ICsgKiB0byBk ZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91 dCBsaW1pdGF0aW9uCj4gKyAqIHRoZSByaWdodHMgdG8gdXNlLCBjb3B5LCBtb2RpZnksIG1lcmdl LCBwdWJsaXNoLCBkaXN0cmlidXRlLCBzdWJsaWNlbnNlLAo+ICsgKiBhbmQvb3Igc2VsbCBjb3Bp ZXMgb2YgdGhlIFNvZnR3YXJlLCBhbmQgdG8gcGVybWl0IHBlcnNvbnMgdG8gd2hvbSB0aGUKPiAr ICogU29mdHdhcmUgaXMgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dp bmcgY29uZGl0aW9uczoKPiArICoKPiArICogVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5k IHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4KPiArICogYWxsIGNv cGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCj4gKyAqCj4gKyAq IFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCAiQVMgSVMiLCBXSVRIT1VUIFdBUlJBTlRZIE9GIEFO WSBLSU5ELCBFWFBSRVNTIE9SCj4gKyAqIElNUExJRUQsIElOQ0xVRElORyBCVVQgTk9UIExJTUlU RUQgVE8gVEhFIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZLAo+ICsgKiBGSVRORVNTIEZP UiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiAgSU4gTk8gRVZFTlQg U0hBTEwKPiArICogVEhFIENPUFlSSUdIVCBIT0xERVIoUykgT1IgQVVUSE9SKFMpIEJFIExJQUJM RSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SCj4gKyAqIE9USEVSIExJQUJJTElUWSwgV0hFVEhF UiBJTiBBTiBBQ1RJT04gT0YgQ09OVFJBQ1QsIFRPUlQgT1IgT1RIRVJXSVNFLAo+ICsgKiBBUklT SU5HIEZST00sIE9VVCBPRiBPUiBJTiBDT05ORUNUSU9OIFdJVEggVEhFIFNPRlRXQVJFIE9SIFRI RSBVU0UgT1IKPiArICogT1RIRVIgREVBTElOR1MgSU4gVEhFIFNPRlRXQVJFLgo+ICsgKgo+ICsg KiBBdXRob3JzOgo+ICsgKiBTZWFuIFBhdWwgPHNlYW5wYXVsQGNocm9taXVtLm9yZz4KPiArICov Cj4gKwo+ICsjaW5jbHVkZSA8ZHJtL2RybVAuaD4KPiArI2luY2x1ZGUgPGRybS9kcm1faGRjcC5o Pgo+ICsjaW5jbHVkZSA8bGludXgvaTJjLmg+Cj4gKyNpbmNsdWRlIDxsaW51eC9yYW5kb20uaD4K PiArCj4gKyNpbmNsdWRlICJpbnRlbF9kcnYuaCIKPiArI2luY2x1ZGUgImk5MTVfcmVnLmgiCj4g Kwo+ICsjZGVmaW5lIEtFWV9MT0FEX1RSSUVTCTUKPiArCj4gK3N0YXRpYyBpbnQgaW50ZWxfaGRj cF9wb2xsX2tzdl9maWZvKHN0cnVjdCBpbnRlbF9kaWdpdGFsX3BvcnQgKmludGVsX2RpZ19wb3J0 LAo+ICsJCQkJICAgIGNvbnN0IHN0cnVjdCBpbnRlbF9oZGNwX3NoaW0gKnNoaW0pCj4gK3sKPiAr CWludCByZXQsIHJlYWRfcmV0Owo+ICsJYm9vbCBrc3ZfcmVhZHk7Cj4gKwo+ICsJcmV0ID0gX193 YWl0X2ZvcihyZWFkX3JldCA9IHNoaW0tPnJlYWRfa3N2X3JlYWR5KGludGVsX2RpZ19wb3J0LAo+ ICsJCQkJCQkJICZrc3ZfcmVhZHkpLAo+ICsJCQkgcmVhZF9yZXQgfHwga3N2X3JlYWR5LCAxNTAw ICogMTAwMCwgMTAwMCwgMTAwICogMTAwMCk7Cj4gKwlpZiAocmV0KQo+ICsJCXJldHVybiByZXQ7 Cj4gKwlpZiAocmVhZF9yZXQpCj4gKwkJcmV0dXJuIHJlYWRfcmV0Owo+ICsJaWYgKCFrc3ZfcmVh ZHkpCj4gKwkJcmV0dXJuIC1FVElNRURPVVQ7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4g K3N0YXRpYyB2b2lkIGludGVsX2hkY3BfY2xlYXJfa2V5cyhzdHJ1Y3QgZHJtX2k5MTVfcHJpdmF0 ZSAqZGV2X3ByaXYpCj4gK3sKPiArCUk5MTVfV1JJVEUoU0tMX0hEQ1BfS0VZX0NPTkYsIFNLTF9I RENQX0NMRUFSX0tFWVNfVFJJR0dFUik7Cj4gKwlJOTE1X1dSSVRFKFNLTF9IRENQX0tFWV9TVEFU VVMsCj4gKwkJICAgU0tMX0hEQ1BfS0VZX0xPQURfRE9ORSB8IFNLTF9IRENQX0tFWV9MT0FEX1NU QVRVUyB8Cj4gKwkJICAgU0tMX0hEQ1BfRlVTRV9JTl9QUk9HUkVTUyB8IFNLTF9IRENQX0ZVU0Vf RVJST1IgfAo+ICsJCSAgIFNLTF9IRENQX0ZVU0VfRE9ORSk7Cj4gK30KPiArCj4gK3N0YXRpYyBp bnQgaW50ZWxfaGRjcF9sb2FkX2tleXMoc3RydWN0IGRybV9pOTE1X3ByaXZhdGUgKmRldl9wcml2 KQo+ICt7Cj4gKwlpbnQgcmV0Owo+ICsJdTMyIHZhbDsKPiArCj4gKwkvKiBJbml0aWF0ZSBsb2Fk aW5nIHRoZSBIRENQIGtleSBmcm9tIGZ1c2VzICovCj4gKwltdXRleF9sb2NrKCZkZXZfcHJpdi0+ cGN1X2xvY2spOwo+ICsJcmV0ID0gc2FuZHlicmlkZ2VfcGNvZGVfd3JpdGUoZGV2X3ByaXYsIFNL TF9QQ09ERV9MT0FEX0hEQ1BfS0VZUywgMSk7Cj4gKwltdXRleF91bmxvY2soJmRldl9wcml2LT5w Y3VfbG9jayk7Cj4gKwlpZiAocmV0KSB7Cj4gKwkJRFJNX0VSUk9SKCJGYWlsZWQgdG8gaW5pdGlh dGUgSERDUCBrZXkgbG9hZCAoJWQpXG4iLCByZXQpOwo+ICsJCXJldHVybiByZXQ7Cj4gKwl9Cj4g Kwo+ICsJLyogV2FpdCBmb3IgdGhlIGtleXMgdG8gbG9hZCAoNTAwdXMpICovCj4gKwlyZXQgPSBf X2ludGVsX3dhaXRfZm9yX3JlZ2lzdGVyKGRldl9wcml2LCBTS0xfSERDUF9LRVlfU1RBVFVTLAo+ ICsJCQkJCVNLTF9IRENQX0tFWV9MT0FEX0RPTkUsCj4gKwkJCQkJU0tMX0hEQ1BfS0VZX0xPQURf RE9ORSwKPiArCQkJCQkxMCwgMSwgJnZhbCk7Cj4gKwlpZiAocmV0KQo+ICsJCXJldHVybiByZXQ7 Cj4gKwllbHNlIGlmICghKHZhbCAmIFNLTF9IRENQX0tFWV9MT0FEX1NUQVRVUykpCj4gKwkJcmV0 dXJuIC1FTlhJTzsKPiArCj4gKwkvKiBTZW5kIEFrc3Ygb3ZlciB0byBQQ0ggZGlzcGxheSBmb3Ig dXNlIGluIGF1dGhlbnRpY2F0aW9uICovCj4gKwlJOTE1X1dSSVRFKFNLTF9IRENQX0tFWV9DT05G LCBTS0xfSERDUF9BS1NWX1NFTkRfVFJJR0dFUik7Cj4gKwo+ICsJcmV0dXJuIDA7Cj4gK30KPiAr Cj4gKy8qIFJldHVybnMgdXBkYXRlZCBTSEEtMSBpbmRleCAqLwo+ICtzdGF0aWMgaW50IGludGVs X3dyaXRlX3NoYV90ZXh0KHN0cnVjdCBkcm1faTkxNV9wcml2YXRlICpkZXZfcHJpdiwgdTMyIHNo YV90ZXh0KQo+ICt7Cj4gKwlJOTE1X1dSSVRFKFNLTF9IRENQX1NIQV9URVhULCBzaGFfdGV4dCk7 Cj4gKwlpZiAoaW50ZWxfd2FpdF9mb3JfcmVnaXN0ZXIoZGV2X3ByaXYsIFNLTF9IRENQX1JFUF9D VEwsCj4gKwkJCQkgICAgU0tMX0hEQ1BfU0hBMV9SRUFEWSwKPiArCQkJCSAgICBTS0xfSERDUF9T SEExX1JFQURZLCAxKSkgewo+ICsJCURSTV9FUlJPUigiVGltZWQgb3V0IHdhaXRpbmcgZm9yIFNI QTEgcmVhZHlcbiIpOwo+ICsJCXJldHVybiAtRVRJTUVET1VUOwo+ICsJfQo+ICsJcmV0dXJuIDA7 Cj4gK30KPiArCj4gK3N0YXRpYwo+ICt1MzIgaW50ZWxfaGRjcF9nZXRfcmVwZWF0ZXJfY3RsKHN0 cnVjdCBpbnRlbF9kaWdpdGFsX3BvcnQgKmludGVsX2RpZ19wb3J0KQo+ICt7Cj4gKwllbnVtIHBv cnQgcG9ydCA9IGludGVsX2RpZ19wb3J0LT5iYXNlLnBvcnQ7Cj4gKwlzd2l0Y2gocG9ydCkgewo+ ICsJY2FzZSBQT1JUX0E6Cj4gKwkJcmV0dXJuIFNLTF9IRENQX0RESUFfUkVQX1BSRVNFTlQgfCBT S0xfSERDUF9ERElBX1NIQTFfTTA7Cj4gKwljYXNlIFBPUlRfQjoKPiArCQlyZXR1cm4gU0tMX0hE Q1BfRERJQl9SRVBfUFJFU0VOVCB8IFNLTF9IRENQX0RESUJfU0hBMV9NMDsKPiArCWNhc2UgUE9S VF9DOgo+ICsJCXJldHVybiBTS0xfSERDUF9ERElDX1JFUF9QUkVTRU5UIHwgU0tMX0hEQ1BfRERJ Q19TSEExX00wOwo+ICsJY2FzZSBQT1JUX0Q6Cj4gKwkJcmV0dXJuIFNLTF9IRENQX0RESURfUkVQ X1BSRVNFTlQgfCBTS0xfSERDUF9ERElEX1NIQTFfTTA7Cj4gKwljYXNlIFBPUlRfRToKPiArCQly ZXR1cm4gU0tMX0hEQ1BfRERJRV9SRVBfUFJFU0VOVCB8IFNLTF9IRENQX0RESUVfU0hBMV9NMDsK PiArCWRlZmF1bHQ6Cj4gKwkJYnJlYWs7Cj4gKwl9Cj4gKwlEUk1fRVJST1IoIlVua25vd24gcG9y dCAlZFxuIiwgcG9ydCk7Cj4gKwlyZXR1cm4gLUVJTlZBTDsKPiArfQo+ICsKPiArLyogSW1wbGVt ZW50cyBQYXJ0IDIgb2YgdGhlIEhEQ1AgYXV0aG9yaXphdGlvbiBwcm9jZWR1cmUgKi8KPiArc3Rh dGljCj4gK2ludCBpbnRlbF9oZGNwX2F1dGhfZG93bnN0cmVhbShzdHJ1Y3QgaW50ZWxfZGlnaXRh bF9wb3J0ICppbnRlbF9kaWdfcG9ydCwKPiArCQkJICAgICAgIGNvbnN0IHN0cnVjdCBpbnRlbF9o ZGNwX3NoaW0gKnNoaW0pCj4gK3sKPiArCXN0cnVjdCBkcm1faTkxNV9wcml2YXRlICpkZXZfcHJp djsKPiArCXUzMiB2cHJpbWUsIHNoYV90ZXh0LCBzaGFfbGVmdG92ZXJzLCByZXBfY3RsOwo+ICsJ dTggYnN0YXR1c1syXSwgbnVtX2Rvd25zdHJlYW0sICprc3ZfZmlmbzsKPiArCWludCByZXQsIGks IGosIHNoYV9pZHg7Cj4gKwo+ICsJZGV2X3ByaXYgPSBpbnRlbF9kaWdfcG9ydC0+YmFzZS5iYXNl LmRldi0+ZGV2X3ByaXZhdGU7Cj4gKwo+ICsJcmV0ID0gc2hpbS0+cmVhZF9ic3RhdHVzKGludGVs X2RpZ19wb3J0LCBic3RhdHVzKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCj4g KwkvKiBJZiB0aGVyZSBhcmUgbm8gZG93bnN0cmVhbSBkZXZpY2VzLCB3ZSdyZSBhbGwgZG9uZS4g Ki8KPiArCW51bV9kb3duc3RyZWFtID0gRFJNX0hEQ1BfTlVNX0RPV05TVFJFQU0oYnN0YXR1c1sw XSk7Cj4gKwlpZiAobnVtX2Rvd25zdHJlYW0gPT0gMCkgewo+ICsJCURSTV9JTkZPKCJIRENQIGlz IGVuYWJsZWQgKG5vIGRvd25zdHJlYW0gZGV2aWNlcylcbiIpOwo+ICsJCXJldHVybiAwOwo+ICsJ fQo+ICsKPiArCS8qIFBvbGwgZm9yIGtzdiBsaXN0IHJlYWR5IChzcGVjIHNheXMgbWF4IHRpbWUg YWxsb3dlZCBpcyA1cykgKi8KPiArCXJldCA9IGludGVsX2hkY3BfcG9sbF9rc3ZfZmlmbyhpbnRl bF9kaWdfcG9ydCwgc2hpbSk7Cj4gKwlpZiAocmV0KSB7Cj4gKwkJRFJNX0VSUk9SKCJLU1YgbGlz dCBmYWlsZWQgdG8gYmVjb21lIHJlYWR5ICglZClcbiIsIHJldCk7Cj4gKwkJcmV0dXJuIHJldDsK PiArCX0KPiArCj4gKwlrc3ZfZmlmbyA9IGt6YWxsb2MobnVtX2Rvd25zdHJlYW0gKiBEUk1fSERD UF9LU1ZfTEVOLCBHRlBfS0VSTkVMKTsKPiArCWlmICgha3N2X2ZpZm8pCj4gKwkJcmV0dXJuIC1F Tk9NRU07Cj4gKwo+ICsJcmV0ID0gc2hpbS0+cmVhZF9rc3ZfZmlmbyhpbnRlbF9kaWdfcG9ydCwg bnVtX2Rvd25zdHJlYW0sIGtzdl9maWZvKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsK PiArCj4gKwkvKiBQcm9jZXNzIFYnIHZhbHVlcyBmcm9tIHRoZSByZWNlaXZlciAqLwo+ICsJZm9y IChpID0gMDsgaSA8IERSTV9IRENQX1ZfUFJJTUVfTlVNX1BBUlRTOyBpKyspIHsKPiArCQlyZXQg PSBzaGltLT5yZWFkX3ZfcHJpbWVfcGFydChpbnRlbF9kaWdfcG9ydCwgaSwgJnZwcmltZSk7Cj4g KwkJaWYgKHJldCkKPiArCQkJcmV0dXJuIHJldDsKPiArCQlJOTE1X1dSSVRFKFNLTF9IRENQX1NI QV9WX1BSSU1FKGkpLCB2cHJpbWUpOwo+ICsJfQo+ICsKPiArCS8qCj4gKwkgKiBXZSBuZWVkIHRv IHdyaXRlIHRoZSBjb25jYXRlbmF0aW9uIG9mIGFsbCBkZXZpY2UgS1NWcywgQklORk8gKERQKSB8 fAo+ICsJICogQlNUQVRVUyAoSERNSSksIGFuZCBNMCAod2hpY2ggaXMgYWRkZWQgdmlhIEhEQ1Bf UkVQX0NUTCkuIFRoaXMgYnl0ZQo+ICsJICogc3RyZWFtIGlzIHdyaXR0ZW4gdmlhIHRoZSBIRENQ X1NIQV9URVhUIHJlZ2lzdGVyIGluIDMyLWJpdAo+ICsJICogaW5jcmVtZW50cy4gRXZlcnkgNjQg Ynl0ZXMsIHdlIG5lZWQgdG8gd3JpdGUgSERDUF9SRVBfQ1RMIGFnYWluLiBUaGlzCj4gKwkgKiBp bmRleCB3aWxsIGtlZXAgdHJhY2sgb2Ygb3VyIHByb2dyZXNzIHRocm91Z2ggdGhlIDY0IGJ5dGVz IGFzIHdlbGwgYXMKPiArCSAqIGhlbHBpbmcgdXMgd29yayB0aGUgNDAtYml0IEtTVnMgdGhyb3Vn aCBvdXIgMzItYml0IHJlZ2lzdGVyLgo+ICsJICoKPiArCSAqIE5PVEU6IGRhdGEgcGFzc2VkIHZp YSBIRENQX1NIQV9URVhUIHNob3VsZCBiZSBiaWctZW5kaWFuCj4gKwkgKi8KPiArCXNoYV9pZHgg PSAwOwo+ICsJc2hhX3RleHQgPSAwOwo+ICsJc2hhX2xlZnRvdmVycyA9IDA7Cj4gKwlyZXBfY3Rs ID0gaW50ZWxfaGRjcF9nZXRfcmVwZWF0ZXJfY3RsKGludGVsX2RpZ19wb3J0KTsKPiArCUk5MTVf V1JJVEUoU0tMX0hEQ1BfUkVQX0NUTCwgcmVwX2N0bCB8IFNLTF9IRENQX1NIQTFfVEVYVF8zMik7 Cj4gKwlmb3IgKGkgPSAwOyBpIDwgbnVtX2Rvd25zdHJlYW07IGkrKykgewo+ICsJCXVuc2lnbmVk IHNoYV9lbXB0eTsKPiArCQl1OCAqa3N2ID0gJmtzdl9maWZvW2kgKiBEUk1fSERDUF9LU1ZfTEVO XTsKPiArCj4gKwkJLyogRmlsbCB1cCB0aGUgZW1wdHkgc2xvdHMgaW4gc2hhX3RleHQgYW5kIHdy aXRlIGl0IG91dCAqLwo+ICsJCXNoYV9lbXB0eSA9IHNpemVvZihzaGFfdGV4dCkgLSBzaGFfbGVm dG92ZXJzOwo+ICsJCWZvciAoaiA9IDA7IGogPCBzaGFfZW1wdHk7IGorKykKPiArCQkJc2hhX3Rl eHQgfD0ga3N2W2pdIDw8ICgoc2l6ZW9mKHNoYV90ZXh0KSAtIGogLSAxKSAqIDgpOwo+ICsKPiAr CQlyZXQgPSBpbnRlbF93cml0ZV9zaGFfdGV4dChkZXZfcHJpdiwgc2hhX3RleHQpOwo+ICsJCWlm IChyZXQgPCAwKQo+ICsJCQlyZXR1cm4gcmV0Owo+ICsKPiArCQkvKiBQcm9ncmFtbWluZyBndWlk ZSB3cml0ZXMgdGhpcyBldmVyeSA2NCBieXRlcyAqLwo+ICsJCXNoYV9pZHggKz0gc2l6ZW9mKHNo YV90ZXh0KTsKPiArCQlpZiAoIShzaGFfaWR4ICUgNjQpKQo+ICsJCQlJOTE1X1dSSVRFKFNLTF9I RENQX1JFUF9DVEwsCj4gKwkJCQkgICByZXBfY3RsIHwgU0tMX0hEQ1BfU0hBMV9URVhUXzMyKTsK PiArCj4gKwkJLyogU3RvcmUgdGhlIGxlZnRvdmVyIGJ5dGVzIGZyb20gdGhlIGtzdiBpbiBzaGFf dGV4dCAqLwo+ICsJCXNoYV9sZWZ0b3ZlcnMgPSBEUk1fSERDUF9LU1ZfTEVOIC0gc2hhX2VtcHR5 Owo+ICsJCXNoYV90ZXh0ID0gMDsKPiArCQlmb3IgKGogPSAwOyBqIDwgc2hhX2xlZnRvdmVyczsg aisrKQo+ICsJCQlzaGFfdGV4dCB8PSBrc3Zbc2hhX2VtcHR5ICsgal0gPDwKPiArCQkJCQkoKHNp emVvZihzaGFfdGV4dCkgLSBqIC0gMSkgKiA4KTsKPiArCj4gKwkJLyoKPiArCQkgKiBJZiB3ZSBz dGlsbCBoYXZlIHJvb20gaW4gc2hhX3RleHQgZm9yIG1vcmUgZGF0YSwgY29udGludWUuCj4gKwkJ ICogT3RoZXJ3aXNlLCB3cml0ZSBpdCBvdXQgaW1tZWRpYXRlbHkuCj4gKwkJICovCj4gKwkJaWYg KHNpemVvZihzaGFfdGV4dCkgPiBzaGFfbGVmdG92ZXJzKQo+ICsJCQljb250aW51ZTsKPiArCj4g KwkJcmV0ID0gaW50ZWxfd3JpdGVfc2hhX3RleHQoZGV2X3ByaXYsIHNoYV90ZXh0KTsKPiArCQlp ZiAocmV0IDwgMCkKPiArCQkJcmV0dXJuIHJldDsKPiArCQlzaGFfbGVmdG92ZXJzID0gMDsKPiAr CQlzaGFfdGV4dCA9IDA7Cj4gKwkJc2hhX2lkeCArPSBzaXplb2Yoc2hhX3RleHQpOwo+ICsJfQo+ ICsKPiArCS8qCj4gKwkgKiBXZSBuZWVkIHRvIHdyaXRlIEJJTkZPL0JTVEFUVVMsIGFuZCBNMCBu b3cuIERlcGVuZGluZyBvbiBob3cgbWFueQo+ICsJICogYnl0ZXMgYXJlIGxlZnRvdmVyIGZyb20g dGhlIGxhc3Qga3N2LCB3ZSBtaWdodCBiZSBhYmxlIHRvIGZpdCB0aGVtCj4gKwkgKiBhbGwgaW4g c2hhX3RleHQgKGZpcnN0IDIgY2FzZXMpLCBvciB3ZSBtaWdodCBuZWVkIHRvIHNwbGl0IHRoZW0g dXAKPiArCSAqIGludG8gMiB3cml0ZXMgKGxhc3QgMiBjYXNlcykuCj4gKwkgKi8KPiArCWlmIChz aGFfbGVmdG92ZXJzID09IDApIHsKPiArCQkvKiBXcml0ZSAxNiBiaXRzIG9mIHRleHQsIDE2IGJp dHMgb2YgTTAgKi8KPiArCQlJOTE1X1dSSVRFKFNLTF9IRENQX1JFUF9DVEwsIHJlcF9jdGwgfCBT S0xfSERDUF9TSEExX1RFWFRfMTYpOwo+ICsJCXJldCA9IGludGVsX3dyaXRlX3NoYV90ZXh0KGRl dl9wcml2LAo+ICsJCQkJCSAgIGJzdGF0dXNbMF0gPDwgOCB8IGJzdGF0dXNbMV0pOwo+ICsJCWlm IChyZXQgPCAwKQo+ICsJCQlyZXR1cm4gcmV0Owo+ICsJCXNoYV9pZHggKz0gc2l6ZW9mKHNoYV90 ZXh0KTsKPiArCj4gKwkJLyogV3JpdGUgMzIgYml0cyBvZiBNMCAqLwo+ICsJCUk5MTVfV1JJVEUo U0tMX0hEQ1BfUkVQX0NUTCwgcmVwX2N0bCB8IFNLTF9IRENQX1NIQTFfVEVYVF8wKTsKPiArCQly ZXQgPSBpbnRlbF93cml0ZV9zaGFfdGV4dChkZXZfcHJpdiwgMCk7Cj4gKwkJaWYgKHJldCA8IDAp Cj4gKwkJCXJldHVybiByZXQ7Cj4gKwkJc2hhX2lkeCArPSBzaXplb2Yoc2hhX3RleHQpOwo+ICsK PiArCQkvKiBXcml0ZSAxNiBiaXRzIG9mIE0wICovCj4gKwkJSTkxNV9XUklURShTS0xfSERDUF9S RVBfQ1RMLCByZXBfY3RsIHwgU0tMX0hEQ1BfU0hBMV9URVhUXzE2KTsKPiArCQlyZXQgPSBpbnRl bF93cml0ZV9zaGFfdGV4dChkZXZfcHJpdiwgMCk7Cj4gKwkJaWYgKHJldCA8IDApCj4gKwkJCXJl dHVybiByZXQ7Cj4gKwkJc2hhX2lkeCArPSBzaXplb2Yoc2hhX3RleHQpOwo+ICsKPiArCX0gZWxz ZSBpZiAoc2hhX2xlZnRvdmVycyA9PSAxKSB7Cj4gKwkJLyogV3JpdGUgMjQgYml0cyBvZiB0ZXh0 LCA4IGJpdHMgb2YgTTAgKi8KPiArCQlJOTE1X1dSSVRFKFNLTF9IRENQX1JFUF9DVEwsIHJlcF9j dGwgfCBTS0xfSERDUF9TSEExX1RFWFRfMjQpOwo+ICsJCXNoYV90ZXh0IHw9IGJzdGF0dXNbMF0g PDwgMTYgfCBic3RhdHVzWzFdIDw8IDg7Cj4gKwkJLyogT25seSAyNC1iaXRzIG9mIGRhdGEsIG11 c3QgYmUgaW4gdGhlIExTQiAqLwo+ICsJCXNoYV90ZXh0ID0gKHNoYV90ZXh0ICYgMHhmZmZmZmYw MCkgPj4gODsKPiArCQlyZXQgPSBpbnRlbF93cml0ZV9zaGFfdGV4dChkZXZfcHJpdiwgc2hhX3Rl eHQpOwo+ICsJCWlmIChyZXQgPCAwKQo+ICsJCQlyZXR1cm4gcmV0Owo+ICsJCXNoYV9pZHggKz0g c2l6ZW9mKHNoYV90ZXh0KTsKPiArCj4gKwkJLyogV3JpdGUgMzIgYml0cyBvZiBNMCAqLwo+ICsJ CUk5MTVfV1JJVEUoU0tMX0hEQ1BfUkVQX0NUTCwgcmVwX2N0bCB8IFNLTF9IRENQX1NIQTFfVEVY VF8wKTsKPiArCQlyZXQgPSBpbnRlbF93cml0ZV9zaGFfdGV4dChkZXZfcHJpdiwgMCk7Cj4gKwkJ aWYgKHJldCA8IDApCj4gKwkJCXJldHVybiByZXQ7Cj4gKwkJc2hhX2lkeCArPSBzaXplb2Yoc2hh X3RleHQpOwo+ICsKPiArCQkvKiBXcml0ZSAyNCBiaXRzIG9mIE0wICovCj4gKwkJSTkxNV9XUklU RShTS0xfSERDUF9SRVBfQ1RMLCByZXBfY3RsIHwgU0tMX0hEQ1BfU0hBMV9URVhUXzgpOwo+ICsJ CXJldCA9IGludGVsX3dyaXRlX3NoYV90ZXh0KGRldl9wcml2LCAwKTsKPiArCQlpZiAocmV0IDwg MCkKPiArCQkJcmV0dXJuIHJldDsKPiArCQlzaGFfaWR4ICs9IHNpemVvZihzaGFfdGV4dCk7Cj4g Kwo+ICsJfSBlbHNlIGlmIChzaGFfbGVmdG92ZXJzID09IDIpIHsKPiArCQkvKiBXcml0ZSAzMiBi aXRzIG9mIHRleHQgKi8KPiArCQlJOTE1X1dSSVRFKFNLTF9IRENQX1JFUF9DVEwsIHJlcF9jdGwg fCBTS0xfSERDUF9TSEExX1RFWFRfMzIpOwo+ICsJCXNoYV90ZXh0IHw9IGJzdGF0dXNbMF0gPDwg MjQgfCBic3RhdHVzWzFdIDw8IDE2Owo+ICsJCXJldCA9IGludGVsX3dyaXRlX3NoYV90ZXh0KGRl dl9wcml2LCBzaGFfdGV4dCk7Cj4gKwkJaWYgKHJldCA8IDApCj4gKwkJCXJldHVybiByZXQ7Cj4g KwkJc2hhX2lkeCArPSBzaXplb2Yoc2hhX3RleHQpOwo+ICsKPiArCQkvKiBXcml0ZSA2NCBiaXRz IG9mIE0wICovCj4gKwkJSTkxNV9XUklURShTS0xfSERDUF9SRVBfQ1RMLCByZXBfY3RsIHwgU0tM X0hEQ1BfU0hBMV9URVhUXzApOwo+ICsJCWZvciAoaSA9IDA7IGkgPCAyOyBpKyspIHsKPiArCQkJ cmV0ID0gaW50ZWxfd3JpdGVfc2hhX3RleHQoZGV2X3ByaXYsIDApOwo+ICsJCQlpZiAocmV0IDwg MCkKPiArCQkJCXJldHVybiByZXQ7Cj4gKwkJCXNoYV9pZHggKz0gc2l6ZW9mKHNoYV90ZXh0KTsK PiArCQl9Cj4gKwl9IGVsc2UgaWYgKHNoYV9sZWZ0b3ZlcnMgPT0gMykgewo+ICsJCS8qIFdyaXRl IDMyIGJpdHMgb2YgdGV4dCAqLwo+ICsJCUk5MTVfV1JJVEUoU0tMX0hEQ1BfUkVQX0NUTCwgcmVw X2N0bCB8IFNLTF9IRENQX1NIQTFfVEVYVF8zMik7Cj4gKwkJc2hhX3RleHQgfD0gYnN0YXR1c1sw XSA8PCAyNDsKPiArCQlyZXQgPSBpbnRlbF93cml0ZV9zaGFfdGV4dChkZXZfcHJpdiwgc2hhX3Rl eHQpOwo+ICsJCWlmIChyZXQgPCAwKQo+ICsJCQlyZXR1cm4gcmV0Owo+ICsJCXNoYV9pZHggKz0g c2l6ZW9mKHNoYV90ZXh0KTsKPiArCj4gKwkJLyogV3JpdGUgOCBiaXRzIG9mIHRleHQsIDI0IGJp dHMgb2YgTTAgKi8KPiArCQlJOTE1X1dSSVRFKFNLTF9IRENQX1JFUF9DVEwsIHJlcF9jdGwgfCBT S0xfSERDUF9TSEExX1RFWFRfOCk7Cj4gKwkJcmV0ID0gaW50ZWxfd3JpdGVfc2hhX3RleHQoZGV2 X3ByaXYsIGJzdGF0dXNbMV0pOwo+ICsJCWlmIChyZXQgPCAwKQo+ICsJCQlyZXR1cm4gcmV0Owo+ ICsJCXNoYV9pZHggKz0gc2l6ZW9mKHNoYV90ZXh0KTsKPiArCj4gKwkJLyogV3JpdGUgMzIgYml0 cyBvZiBNMCAqLwo+ICsJCUk5MTVfV1JJVEUoU0tMX0hEQ1BfUkVQX0NUTCwgcmVwX2N0bCB8IFNL TF9IRENQX1NIQTFfVEVYVF8wKTsKPiArCQlyZXQgPSBpbnRlbF93cml0ZV9zaGFfdGV4dChkZXZf cHJpdiwgMCk7Cj4gKwkJaWYgKHJldCA8IDApCj4gKwkJCXJldHVybiByZXQ7Cj4gKwkJc2hhX2lk eCArPSBzaXplb2Yoc2hhX3RleHQpOwo+ICsKPiArCQkvKiBXcml0ZSA4IGJpdHMgb2YgTTAgKi8K PiArCQlJOTE1X1dSSVRFKFNLTF9IRENQX1JFUF9DVEwsIHJlcF9jdGwgfCBTS0xfSERDUF9TSEEx X1RFWFRfMjQpOwo+ICsJCXJldCA9IGludGVsX3dyaXRlX3NoYV90ZXh0KGRldl9wcml2LCAwKTsK PiArCQlpZiAocmV0IDwgMCkKPiArCQkJcmV0dXJuIHJldDsKPiArCQlzaGFfaWR4ICs9IHNpemVv ZihzaGFfdGV4dCk7Cj4gKwl9IGVsc2Ugewo+ICsJCURSTV9FUlJPUigiSW52YWxpZCBudW1iZXIg b2YgbGVmdG92ZXJzICVkXG4iLCBzaGFfbGVmdG92ZXJzKTsKPiArCQlyZXR1cm4gLUVJTlZBTDsK PiArCX0KCkknZCBoYXZlIGV4dHJhY3RlZCBhIGxpdHRsZSBoZWxwZXIgdG8gd3JpdGUgdGVoIHNo YV90ZXh0IGJ5dGV3aXNlIHdoaWNoCmludGVybmFsbHkgYWNjdW11bGF0ZXMgaXQgYW5kIHB1c2hl cyBpdCBvdXQgZXZlcnkgMzIgYnl0ZXMuIFdvdWxkIG5lYXRseQpzZXBhcmF0ZSB3aGF0IHdlIHdy aXRlIGZyb20gaG93IHRoZSBzaGEgbWFjaGluZXJ5IHdvcmtzLgoKQnV0IHRoaXMgYSBiaXQgbW9y ZSB2ZXJib3NlIHN0eWxlIHdvcmtzIHRvbyBJIGd1ZXNzLCBzbyBqdXN0IGFuIGlkZWEgaW4KY2Fz ZSB3ZSBldmVyIHNwb3QgYSBidWcgaW4gaGVyZSAoSSBkaWRuJ3QpLgoKPiArCj4gKwlJOTE1X1dS SVRFKFNLTF9IRENQX1JFUF9DVEwsIHJlcF9jdGwgfCBTS0xfSERDUF9TSEExX1RFWFRfMzIpOwo+ ICsJLyogRmlsbCB1cCB0byA2NC00IGJ5dGVzIHdpdGggemVyb3MgKGxlYXZlIHRoZSBsYXN0IHdy aXRlIGZvciBsZW5ndGgpICovCj4gKwl3aGlsZSAoKHNoYV9pZHggJSA2NCkgPCAoNjQgLSBzaXpl b2Yoc2hhX3RleHQpKSkgewo+ICsJCXJldCA9IGludGVsX3dyaXRlX3NoYV90ZXh0KGRldl9wcml2 LCAwKTsKPiArCQlpZiAocmV0IDwgMCkKPiArCQkJcmV0dXJuIHJldDsKPiArCQlzaGFfaWR4ICs9 IHNpemVvZihzaGFfdGV4dCk7Cj4gKwl9Cj4gKwo+ICsJLyoKPiArCSAqIExhc3Qgd3JpdGUgZ2V0 cyB0aGUgbGVuZ3RoIG9mIHRoZSBjb25jYXRlbmF0aW9uIGluIGJpdHMuIFRoYXQgaXM6Cj4gKwkg KiAgLSA1IGJ5dGVzIHBlciBkZXZpY2UKPiArCSAqICAtIDEwIGJ5dGVzIGZvciBCSU5GTy9CU1RB VFVTKDIpLCBNMCg4KQo+ICsJICovCj4gKwlzaGFfdGV4dCA9IChudW1fZG93bnN0cmVhbSAqIDUg KyAxMCkgKiA4Owo+ICsJcmV0ID0gaW50ZWxfd3JpdGVfc2hhX3RleHQoZGV2X3ByaXYsIHNoYV90 ZXh0KTsKPiArCWlmIChyZXQgPCAwKQo+ICsJCXJldHVybiByZXQ7Cj4gKwo+ICsJLyogVGVsbCB0 aGUgSFcgd2UncmUgZG9uZSB3aXRoIHRoZSBoYXNoIGFuZCB3YWl0IGZvciBpdCB0byBBQ0sgKi8K PiArCUk5MTVfV1JJVEUoU0tMX0hEQ1BfUkVQX0NUTCwgcmVwX2N0bCB8IFNLTF9IRENQX1NIQTFf Q09NUExFVEVfSEFTSCk7Cj4gKwlpZiAoaW50ZWxfd2FpdF9mb3JfcmVnaXN0ZXIoZGV2X3ByaXYs IFNLTF9IRENQX1JFUF9DVEwsCj4gKwkJCQkgICAgU0tMX0hEQ1BfU0hBMV9DT01QTEVURSwKPiAr CQkJCSAgICBTS0xfSERDUF9TSEExX0NPTVBMRVRFLCAxKSkgewo+ICsJCURSTV9FUlJPUigiVGlt ZWQgb3V0IHdhaXRpbmcgZm9yIFNIQTEgY29tcGxldGVcbiIpOwo+ICsJCXJldHVybiAtRVRJTUVE T1VUOwo+ICsJfQo+ICsJaWYgKCEoSTkxNV9SRUFEKFNLTF9IRENQX1JFUF9DVEwpICYgU0tMX0hE Q1BfU0hBMV9WX01BVENIKSkgewo+ICsJCURSTV9FUlJPUigiU0hBLTEgbWlzbWF0Y2gsIEhEQ1Ag ZmFpbGVkXG4iKTsKPiArCQlyZXR1cm4gLUVOWElPOwo+ICsJfQo+ICsKPiArCURSTV9JTkZPKCJI RENQIGlzIGVuYWJsZWQgKCVkIGRvd25zdHJlYW0gZGV2aWNlcylcbiIsIG51bV9kb3duc3RyZWFt KTsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICsvKiBJbXBsZW1lbnRzIFBhcnQgMSBvZiB0aGUg SERDUCBhdXRob3JpemF0aW9uIHByb2NlZHVyZSAqLwo+ICtzdGF0aWMgaW50IGludGVsX2hkY3Bf YXV0aChzdHJ1Y3QgaW50ZWxfZGlnaXRhbF9wb3J0ICppbnRlbF9kaWdfcG9ydCwKPiArCQkJICAg Y29uc3Qgc3RydWN0IGludGVsX2hkY3Bfc2hpbSAqc2hpbSkKPiArewo+ICsJc3RydWN0IGRybV9p OTE1X3ByaXZhdGUgKmRldl9wcml2Owo+ICsJZW51bSBwb3J0IHBvcnQ7Cj4gKwl1bnNpZ25lZCBs b25nIHIwX3ByaW1lX2dlbl9zdGFydDsKPiArCWludCByZXQsIGk7Cj4gKwl1bmlvbiB7Cj4gKwkJ dTMyIHJlZ1syXTsKPiArCQl1OCBzaGltW0RSTV9IRENQX0FOX0xFTl07Cj4gKwl9IGFuOwo+ICsJ dW5pb24gewo+ICsJCXUzMiByZWdbMl07Cj4gKwkJdTggc2hpbVtEUk1fSERDUF9LU1ZfTEVOXTsK PiArCX0gYmtzdjsKPiArCXVuaW9uIHsKPiArCQl1MzIgcmVnOwo+ICsJCXU4IHNoaW1bRFJNX0hE Q1BfUklfTEVOXTsKPiArCX0gcmk7Cj4gKwlib29sIHJlcGVhdGVyX3ByZXNlbnQ7Cj4gKwo+ICsJ ZGV2X3ByaXYgPSBpbnRlbF9kaWdfcG9ydC0+YmFzZS5iYXNlLmRldi0+ZGV2X3ByaXZhdGU7Cj4g Kwo+ICsJcG9ydCA9IGludGVsX2RpZ19wb3J0LT5iYXNlLnBvcnQ7Cj4gKwo+ICsJLyogSW5pdGlh bGl6ZSBBbiB3aXRoIDIgcmFuZG9tIHZhbHVlcyBhbmQgYWNxdWlyZSBpdCAqLwo+ICsJZm9yIChp ID0gMDsgaSA8IDI7IGkrKykKPiArCQlJOTE1X1dSSVRFKFNLTF9QT1JUX0hEQ1BfQU5JTklUKHBv cnQpLCBnZXRfcmFuZG9tX2xvbmcoKSk7CgpuaXQ6IGdldF9yYW5kb21fdTMyIGluc3RhZCBvZiBn ZXRfcmFuZG9tX2xvbmc/Cgo+ICsJSTkxNV9XUklURShTS0xfUE9SVF9IRENQX0NPTkYocG9ydCks IFNLTF9IRENQX0NPTkZfQ0FQVFVSRV9BTik7Cj4gKwo+ICsJLyogV2FpdCBmb3IgQW4gdG8gYmUg YWNxdWlyZWQgKi8KPiArCWlmIChpbnRlbF93YWl0X2Zvcl9yZWdpc3RlcihkZXZfcHJpdiwgU0tM X1BPUlRfSERDUF9TVEFUVVMocG9ydCksCj4gKwkJCQkgICAgU0tMX0hEQ1BfU1RBVFVTX0FOX1JF QURZLAo+ICsJCQkJICAgIFNLTF9IRENQX1NUQVRVU19BTl9SRUFEWSwgMSkpIHsKPiArCQlEUk1f RVJST1IoIlRpbWVkIG91dCB3YWl0aW5nIGZvciBBblxuIik7Cj4gKwkJcmV0dXJuIC1FVElNRURP VVQ7Cj4gKwl9Cj4gKwo+ICsJYW4ucmVnWzBdID0gSTkxNV9SRUFEKFNLTF9QT1JUX0hEQ1BfQU5M Tyhwb3J0KSk7Cj4gKwlhbi5yZWdbMV0gPSBJOTE1X1JFQUQoU0tMX1BPUlRfSERDUF9BTkhJKHBv cnQpKTsKPiArCXJldCA9IHNoaW0tPndyaXRlX2FuX2Frc3YoaW50ZWxfZGlnX3BvcnQsIGFuLnNo aW0pOwo+ICsJaWYgKHJldCkKPiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCXIwX3ByaW1lX2dlbl9z dGFydCA9IGppZmZpZXM7Cj4gKwo+ICsJbWVtc2V0KCZia3N2LCAwLCBzaXplb2YoYmtzdikpOwo+ ICsJcmV0ID0gc2hpbS0+cmVhZF9ia3N2KGludGVsX2RpZ19wb3J0LCBia3N2LnNoaW0pOwo+ICsJ aWYgKHJldCkKPiArCQlyZXR1cm4gcmV0Owo+ICsKPiArCUk5MTVfV1JJVEUoU0tMX1BPUlRfSERD UF9CS1NWTE8ocG9ydCksIGJrc3YucmVnWzBdKTsKPiArCUk5MTVfV1JJVEUoU0tMX1BPUlRfSERD UF9CS1NWSEkocG9ydCksIGJrc3YucmVnWzFdKTsKPiArCj4gKwlyZXQgPSBzaGltLT5yZXBlYXRl cl9wcmVzZW50KGludGVsX2RpZ19wb3J0LCAmcmVwZWF0ZXJfcHJlc2VudCk7Cj4gKwlpZiAocmV0 KQo+ICsJCXJldHVybiByZXQ7Cj4gKwlpZiAocmVwZWF0ZXJfcHJlc2VudCkKPiArCQlJOTE1X1dS SVRFKFNLTF9IRENQX1JFUF9DVEwsCj4gKwkJCSAgIGludGVsX2hkY3BfZ2V0X3JlcGVhdGVyX2N0 bChpbnRlbF9kaWdfcG9ydCkpOwo+ICsKPiArCXJldCA9IHNoaW0tPnRvZ2dsZV9zaWduYWxsaW5n KGludGVsX2RpZ19wb3J0LCB0cnVlKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiAr Cj4gKwlJOTE1X1dSSVRFKFNLTF9QT1JUX0hEQ1BfQ09ORihwb3J0KSwgU0tMX0hEQ1BfQ09ORl9B VVRIX0FORF9FTkMpOwo+ICsKPiArCS8qIFdhaXQgZm9yIFIwIHJlYWR5ICovCj4gKwlpZiAod2Fp dF9mb3IoSTkxNV9SRUFEKFNLTF9QT1JUX0hEQ1BfU1RBVFVTKHBvcnQpKSAmCj4gKwkJICAgICAo U0tMX0hEQ1BfU1RBVFVTX1IwX1JFQURZIHwgU0tMX0hEQ1BfU1RBVFVTX0VOQyksIDEpKSB7Cj4g KwkJRFJNX0VSUk9SKCJUaW1lZCBvdXQgd2FpdGluZyBmb3IgUjAgcmVhZHlcbiIpOwo+ICsJCXJl dHVybiAtRVRJTUVET1VUOwo+ICsJfQo+ICsKPiArCS8qCj4gKwkgKiBXYWl0IGZvciBSMCcgdG8g YmVjb21lIGF2YWlsYWJsZSwgdGhlIHNwZWMgc2F5cyAxMDBtcyBmcm9tIEFrc3YKPiArCSAqIHdy aXRlLiBPbiBEUCwgdGhlcmUncyBhbiBSMF9SRUFEWSBiaXQgYXZhaWxhYmxlIGJ1dCBubyBzdWNo IGJpdAo+ICsJICogZXhpc3RzIG9uIEhETUkuIFNpbmNlIHRoZSB1cHBlci1ib3VuZCBpcyB0aGUg c2FtZSwgd2UnbGwganVzdCBkbwo+ICsJICogdGhlIHN0dXBpZCB0aGluZyBpbnN0ZWFkIG9mIHBv bGxpbmcgb24gb25lIGFuZCBub3QgdGhlIG90aGVyLgo+ICsJICovCj4gKwl3YWl0X3JlbWFpbmlu Z19tc19mcm9tX2ppZmZpZXMocjBfcHJpbWVfZ2VuX3N0YXJ0LCAxMDApOwo+ICsKPiArCXJpLnJl ZyA9IDA7Cj4gKwlyZXQgPSBzaGltLT5yZWFkX3JpX3ByaW1lKGludGVsX2RpZ19wb3J0LCByaS5z aGltKTsKPiArCWlmIChyZXQpCj4gKwkJcmV0dXJuIHJldDsKPiArCUk5MTVfV1JJVEUoU0tMX1BP UlRfSERDUF9SUFJJTUUocG9ydCksIHJpLnJlZyk7Cj4gKwo+ICsJLyogV2FpdCBmb3IgUmkgcHJp bWUgbWF0Y2ggKi8KPiArCWlmICh3YWl0X2ZvcihJOTE1X1JFQUQoU0tMX1BPUlRfSERDUF9TVEFU VVMocG9ydCkpICYKPiArCQkgICAgIChTS0xfSERDUF9TVEFUVVNfUklfTUFUQ0ggfCBTS0xfSERD UF9TVEFUVVNfRU5DKSwgMSkpIHsKPiArCQlEUk1fRVJST1IoIlRpbWVkIG91dCB3YWl0aW5nIGZv ciBSaSBwcmltZSBtYXRjaCAoJXgpXG4iLAo+ICsJCQkgIEk5MTVfUkVBRChTS0xfUE9SVF9IRENQ X1NUQVRVUyhwb3J0KSkpOwo+ICsJCXJldHVybiAtRVRJTUVET1VUOwo+ICsJfQo+ICsKPiArCS8q IFdhaXQgZm9yIGVuY3J5cHRpb24gY29uZmlybWF0aW9uICovCj4gKwlpZiAoaW50ZWxfd2FpdF9m b3JfcmVnaXN0ZXIoZGV2X3ByaXYsIFNLTF9QT1JUX0hEQ1BfU1RBVFVTKHBvcnQpLAo+ICsJCQkJ ICAgIFNLTF9IRENQX1NUQVRVU19FTkMsCj4gKwkJCQkgICAgU0tMX0hEQ1BfU1RBVFVTX0VOQywg MjApKSB7Cj4gKwkJRFJNX0VSUk9SKCJUaW1lZCBvdXQgd2FpdGluZyBmb3IgZW5jcnlwdGlvblxu Iik7Cj4gKwkJcmV0dXJuIC1FVElNRURPVVQ7Cj4gKwl9Cj4gKwo+ICsJLyoKPiArCSAqIFhYWDog SWYgd2UgaGF2ZSBNU1QtY29ubmVjdGVkIGRldmljZXMsIHdlIG5lZWQgdG8gZW5hYmxlIGVuY3J5 cHRpb24KPiArCSAqIG9uIHRob3NlIGFzIHdlbGwuCj4gKwkgKi8KCkp1c3QgYW4gYXNpZGU6IEkg dGhpbmsgd2UgY2FuIHN0dWZmIHRoZSBEREkgc3RyZWFtIHNwZWNpZmljIHN0dWZmIGludG8KdGhl IHRvZ2dsZV9zaWduYWxsaW5nIGNhbGxiYWNrLiBCdXQgbm90IGVudGlyZWx5IHN1cmUuCgo+ICsK PiArCXJldHVybiBpbnRlbF9oZGNwX2F1dGhfZG93bnN0cmVhbShpbnRlbF9kaWdfcG9ydCwgc2hp bSk7Cj4gK30KPiArCj4gK3N0YXRpYwo+ICtzdHJ1Y3QgaW50ZWxfZGlnaXRhbF9wb3J0ICpjb25u X3RvX2RpZ19wb3J0KHN0cnVjdCBpbnRlbF9jb25uZWN0b3IgKmNvbm5lY3RvcikKPiArewo+ICsJ cmV0dXJuIGVuY190b19kaWdfcG9ydCgmaW50ZWxfYXR0YWNoZWRfZW5jb2RlcigmY29ubmVjdG9y LT5iYXNlKS0+YmFzZSk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgX2ludGVsX2hkY3BfZGlzYWJs ZShzdHJ1Y3QgaW50ZWxfY29ubmVjdG9yICpjb25uZWN0b3IpCj4gK3sKPiArCXN0cnVjdCBkcm1f aTkxNV9wcml2YXRlICpkZXZfcHJpdiA9IGNvbm5lY3Rvci0+YmFzZS5kZXYtPmRldl9wcml2YXRl Owo+ICsJc3RydWN0IGludGVsX2RpZ2l0YWxfcG9ydCAqaW50ZWxfZGlnX3BvcnQgPSBjb25uX3Rv X2RpZ19wb3J0KGNvbm5lY3Rvcik7Cj4gKwllbnVtIHBvcnQgcG9ydCA9IGludGVsX2RpZ19wb3J0 LT5iYXNlLnBvcnQ7Cj4gKwlpbnQgcmV0Owo+ICsKPiArCUk5MTVfV1JJVEUoU0tMX1BPUlRfSERD UF9DT05GKHBvcnQpLCAwKTsKPiArCWlmIChpbnRlbF93YWl0X2Zvcl9yZWdpc3RlcihkZXZfcHJp diwgU0tMX1BPUlRfSERDUF9TVEFUVVMocG9ydCksIH4wLCAwLAo+ICsJCQkJICAgIDIwKSkgewo+ ICsJCURSTV9FUlJPUigiRmFpbGVkIHRvIGRpc2FibGUgSERDUCwgdGltZW91dCBjbGVhcmluZyBz dGF0dXNcbiIpOwo+ICsJCXJldHVybiAtRVRJTUVET1VUOwo+ICsJfQo+ICsKPiArCWludGVsX2hk Y3BfY2xlYXJfa2V5cyhkZXZfcHJpdik7Cj4gKwo+ICsJcmV0ID0gY29ubmVjdG9yLT5oZGNwX3No aW0tPnRvZ2dsZV9zaWduYWxsaW5nKGludGVsX2RpZ19wb3J0LCBmYWxzZSk7Cj4gKwlpZiAocmV0 KSB7Cj4gKwkJRFJNX0VSUk9SKCJGYWlsZWQgdG8gZGlzYWJsZSBIRENQIHNpZ25hbGxpbmdcbiIp Owo+ICsJCXJldHVybiByZXQ7Cj4gKwl9Cj4gKwo+ICsJRFJNX0lORk8oIkhEQ1AgaXMgZGlzYWJs ZWRcbiIpOwo+ICsJcmV0dXJuIDA7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgX2ludGVsX2hkY3Bf ZW5hYmxlKHN0cnVjdCBpbnRlbF9jb25uZWN0b3IgKmNvbm5lY3RvcikKPiArewo+ICsJc3RydWN0 IGRybV9pOTE1X3ByaXZhdGUgKmRldl9wcml2ID0gY29ubmVjdG9yLT5iYXNlLmRldi0+ZGV2X3By aXZhdGU7Cj4gKwlpbnQgaSwgcmV0Owo+ICsKPiArCWlmICghKEk5MTVfUkVBRChTS0xfRlVTRV9T VEFUVVMpICYgU0tMX0ZVU0VfUEdfRElTVF9TVEFUVVMoMSkpKSB7Cj4gKwkJRFJNX0VSUk9SKCJQ RzEgaXMgZGlzYWJsZWQsIGNhbm5vdCBsb2FkIGtleXNcbiIpOwo+ICsJCXJldHVybiAtRU5YSU87 Cj4gKwl9Cj4gKwo+ICsJZm9yIChpID0gMDsgaSA8IEtFWV9MT0FEX1RSSUVTOyBpKyspIHsKPiAr CQlyZXQgPSBpbnRlbF9oZGNwX2xvYWRfa2V5cyhkZXZfcHJpdik7Cj4gKwkJaWYgKCFyZXQpCj4g KwkJCWJyZWFrOwo+ICsJCWludGVsX2hkY3BfY2xlYXJfa2V5cyhkZXZfcHJpdik7Cj4gKwl9Cj4g KwlpZiAocmV0KSB7Cj4gKwkJRFJNX0VSUk9SKCJDb3VsZCBub3QgbG9hZCBIRENQIGtleXMsICgl ZClcbiIsIHJldCk7Cj4gKwkJcmV0dXJuIHJldDsKPiArCX0KPiArCj4gKwlyZXQgPSBpbnRlbF9o ZGNwX2F1dGgoY29ubl90b19kaWdfcG9ydChjb25uZWN0b3IpLAo+ICsJCQkgICAgICBjb25uZWN0 b3ItPmhkY3Bfc2hpbSk7Cj4gKwlpZiAocmV0KSB7Cj4gKwkJRFJNX0VSUk9SKCJGYWlsZWQgdG8g YXV0aGVudGljYXRlIEhEQ1AgKCVkKVxuIiwgcmV0KTsKPiArCQlyZXR1cm4gcmV0Owo+ICsJfQo+ ICsKPiArCXJldHVybiAwOwo+ICt9Cj4gKwo+ICt2b2lkIGludGVsX2hkY3BfY2hlY2tfd29yayhz dHJ1Y3Qgd29ya19zdHJ1Y3QgKndvcmspCj4gK3sKPiArCXN0cnVjdCBpbnRlbF9jb25uZWN0b3Ig KmNvbm5lY3RvciA9IGNvbnRhaW5lcl9vZih0b19kZWxheWVkX3dvcmsod29yayksCj4gKwkJCQkJ CQkgc3RydWN0IGludGVsX2Nvbm5lY3RvciwKPiArCQkJCQkJICAgICAgICAgaGRjcF9jaGVja193 b3JrKTsKPiArCWlmICghaW50ZWxfaGRjcF9jaGVja19saW5rKGNvbm5lY3RvcikpCj4gKwkJc2No ZWR1bGVfZGVsYXllZF93b3JrKCZjb25uZWN0b3ItPmhkY3BfY2hlY2tfd29yaywKPiArCQkJCSAg ICAgIERSTV9IRENQX0NIRUNLX1BFUklPRF9NUyk7Cj4gK30KPiArCj4gK3ZvaWQgaW50ZWxfaGRj cF9wcm9wX3dvcmsoc3RydWN0IHdvcmtfc3RydWN0ICp3b3JrKQo+ICt7Cj4gKwlzdHJ1Y3QgaW50 ZWxfY29ubmVjdG9yICpjb25uZWN0b3IgPSBjb250YWluZXJfb2Yod29yaywKPiArCQkJCQkJCSBz dHJ1Y3QgaW50ZWxfY29ubmVjdG9yLAo+ICsJCQkJCQkgICAgICAgICBoZGNwX3Byb3Bfd29yayk7 Cj4gKwlzdHJ1Y3QgZHJtX2RldmljZSAqZGV2ID0gY29ubmVjdG9yLT5iYXNlLmRldjsKPiArCXN0 cnVjdCBkcm1fY29ubmVjdG9yX3N0YXRlICpzdGF0ZTsKPiArCj4gKwltdXRleF9sb2NrKCZkZXYt Pm1vZGVfY29uZmlnLm11dGV4KTsKCllvdSBkb24ndCBuZWVkIHRoaXMgbG9jayBoZXJlLiBPbmx5 IGNvbm5lY3Rpb25fbXV0ZXggaXMgbmVlZGVkIHRvIHByb3RlY3QKY29ubmVjdG9yLT5zdGF0dXMu Cgo+ICsJZHJtX21vZGVzZXRfbG9jaygmZGV2LT5tb2RlX2NvbmZpZy5jb25uZWN0aW9uX211dGV4 LCBOVUxMKTsKPiArCW11dGV4X2xvY2soJmNvbm5lY3Rvci0+aGRjcF9tdXRleCk7Cj4gKwo+ICsJ LyoKPiArCSAqIFRoaXMgd29ya2VyIGlzIG9ubHkgdXNlZCB0byBmbGlwIGJldHdlZW4gRU5BQkxF RC9ERVNJUkVELiBFaXRoZXIgb2YKPiArCSAqIHRob3NlIHRvIE9GRiBpcyBoYW5kbGVkIGJ5IGNv cmUuIElmIGhkY3BfdmFsdWUgPT0gT0ZGLCB3ZSdyZSBydW5uaW5nCj4gKwkgKiBqdXN0IGFmdGVy IGhkY3AgaGFzIGJlZW4gZGlzYWJsZWQsIHNvIGp1c3QgZXhpdAo+ICsJICovCj4gKwlpZiAoY29u bmVjdG9yLT5oZGNwX3ZhbHVlICE9IERSTV9NT0RFX0NPTlRFTlRfUFJPVEVDVElPTl9PRkYpIHsK PiArCQlzdGF0ZSA9IGNvbm5lY3Rvci0+YmFzZS5zdGF0ZTsKPiArCQlzdGF0ZS0+Y29udGVudF9w cm90ZWN0aW9uID0gY29ubmVjdG9yLT5oZGNwX3ZhbHVlOwo+ICsJfQo+ICsKPiArCW11dGV4X3Vu bG9jaygmY29ubmVjdG9yLT5oZGNwX211dGV4KTsKPiArCWRybV9tb2Rlc2V0X3VubG9jaygmZGV2 LT5tb2RlX2NvbmZpZy5jb25uZWN0aW9uX211dGV4KTsKPiArCW11dGV4X3VubG9jaygmZGV2LT5t b2RlX2NvbmZpZy5tdXRleCk7Cj4gK30KPiArCj4gK3N0YXRpYyBpbnQgaW50ZWxfaGRjcF9lbmFi bGUoc3RydWN0IGludGVsX2Nvbm5lY3RvciAqY29ubmVjdG9yKQo+ICt7Cj4gKwlpbnQgcmV0Owo+ ICsKPiArCWlmICghY29ubmVjdG9yLT5oZGNwX3NoaW0pCj4gKwkJcmV0dXJuIC1FTk9FTlQ7Cj4g Kwo+ICsJbXV0ZXhfbG9jaygmY29ubmVjdG9yLT5oZGNwX211dGV4KTsKPiArCj4gKwlyZXQgPSBf aW50ZWxfaGRjcF9lbmFibGUoY29ubmVjdG9yKTsKPiArCWlmIChyZXQpCj4gKwkJZ290byBvdXQ7 Cj4gKwo+ICsJY29ubmVjdG9yLT5oZGNwX3ZhbHVlID0gRFJNX01PREVfQ09OVEVOVF9QUk9URUNU SU9OX0VOQUJMRUQ7Cj4gKwlzY2hlZHVsZV93b3JrKCZjb25uZWN0b3ItPmhkY3BfcHJvcF93b3Jr KTsKPiArCXNjaGVkdWxlX2RlbGF5ZWRfd29yaygmY29ubmVjdG9yLT5oZGNwX2NoZWNrX3dvcmss Cj4gKwkJCSAgICAgIERSTV9IRENQX0NIRUNLX1BFUklPRF9NUyk7Cj4gK291dDoKPiArCW11dGV4 X3VubG9jaygmY29ubmVjdG9yLT5oZGNwX211dGV4KTsKPiArCXJldHVybiByZXQ7Cj4gK30KPiAr Cj4gK3N0YXRpYyBpbnQgaW50ZWxfaGRjcF9kaXNhYmxlKHN0cnVjdCBpbnRlbF9jb25uZWN0b3Ig KmNvbm5lY3RvcikKPiArewo+ICsJaW50IHJldDsKPiArCj4gKwlpZiAoIWNvbm5lY3Rvci0+aGRj cF9zaGltKQo+ICsJCXJldHVybiAtRU5PRU5UOwo+ICsKPiArCW11dGV4X2xvY2soJmNvbm5lY3Rv ci0+aGRjcF9tdXRleCk7Cj4gKwo+ICsJY29ubmVjdG9yLT5oZGNwX3ZhbHVlID0gRFJNX01PREVf Q09OVEVOVF9QUk9URUNUSU9OX09GRjsKPiArCXJldCA9IF9pbnRlbF9oZGNwX2Rpc2FibGUoY29u bmVjdG9yKTsKPiArCj4gKwltdXRleF91bmxvY2soJmNvbm5lY3Rvci0+aGRjcF9tdXRleCk7Cj4g KwljYW5jZWxfZGVsYXllZF93b3JrX3N5bmMoJmNvbm5lY3Rvci0+aGRjcF9jaGVja193b3JrKTsK PiArCXJldHVybiByZXQ7Cj4gK30KPiArCj4gK3ZvaWQgaW50ZWxfaGRjcF9hdG9taWNfY2hlY2so c3RydWN0IGRybV9jb25uZWN0b3IgKmNvbm5lY3RvciwKPiArCQkJICAgICBzdHJ1Y3QgZHJtX2Nv bm5lY3Rvcl9zdGF0ZSAqb2xkX3N0YXRlLAo+ICsJCQkgICAgIHN0cnVjdCBkcm1fY29ubmVjdG9y X3N0YXRlICpuZXdfc3RhdGUpCj4gK3sKPiArCXVpbnQ2NF90IG9sZF9jcCA9IG9sZF9zdGF0ZS0+ Y29udGVudF9wcm90ZWN0aW9uOwo+ICsJdWludDY0X3QgbmV3X2NwID0gbmV3X3N0YXRlLT5jb250 ZW50X3Byb3RlY3Rpb247Cj4gKwo+ICsJaWYgKCFuZXdfc3RhdGUtPmNydGMpIHsKPiArCQkvKgo+ ICsJCSAqIElmIHRoZSBjb25uZWN0b3IgaXMgYmVpbmcgZGlzYWJsZWQgd2l0aCBDUCBlbmFibGVk LCBtYXJrIGl0Cj4gKwkJICogZGVzaXJlZCBzbyBpdCdzIHJlLWVuYWJsZWQgd2hlbiB0aGUgY29u bmVjdG9yIGlzIGJyb3VnaHQgYmFjawo+ICsJCSAqLwo+ICsJCWlmIChvbGRfY3AgPT0gRFJNX01P REVfQ09OVEVOVF9QUk9URUNUSU9OX0VOQUJMRUQpCj4gKwkJCW5ld19zdGF0ZS0+Y29udGVudF9w cm90ZWN0aW9uID0KPiArCQkJCURSTV9NT0RFX0NPTlRFTlRfUFJPVEVDVElPTl9ERVNJUkVEOwo+ ICsJCXJldHVybjsKPiArCX0KPiArCj4gKwkvKiBPbmx5IGRyaXZlcnMgY2FuIHNldCBjb250ZW50 IHByb3RlY3Rpb24gZW5hYmxlZCAqLwo+ICsJaWYgKG9sZF9jcCAhPSBEUk1fTU9ERV9DT05URU5U X1BST1RFQ1RJT05fRU5BQkxFRCAmJgo+ICsJICAgIG5ld19jcCA9PSBEUk1fTU9ERV9DT05URU5U X1BST1RFQ1RJT05fRU5BQkxFRCkKPiArCQluZXdfc3RhdGUtPmNvbnRlbnRfcHJvdGVjdGlvbiA9 Cj4gKwkJCURSTV9NT0RFX0NPTlRFTlRfUFJPVEVDVElPTl9ERVNJUkVEOwo+ICt9Cj4gKwo+ICt2 b2lkIGludGVsX2hkY3BfYXRvbWljX3ByZV9jb21taXQoc3RydWN0IGRybV9jb25uZWN0b3IgKmNv bm5lY3RvciwKPiArCQkJICAgICAgICAgIHN0cnVjdCBkcm1fY29ubmVjdG9yX3N0YXRlICpvbGRf c3RhdGUsCj4gKwkJCSAgICAgICAgICBzdHJ1Y3QgZHJtX2Nvbm5lY3Rvcl9zdGF0ZSAqbmV3X3N0 YXRlKQo+ICt7Cj4gKwl1aW50NjRfdCBvbGRfY3AgPSBvbGRfc3RhdGUtPmNvbnRlbnRfcHJvdGVj dGlvbjsKPiArCXVpbnQ2NF90IG5ld19jcCA9IG5ld19zdGF0ZS0+Y29udGVudF9wcm90ZWN0aW9u Owo+ICsKPiArCS8qCj4gKwkgKiBEaXNhYmxlIEhEQ1AgaWYgdGhlIGNvbm5lY3RvciBpcyBiZWNv bWluZyBkaXNhYmxlZCwgb3IgaWYgcmVxdWVzdGVkCj4gKwkgKiB2aWEgdGhlIHByb3BlcnR5Lgo+ ICsJICovCj4gKwlpZiAoKCFuZXdfc3RhdGUtPmNydGMgJiYgb2xkX2NwICE9IERSTV9NT0RFX0NP TlRFTlRfUFJPVEVDVElPTl9PRkYpIHx8Cj4gKwkgICAgKG5ld19zdGF0ZS0+Y3J0YyAmJiBvbGRf Y3AgIT0gRFJNX01PREVfQ09OVEVOVF9QUk9URUNUSU9OX09GRiAmJgo+ICsJICAgICBuZXdfY3Ag PT0gRFJNX01PREVfQ09OVEVOVF9QUk9URUNUSU9OX09GRikpCj4gKwkJaW50ZWxfaGRjcF9kaXNh YmxlKHRvX2ludGVsX2Nvbm5lY3Rvcihjb25uZWN0b3IpKTsKPiArfQo+ICsKPiArdm9pZCBpbnRl bF9oZGNwX2F0b21pY19jb21taXQoc3RydWN0IGRybV9jb25uZWN0b3IgKmNvbm5lY3RvciwKPiAr CQkJICAgICAgc3RydWN0IGRybV9jb25uZWN0b3Jfc3RhdGUgKm5ld19zdGF0ZSkKPiArewo+ICsJ dWludDY0X3QgbmV3X2NwID0gbmV3X3N0YXRlLT5jb250ZW50X3Byb3RlY3Rpb247Cj4gKwo+ICsJ LyogRW5hYmxlIGhkY3AgaWYgaXQncyBkZXNpcmVkICovCj4gKwlpZiAobmV3X3N0YXRlLT5jcnRj ICYmIG5ld19jcCA9PSBEUk1fTU9ERV9DT05URU5UX1BST1RFQ1RJT05fREVTSVJFRCkKPiArCQlp bnRlbF9oZGNwX2VuYWJsZSh0b19pbnRlbF9jb25uZWN0b3IoY29ubmVjdG9yKSk7Cj4gK30KPiAr Cj4gKy8qIEltcGxlbWVudHMgUGFydCAzIG9mIHRoZSBIRENQIGF1dGhvcml6YXRpb24gcHJvY2Vk dXJlICovCj4gK2ludCBpbnRlbF9oZGNwX2NoZWNrX2xpbmsoc3RydWN0IGludGVsX2Nvbm5lY3Rv ciAqY29ubmVjdG9yKQo+ICt7Cj4gKwlzdHJ1Y3QgZHJtX2k5MTVfcHJpdmF0ZSAqZGV2X3ByaXYg PSBjb25uZWN0b3ItPmJhc2UuZGV2LT5kZXZfcHJpdmF0ZTsKPiArCXN0cnVjdCBpbnRlbF9kaWdp dGFsX3BvcnQgKmludGVsX2RpZ19wb3J0ID0gY29ubl90b19kaWdfcG9ydChjb25uZWN0b3IpOwo+ ICsJZW51bSBwb3J0IHBvcnQgPSBpbnRlbF9kaWdfcG9ydC0+YmFzZS5wb3J0Owo+ICsJaW50IHJl dCA9IDA7Cj4gKwo+ICsJaWYgKCFjb25uZWN0b3ItPmhkY3Bfc2hpbSkKPiArCQlyZXR1cm4gLUVO T0VOVDsKPiArCj4gKwltdXRleF9sb2NrKCZjb25uZWN0b3ItPmhkY3BfbXV0ZXgpOwo+ICsKPiAr CWlmIChjb25uZWN0b3ItPmhkY3BfdmFsdWUgPT0gRFJNX01PREVfQ09OVEVOVF9QUk9URUNUSU9O X09GRikKPiArCQlnb3RvIG91dDsKPiArCj4gKwlpZiAoIShJOTE1X1JFQUQoU0tMX1BPUlRfSERD UF9TVEFUVVMocG9ydCkpICYgU0tMX0hEQ1BfU1RBVFVTX0VOQykpIHsKPiArCQlEUk1fRVJST1Io IkhEQ1AgY2hlY2sgZmFpbGVkOiBsaW5rIGlzIG5vdCBlbmNyeXB0ZWQsICV4XG4iLAo+ICsJCQkg ICBJOTE1X1JFQUQoU0tMX1BPUlRfSERDUF9TVEFUVVMocG9ydCkpKTsKPiArCQlyZXQgPSAtRU5Y SU87Cj4gKwkJY29ubmVjdG9yLT5oZGNwX3ZhbHVlID0gRFJNX01PREVfQ09OVEVOVF9QUk9URUNU SU9OX0RFU0lSRUQ7Cj4gKwkJc2NoZWR1bGVfd29yaygmY29ubmVjdG9yLT5oZGNwX3Byb3Bfd29y ayk7Cj4gKwkJZ290byBvdXQ7Cj4gKwl9Cj4gKwo+ICsJaWYgKGNvbm5lY3Rvci0+aGRjcF9zaGlt LT5jaGVja19saW5rKGludGVsX2RpZ19wb3J0KSkgewo+ICsJCWlmIChjb25uZWN0b3ItPmhkY3Bf dmFsdWUgIT0gRFJNX01PREVfQ09OVEVOVF9QUk9URUNUSU9OX09GRikgewo+ICsJCQljb25uZWN0 b3ItPmhkY3BfdmFsdWUgPQo+ICsJCQkJRFJNX01PREVfQ09OVEVOVF9QUk9URUNUSU9OX0VOQUJM RUQ7Cj4gKwkJCXNjaGVkdWxlX3dvcmsoJmNvbm5lY3Rvci0+aGRjcF9wcm9wX3dvcmspOwo+ICsJ CX0KPiArCQlnb3RvIG91dDsKPiArCX0KPiArCj4gKwlEUk1fSU5GTygiSERDUCBsaW5rIGZhaWxl ZCwgcmV0cnlpbmcgYXV0aGVudGljYXRpb25cbiIpOwo+ICsKPiArCXJldCA9IF9pbnRlbF9oZGNw X2Rpc2FibGUoY29ubmVjdG9yKTsKPiArCWlmIChyZXQpIHsKPiArCQlEUk1fRVJST1IoIkZhaWxl ZCB0byBkaXNhYmxlIGhkY3AgKCVkKVxuIiwgcmV0KTsKPiArCQljb25uZWN0b3ItPmhkY3BfdmFs dWUgPSBEUk1fTU9ERV9DT05URU5UX1BST1RFQ1RJT05fREVTSVJFRDsKPiArCQlzY2hlZHVsZV93 b3JrKCZjb25uZWN0b3ItPmhkY3BfcHJvcF93b3JrKTsKPiArCQlnb3RvIG91dDsKPiArCX0KPiAr Cj4gKwlyZXQgPSBfaW50ZWxfaGRjcF9lbmFibGUoY29ubmVjdG9yKTsKPiArCWlmIChyZXQpIHsK PiArCQlEUk1fRVJST1IoIkZhaWxlZCB0byBlbmFibGUgaGRjcCAoJWQpXG4iLCByZXQpOwo+ICsJ CWNvbm5lY3Rvci0+aGRjcF92YWx1ZSA9IERSTV9NT0RFX0NPTlRFTlRfUFJPVEVDVElPTl9ERVNJ UkVEOwo+ICsJCXNjaGVkdWxlX3dvcmsoJmNvbm5lY3Rvci0+aGRjcF9wcm9wX3dvcmspOwo+ICsJ CWdvdG8gb3V0Owo+ICsJfQo+ICsKPiArb3V0Ogo+ICsJbXV0ZXhfdW5sb2NrKCZjb25uZWN0b3It PmhkY3BfbXV0ZXgpOwo+ICsJcmV0dXJuIHJldDsKPiArfQoKV2l0aCB0aGUgY29tbWVudHMgYWRk cmVzc2VkOgoKUmV2aWV3ZWQtYnk6IERhbmllbCBWZXR0ZXIgPGRhbmllbC52ZXR0ZXJAZmZ3bGwu Y2g+CgpBbHNvIGNvdW50cyBmb3IgdGhlIHJlZyByZW5hbWluZyBwYXRjaCBpZiB5b3Ugd2FudCB0 byBkbyB0aGF0IGFzIGEKZm9sbG93LXVwIGluIHRoaXMgc2VyaWVzIDotKQotRGFuaWVsCgo+IC0t IAo+IDIuMTUuMC41MzEuZzJjY2IzMDEyYzktZ29vZwo+IAo+IF9fX19fX19fX19fX19fX19fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fCj4gZHJpLWRldmVsIG1haWxpbmcgbGlzdAo+IGRy aS1kZXZlbEBsaXN0cy5mcmVlZGVza3RvcC5vcmcKPiBodHRwczovL2xpc3RzLmZyZWVkZXNrdG9w Lm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAoKLS0gCkRhbmllbCBWZXR0ZXIKU29mdHdh cmUgRW5naW5lZXIsIEludGVsIENvcnBvcmF0aW9uCmh0dHA6Ly9ibG9nLmZmd2xsLmNoCl9fX19f X19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fX19fCmRyaS1kZXZlbCBtYWls aW5nIGxpc3QKZHJpLWRldmVsQGxpc3RzLmZyZWVkZXNrdG9wLm9yZwpodHRwczovL2xpc3RzLmZy ZWVkZXNrdG9wLm9yZy9tYWlsbWFuL2xpc3RpbmZvL2RyaS1kZXZlbAo=