diff for duplicates of <1487672942.12632.1.camel@intel.com> diff --git a/a/1.txt b/N1/1.txt index 11d5ce9..92fd5e3 100644 --- a/a/1.txt +++ b/N1/1.txt @@ -1,572 +1,328 @@ -On Sun, 2017-02-19 at 11:48 +0000, Jonathan Cameron wrote: -> On 13/02/17 09:49, Song Hongyan wrote: -> > Environmental temperature sensor is a hid defined sensor, -> > it measures temperature. -> > -> > More information can be found in: -> > http://www.usb.org/developers/hidpage/HUTRR39b.pdf -> > -> > According to IIO ABI definition, IIO_TEMP data output unit is -> > milli degrees Celsius. Add the unit convert from degree to milli -> > degree. -> > -> > Signed-off-by: Song Hongyan <hongyan.song@intel.com> -> -> Hi Song, -> -> I'm afraid I haven't really been taking a close look at the previous -> versions so a few comments inline from me that might otherwise have -> come on earlier versions. -> -> I will be looking for a reviewed-by or Ack from Srinivas on this -> before taking it (mostly to reflect the effort he has put in on those -> earlier reviews!) -Hongyan, - -You can add - -Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com> - -after addressing Jonathan's comments. - -Thanks, -Srinivas - -> -> Jonathan -> > --- -> > .../iio/common/hid-sensors/hid-sensor-attributes.c | 3 + -> > drivers/iio/temperature/Kconfig | 14 + -> > drivers/iio/temperature/Makefile | 1 + -> > drivers/iio/temperature/hid-sensor-temperature.c | 326 -> > +++++++++++++++++++++ -> > include/linux/hid-sensor-ids.h | 4 + -> > 5 files changed, 348 insertions(+) -> > create mode 100644 drivers/iio/temperature/hid-sensor- -> > temperature.c -> > -> > diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c -> > b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c -> > index 7ef94a9..68c2bb0 100644 -> > --- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c -> > +++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c -> > @@ -58,6 +58,9 @@ -> > -> > {HID_USAGE_SENSOR_PRESSURE, 0, 100, 0}, -> > {HID_USAGE_SENSOR_PRESSURE, HID_USAGE_SENSOR_UNITS_PASCAL, -> > 0, 1000000}, -> > + -> > + {HID_USAGE_SENSOR_TEMPERATURE, 0, 1000, 0}, -> > + {HID_USAGE_SENSOR_TEMPERATURE, -> > HID_USAGE_SENSOR_UNITS_DEGREES, 1000, 0}, -> > }; -> > -> > static int pow_10(unsigned power) -> > diff --git a/drivers/iio/temperature/Kconfig -> > b/drivers/iio/temperature/Kconfig -> > index 5ea77a7..5f7b9f7 100644 -> > --- a/drivers/iio/temperature/Kconfig -> > +++ b/drivers/iio/temperature/Kconfig -> > @@ -19,6 +19,20 @@ config MAXIM_THERMOCOUPLE -> > This driver can also be built as a module. If so, the -> > module will -> > be called maxim_thermocouple. -> > -> > +config HID_SENSOR_TEMP -> > + tristate "HID Environmental temperature sensor" -> > + depends on HID_SENSOR_HUB -> > + select IIO_BUFFER -> > + select IIO_TRIGGERED_BUFFER -> > + select HID_SENSOR_IIO_COMMON -> > + select HID_SENSOR_IIO_TRIGGER -> > + help -> > + Say yes here to build support for the HID SENSOR -> > + temperature driver -> > + -> > + To compile this driver as a module, choose M here: the -> > module -> > + will be called hid-sensor-temperature. -> > + -> > config MLX90614 -> > tristate "MLX90614 contact-less infrared sensor" -> > depends on I2C -> > diff --git a/drivers/iio/temperature/Makefile -> > b/drivers/iio/temperature/Makefile -> > index 78c3de0..e157eda 100644 -> > --- a/drivers/iio/temperature/Makefile -> > +++ b/drivers/iio/temperature/Makefile -> > @@ -7,3 +7,4 @@ obj-$(CONFIG_MLX90614) += mlx90614.o -> > obj-$(CONFIG_TMP006) += tmp006.o -> > obj-$(CONFIG_TSYS01) += tsys01.o -> > obj-$(CONFIG_TSYS02D) += tsys02d.o -> > +obj-$(CONFIG_HID_SENSOR_TEMP) += hid-sensor-temperature.o -> > diff --git a/drivers/iio/temperature/hid-sensor-temperature.c -> > b/drivers/iio/temperature/hid-sensor-temperature.c -> > new file mode 100644 -> > index 0000000..84abd2d -> > --- /dev/null -> > +++ b/drivers/iio/temperature/hid-sensor-temperature.c -> > @@ -0,0 +1,326 @@ -> > +/* HID Sensors Driver -> > + * Copyright (c) 2017, Intel Corporation. -> > + * -> > + * This program is free software; you can redistribute it and/or -> > modify it -> > + * under the terms and conditions of the GNU General Public -> > License, -> > + * version 2, as published by the Free Software Foundation. -> > + * -> > + * This program is distributed in the hope it will be useful, but -> > WITHOUT -> > + * ANY WARRANTY; without even the implied warranty of -> > MERCHANTABILITY or -> > + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public -> > License for -> > + * more details. -> > + * -> > + * You should have received a copy of the GNU General Public -> > License along with -> > + * this program. -> > + * -> > + */ -> > +#include <linux/device.h> -> > +#include <linux/hid-sensor-hub.h> -> > +#include <linux/iio/buffer.h> -> > +#include <linux/iio/iio.h> -> > +#include <linux/iio/triggered_buffer.h> -> > +#include <linux/iio/trigger_consumer.h> -> > +#include <linux/module.h> -> > +#include <linux/platform_device.h> -> > +#include "../common/hid-sensors/hid-sensor-trigger.h" -> > + -> > +struct temperature_state { -> > + struct hid_sensor_common common_attributes; -> > + struct hid_sensor_hub_attribute_info temperature_attr; -> > + s32 temperature_data; -> > + int scale_pre_decml; -> > + int scale_post_decml; -> > + int scale_precision; -> > + int value_offset; -> > +}; -> > + -> > +/* Channel definitions */ -> > +static const struct iio_chan_spec temperature_channels[] = { -> > + { -> > + .type = IIO_TEMP, -> > + .info_mask_separate = BIT(IIO_CHAN_INFO_RAW), -> > + .info_mask_shared_by_type = -> > BIT(IIO_CHAN_INFO_OFFSET) | -> > + BIT(IIO_CHAN_INFO_SCALE) | -> > + BIT(IIO_CHAN_INFO_SAMP_FREQ) | -> > + BIT(IIO_CHAN_INFO_HYSTERESIS), -> > + .scan_index = 0, -> > + } -> > +}; -> > + -> > +/* Adjust channel real bits based on report descriptor */ -> > +static void temperature_adjust_channel_bit_mask(struct -> > iio_chan_spec *channels, -> > + int channel, int size) -> > +{ -> > + channels[channel].scan_type.sign = 's'; -> > + /* Real storage bits will change based on the report desc. -> > */ -> > + channels[channel].scan_type.realbits = size * 8; -> > + /* Maximum size of a sample to capture is s32 */ -> > + channels[channel].scan_type.storagebits = sizeof(s32) * 8; -> > +} -> > + -> > +/* Channel read_raw handler */ -> > +static int temperature_read_raw(struct iio_dev *indio_dev, -> > + struct iio_chan_spec const *chan, -> > + int *val, int *val2, long mask) -> > +{ -> > + struct temperature_state *temperature_state = -> > iio_priv(indio_dev); -> > + int ret; -> > + -> > + switch (mask) { -> > + case IIO_CHAN_INFO_RAW: -> > + if (chan->type == IIO_TEMP) { -> > + hid_sensor_power_state( -> > + &temperature_state- -> > >common_attributes, true); -> > + *val = -> > sensor_hub_input_attr_get_raw_value( -> > + temperature_state- -> > >common_attributes.hsdev, -> > + HID_USAGE_SENSOR_TEMPERATURE, -> > + HID_USAGE_SENSOR_DATA_ENVIRONMENTA -> > L_TEMPERATURE, -> > + temperature_state- -> > >temperature_attr.report_id, -> > + SENSOR_HUB_SYNC); -> > + hid_sensor_power_state( -> > + &temperature_state- -> > >common_attributes, -> > + false); -> > + } -> -> This is an oddity. If you get here without chan->type == IIO_TEMP -> (which you can't, but your code is kind of assuming you can) -> then you are returning that the data is valid without setting it to -> anything. -> -> I'd flip the logic -> if (chan->type != IIO_TEMP) { -> return -EINVAL; -> } -> ... normal code flow ... -> > + ret = IIO_VAL_INT; -> -> There is nothing other than a return to be done after this so just -> do it directly here instead. Basic rule of thumb in kernel code is -> return as early as possible when there is no unwinding to be done. -> Same in all the branches of this switch statement pelase. -> > + break; -> > + case IIO_CHAN_INFO_SCALE: -> > + *val = temperature_state->scale_pre_decml; -> > + *val2 = temperature_state->scale_post_decml; -> > + ret = temperature_state->scale_precision; -> > + break; -> > + case IIO_CHAN_INFO_OFFSET: -> > + *val = temperature_state->value_offset; -> > + ret = IIO_VAL_INT; -> > + break; -> > + case IIO_CHAN_INFO_SAMP_FREQ: -> > + ret = hid_sensor_read_samp_freq_value( -> > + &temperature_state- -> > >common_attributes, -> > + val, val2); -> > + break; -> > + case IIO_CHAN_INFO_HYSTERESIS: -> > + ret = hid_sensor_read_raw_hyst_value( -> > + &temperature_state- -> > >common_attributes, -> > + val, val2); -> > + break; -> > + default: -> > + ret = -EINVAL; -> > + } -> > + -> > + return ret; -> > +} -> > + -> > +/* Channel write_raw handler */ -> -> Perhaps drop the more obvious comments as not necessarily providing -> any additional info. I don't really mind if you feel they are useful -> however and want to keep them. -> > +static int temperature_write_raw(struct iio_dev *indio_dev, -> > + struct iio_chan_spec const *chan, -> > + int val, int val2, long mask) -> > +{ -> > + struct temperature_state *temperature_state = -> > iio_priv(indio_dev); -> > + int ret; -> > + -> > + switch (mask) { -> > + case IIO_CHAN_INFO_SAMP_FREQ: -> > + ret = hid_sensor_write_samp_freq_value( -> > + &temperature_state- -> > >common_attributes, val, -> > + val2); -> -> As with the read_raw above, return directly within these statements -> rather than -> having to bother with breaking out of the switch and then doing it. -> Tidier code that way. -> -> return hid_sensor.... -> > + break; -> > + case IIO_CHAN_INFO_HYSTERESIS: -> > + ret = hid_sensor_write_raw_hyst_value( -> > + &temperature_state- -> > >common_attributes, val, -> > + val2); -> > + break; -> > + default: -> > + ret = -EINVAL; -> > + } -> > + -> > + return ret; -> > +} -> > + -> > +static const struct iio_info temperature_info = { -> > + .driver_module = THIS_MODULE, -> > + .read_raw = &temperature_read_raw, -> > + .write_raw = &temperature_write_raw, -> > +}; -> > + -> > +/* Callback handler to send event after all samples are received -> > and captured */ -> > +static int temperature_proc_event(struct hid_sensor_hub_device -> > *hsdev, -> > + unsigned int usage_id, void *pdev) -> > +{ -> > + struct iio_dev *indio_dev = platform_get_drvdata(pdev); -> > + struct temperature_state *temperature_state = -> > iio_priv(indio_dev); -> > + -> > + if (atomic_read(&temperature_state- -> > >common_attributes.data_ready)) -> > + iio_push_to_buffers(indio_dev, -> > + &temperature_state- -> > >temperature_data); -> > + return 0; -> > +} -> > + -> > +/* Capture samples in local storage */ -> > +static int temperature_capture_sample(struct hid_sensor_hub_device -> > *hsdev, -> > + unsigned int usage_id, size_t -> > raw_len, -> > + char *raw_data, void *pdev) -> > +{ -> > + struct iio_dev *indio_dev = platform_get_drvdata(pdev); -> > + struct temperature_state *temperature_state = -> > iio_priv(indio_dev); -> > + -> > + switch (usage_id) { -> > + case HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE: -> > + temperature_state->temperature_data = *(s32 -> > *)raw_data; -> > + return 0; -> > + default: -> > + return -EINVAL; -> > + } -> > +} -> > + -> > +/* Parse report which is specific to an usage id*/ -> > +static int temperature_parse_report(struct platform_device *pdev, -> > + struct hid_sensor_hub_device -> > *hsdev, -> > + struct iio_chan_spec *channels, -> > + unsigned int usage_id, -> > + struct temperature_state *st) -> > +{ -> > + int ret; -> > + -> > + ret = sensor_hub_input_get_attribute_info(hsdev, -> > HID_INPUT_REPORT, -> > + usage_id, -> > + HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPER -> > ATURE, -> > + &st->temperature_attr); -> > + if (ret < 0) -> > + return ret; -> > + -> > + temperature_adjust_channel_bit_mask(channels, 0, -> > + st- -> > >temperature_attr.size); -> > + -> > + st->scale_precision = hid_sensor_format_scale( -> > + HID_USAGE_SENSOR_TEMPERATURE, -> > + &st->temperature_attr, -> > + &st->scale_pre_decml, &st- -> > >scale_post_decml); -> > + -> > + /* Set Sensitivity field ids, when there is no individual -> > modifier */ -> > + if (st->common_attributes.sensitivity.index < 0) -> > + sensor_hub_input_get_attribute_info(hsdev, -> > + HID_FEATURE_REPORT, usage_id, -> > + HID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVI -> > TY_ABS | -> > + HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPER -> > ATURE, -> > + &st->common_attributes.sensitivity); -> > + -> > + return ret; -> > +} -> > + -> > +static struct hid_sensor_hub_callbacks temperature_callbacks = { -> > + .send_event = &temperature_proc_event, -> > + .capture_sample = &temperature_capture_sample, -> > +}; -> > + -> > +/* Function to initialize the processing for usage id */ -> > +static int hid_temperature_probe(struct platform_device *pdev) -> > +{ -> > + static const char *name = "temperature"; -> > + struct iio_dev *indio_dev; -> > + struct temperature_state *temperature_state; -> -> Maybe shorten the variable name to lead to some shorter lines later? -> temp_st for example would I think convey enough meaning. -> -> > + struct hid_sensor_hub_device *hsdev = pdev- -> > >dev.platform_data; -> > + int ret; -> > + -> > + indio_dev = devm_iio_device_alloc(&pdev->dev, -> > + sizeof(struct temperature_state)); -> -> Ever so slight preference for sizeof(*temperature_state) -> -> > + if (!indio_dev) -> > + return -ENOMEM; -> > + -> > + temperature_state = iio_priv(indio_dev); -> > + temperature_state->common_attributes.hsdev = hsdev; -> > + temperature_state->common_attributes.pdev = pdev; -> > + -> > + ret = hid_sensor_parse_common_attributes(hsdev, -> > + HID_USAGE_SENSOR_TEMPERATU -> > RE, -> > + &temperature_state- -> > >common_attributes); -> > + if (ret) -> > + return ret; -> > + -> > + indio_dev->channels = devm_kmemdup(&indio_dev->dev, -> -> maybe rename as temp_chans as verbosity not adding much here. -> > + temperature_channels, -> > + sizeof(temperature_channel -> > s), -> > + GFP_KERNEL); -> > + if (!indio_dev->channels) -> > + return -ENOMEM; -> > + -> > + ret = temperature_parse_report(pdev, hsdev, -> > + (struct iio_chan_spec *)indio_dev- -> > >channels, -> -> This is casting away a const, which I don't particularly like. -> I'd prefer that you used a local variable, got everthing setup as you -> like -> and then assigned indio_dev->channels to it. Semantically slightly -> nicer as -> assumption is that they are const if accessed via this element of -> struct -> iio_dev (here we obviously know we can change them but it's still not -> nice!) -> -> > + HID_USAGE_SENSOR_TEMPERATURE, -> > + temperature_state); -> > + if (ret) -> > + return ret; -> > + -> > + indio_dev->num_channels = -> > ARRAY_SIZE(temperature_channels); -> > + indio_dev->dev.parent = &pdev->dev; -> > + indio_dev->info = &temperature_info; -> > + indio_dev->name = name; -> > + indio_dev->modes = INDIO_DIRECT_MODE; -> > + -> > + ret = devm_iio_triggered_buffer_setup(&pdev->dev, -> > indio_dev, -> > + &iio_pollfunc_store_time, -> -> Oddity here as you don't actually use the timestamp... -> > + NULL, NULL); -> > + if (ret) -> > + return ret; -> > + -> > + atomic_set(&temperature_state- -> > >common_attributes.data_ready, 0); -> > + ret = hid_sensor_setup_trigger(indio_dev, name, -> > + &temperature_state- -> > >common_attributes); -> > + if (ret) -> > + return ret; -> > + -> > + platform_set_drvdata(pdev, indio_dev); -> > + -> > + temperature_callbacks.pdev = pdev; -> > + ret = sensor_hub_register_callback(hsdev, -> > HID_USAGE_SENSOR_TEMPERATURE, -> > + &temperature_callbacks); -> > + if (ret) -> > + goto error_remove_trigger; -> > + -> > + ret = devm_iio_device_register(indio_dev->dev.parent, -> > indio_dev); -> > + if (ret) -> > + goto error_remove_callback; -> > + -> > + return ret; -> > + -> > +error_remove_callback: -> > + sensor_hub_remove_callback(hsdev, -> > HID_USAGE_SENSOR_TEMPERATURE); -> > +error_remove_trigger: -> > + hid_sensor_remove_trigger(&temperature_state- -> > >common_attributes); -> > + return ret; -> > +} -> > + -> > +/* Function to deinitialize the processing for usage id */ -> > +static int hid_temperature_remove(struct platform_device *pdev) -> > +{ -> > + struct hid_sensor_hub_device *hsdev = pdev- -> > >dev.platform_data; -> -> Is it just me that feels that for consistence there should be a -> platform_get_platform_data() function? -> A well, can't say it would really add anything, just my sense of -> consistency kicking in ;) -> Anyhow, not really anything to do with this driver review so feel -> free to ignore! -> -> > + struct iio_dev *indio_dev = platform_get_drvdata(pdev); -> > + struct temperature_state *temperature_state = -> > iio_priv(indio_dev); -> > + -> > + sensor_hub_remove_callback(hsdev, -> > HID_USAGE_SENSOR_TEMPERATURE); -> > + hid_sensor_remove_trigger(&temperature_state- -> > >common_attributes); -> > + -> > + return 0; -> > +} -> > + -> > +static const struct platform_device_id hid_temperature_ids[] = { -> > + { -> > + /* Format: HID-SENSOR-usage_id_in_hex_lowercase */ -> > + .name = "HID-SENSOR-200033", -> > + }, -> > + { /* sentinel */ } -> > +}; -> > +MODULE_DEVICE_TABLE(platform, hid_temperature_ids); -> > + -> > +static struct platform_driver hid_temperature_platform_driver = { -> > + .id_table = hid_temperature_ids, -> > + .driver = { -> > + .name = KBUILD_MODNAME, -> > + .pm = &hid_sensor_pm_ops, -> > + }, -> > + .probe = hid_temperature_probe, -> > + .remove = hid_temperature_remove, -> > +}; -> > +module_platform_driver(hid_temperature_platform_driver); -> > + -> > +MODULE_DESCRIPTION("HID Environmental temperature sensor"); -> > +MODULE_AUTHOR("Song Hongyan <hongyan.song@intel.com>"); -> > +MODULE_LICENSE("GPL v2"); -> > diff --git a/include/linux/hid-sensor-ids.h b/include/linux/hid- -> > sensor-ids.h -> > index bab8375..ecec978 100644 -> > --- a/include/linux/hid-sensor-ids.h -> > +++ b/include/linux/hid-sensor-ids.h -> > @@ -45,6 +45,10 @@ -> > #define -> > HID_USAGE_SENSOR_DATA_ATMOSPHERIC_PRESSURE 0x200430 -> > #define -> > HID_USAGE_SENSOR_ATMOSPHERIC_PRESSURE 0x200431 -> > -> > +/* Tempreture (200033) */ -> > +#define HID_USAGE_SENSOR_TEMPERATURE -> > 0x200033 -> > +#define HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE -> > 0x200434 -> > + -> > /* Gyro 3D: (200076) */ -> > #define HID_USAGE_SENSOR_GYRO_3D 0x -> > 200076 -> > #define HID_USAGE_SENSOR_DATA_ANGL_VELOCITY -> > 0x200456 -> > -> -> +T24gU3VuLCAyMDE3LTAyLTE5IGF0IDExOjQ4ICswMDAwLCBKb25hdGhhbiBDYW1lcm9uIHdyb3Rl +Og0KPiBPbiAxMy8wMi8xNyAwOTo0OSwgU29uZyBIb25neWFuIHdyb3RlOg0KPiA+IEVudmlyb25t +ZW50YWwgdGVtcGVyYXR1cmUgc2Vuc29yIGlzIGEgaGlkIGRlZmluZWQgc2Vuc29yLA0KPiA+IGl0 +IG1lYXN1cmVzIHRlbXBlcmF0dXJlLg0KPiA+IA0KPiA+IE1vcmUgaW5mb3JtYXRpb24gY2FuIGJl +IGZvdW5kIGluOg0KPiA+IGh0dHA6Ly93d3cudXNiLm9yZy9kZXZlbG9wZXJzL2hpZHBhZ2UvSFVU +UlIzOWIucGRmDQo+ID4gDQo+ID4gQWNjb3JkaW5nIHRvIElJTyBBQkkgZGVmaW5pdGlvbiwgSUlP +X1RFTVAgZGF0YSBvdXRwdXQgdW5pdCBpcw0KPiA+IG1pbGxpIGRlZ3JlZXMgQ2Vsc2l1cy4gQWRk +IHRoZSB1bml0IGNvbnZlcnQgZnJvbSBkZWdyZWUgdG8gbWlsbGkNCj4gPiBkZWdyZWUuDQo+ID4g +DQo+ID4gU2lnbmVkLW9mZi1ieTogU29uZyBIb25neWFuIDxob25neWFuLnNvbmdAaW50ZWwuY29t +Pg0KPiANCj4gSGkgU29uZywNCj4gDQo+IEknbSBhZnJhaWQgSSBoYXZlbid0IHJlYWxseSBiZWVu +IHRha2luZyBhIGNsb3NlIGxvb2sgYXQgdGhlIHByZXZpb3VzDQo+IHZlcnNpb25zIHNvIGEgZmV3 +IGNvbW1lbnRzIGlubGluZSBmcm9tIG1lIHRoYXQgbWlnaHQgb3RoZXJ3aXNlIGhhdmUNCj4gY29t +ZSBvbiBlYXJsaWVyIHZlcnNpb25zLg0KPiANCj4gSSB3aWxsIGJlIGxvb2tpbmcgZm9yIGEgcmV2 +aWV3ZWQtYnkgb3IgQWNrIGZyb20gU3Jpbml2YXMgb24gdGhpcw0KPiBiZWZvcmUgdGFraW5nIGl0 +IChtb3N0bHkgdG8gcmVmbGVjdCB0aGUgZWZmb3J0IGhlIGhhcyBwdXQgaW4gb24gdGhvc2UNCj4g +ZWFybGllciByZXZpZXdzISkNCkhvbmd5YW4sDQoNCllvdSBjYW4gYWRkDQoNCkFja2VkLWJ5OiBT +cmluaXZhcyBQYW5kcnV2YWRhIDxzcmluaXZhcy5wYW5kcnV2YWRhQGxpbnV4LmludGVsLmNvbT4N +Cg0KYWZ0ZXIgYWRkcmVzc2luZyBKb25hdGhhbidzIGNvbW1lbnRzLg0KDQpUaGFua3MsDQpTcmlu +aXZhcw0KDQo+IA0KPiBKb25hdGhhbg0KPiA+IC0tLQ0KPiA+IMKgLi4uL2lpby9jb21tb24vaGlk +LXNlbnNvcnMvaGlkLXNlbnNvci1hdHRyaWJ1dGVzLmMgfMKgwqDCoDMgKw0KPiA+IMKgZHJpdmVy +cy9paW8vdGVtcGVyYXR1cmUvS2NvbmZpZ8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg +wqDCoMKgwqB8wqDCoDE0ICsNCj4gPiDCoGRyaXZlcnMvaWlvL3RlbXBlcmF0dXJlL01ha2VmaWxl +wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgMSArDQo+ID4gwqBk +cml2ZXJzL2lpby90ZW1wZXJhdHVyZS9oaWQtc2Vuc29yLXRlbXBlcmF0dXJlLmPCoMKgwqB8IDMy +Ng0KPiA+ICsrKysrKysrKysrKysrKysrKysrKw0KPiA+IMKgaW5jbHVkZS9saW51eC9oaWQtc2Vu +c29yLWlkcy5owqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDC +oDQgKw0KPiA+IMKgNSBmaWxlcyBjaGFuZ2VkLCAzNDggaW5zZXJ0aW9ucygrKQ0KPiA+IMKgY3Jl +YXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvaWlvL3RlbXBlcmF0dXJlL2hpZC1zZW5zb3ItDQo+ID4g +dGVtcGVyYXR1cmUuYw0KPiA+IA0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2lpby9jb21tb24v +aGlkLXNlbnNvcnMvaGlkLXNlbnNvci1hdHRyaWJ1dGVzLmMgDQo+ID4gYi9kcml2ZXJzL2lpby9j +b21tb24vaGlkLXNlbnNvcnMvaGlkLXNlbnNvci1hdHRyaWJ1dGVzLmMNCj4gPiBpbmRleCA3ZWY5 +NGE5Li42OGMyYmIwIDEwMDY0NA0KPiA+IC0tLSBhL2RyaXZlcnMvaWlvL2NvbW1vbi9oaWQtc2Vu +c29ycy9oaWQtc2Vuc29yLWF0dHJpYnV0ZXMuYw0KPiA+ICsrKyBiL2RyaXZlcnMvaWlvL2NvbW1v +bi9oaWQtc2Vuc29ycy9oaWQtc2Vuc29yLWF0dHJpYnV0ZXMuYw0KPiA+IEBAIC01OCw2ICs1OCw5 +IEBADQo+ID4gwqANCj4gPiDCoAl7SElEX1VTQUdFX1NFTlNPUl9QUkVTU1VSRSwgMCwgMTAwLCAw +fSwNCj4gPiDCoAl7SElEX1VTQUdFX1NFTlNPUl9QUkVTU1VSRSwgSElEX1VTQUdFX1NFTlNPUl9V +TklUU19QQVNDQUwsDQo+ID4gMCwgMTAwMDAwMH0sDQo+ID4gKw0KPiA+ICsJe0hJRF9VU0FHRV9T +RU5TT1JfVEVNUEVSQVRVUkUsIDAsIDEwMDAsIDB9LA0KPiA+ICsJe0hJRF9VU0FHRV9TRU5TT1Jf +VEVNUEVSQVRVUkUsDQo+ID4gSElEX1VTQUdFX1NFTlNPUl9VTklUU19ERUdSRUVTLCAxMDAwLCAw +fSwNCj4gPiDCoH07DQo+ID4gwqANCj4gPiDCoHN0YXRpYyBpbnQgcG93XzEwKHVuc2lnbmVkIHBv +d2VyKQ0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2lpby90ZW1wZXJhdHVyZS9LY29uZmlnDQo+ +ID4gYi9kcml2ZXJzL2lpby90ZW1wZXJhdHVyZS9LY29uZmlnDQo+ID4gaW5kZXggNWVhNzdhNy4u +NWY3YjlmNyAxMDA2NDQNCj4gPiAtLS0gYS9kcml2ZXJzL2lpby90ZW1wZXJhdHVyZS9LY29uZmln +DQo+ID4gKysrIGIvZHJpdmVycy9paW8vdGVtcGVyYXR1cmUvS2NvbmZpZw0KPiA+IEBAIC0xOSw2 +ICsxOSwyMCBAQCBjb25maWcgTUFYSU1fVEhFUk1PQ09VUExFDQo+ID4gwqAJwqDCoFRoaXMgZHJp +dmVyIGNhbiBhbHNvIGJlIGJ1aWx0IGFzIGEgbW9kdWxlLiBJZiBzbywgdGhlDQo+ID4gbW9kdWxl +IHdpbGwNCj4gPiDCoAnCoMKgYmUgY2FsbGVkIG1heGltX3RoZXJtb2NvdXBsZS4NCj4gPiDCoA0K +PiA+ICtjb25maWcgSElEX1NFTlNPUl9URU1QDQo+ID4gKwl0cmlzdGF0ZSAiSElEIEVudmlyb25t +ZW50YWwgdGVtcGVyYXR1cmUgc2Vuc29yIg0KPiA+ICsJZGVwZW5kcyBvbiBISURfU0VOU09SX0hV +Qg0KPiA+ICsJc2VsZWN0IElJT19CVUZGRVINCj4gPiArCXNlbGVjdCBJSU9fVFJJR0dFUkVEX0JV +RkZFUg0KPiA+ICsJc2VsZWN0IEhJRF9TRU5TT1JfSUlPX0NPTU1PTg0KPiA+ICsJc2VsZWN0IEhJ +RF9TRU5TT1JfSUlPX1RSSUdHRVINCj4gPiArCWhlbHANCj4gPiArCcKgwqBTYXkgeWVzIGhlcmUg +dG8gYnVpbGQgc3VwcG9ydCBmb3IgdGhlIEhJRCBTRU5TT1INCj4gPiArCcKgwqB0ZW1wZXJhdHVy +ZSBkcml2ZXINCj4gPiArDQo+ID4gKwnCoMKgVG8gY29tcGlsZSB0aGlzIGRyaXZlciBhcyBhIG1v +ZHVsZSwgY2hvb3NlIE0gaGVyZTogdGhlDQo+ID4gbW9kdWxlDQo+ID4gKwnCoMKgd2lsbCBiZSBj +YWxsZWQgaGlkLXNlbnNvci10ZW1wZXJhdHVyZS4NCj4gPiArDQo+ID4gwqBjb25maWcgTUxYOTA2 +MTQNCj4gPiDCoAl0cmlzdGF0ZSAiTUxYOTA2MTQgY29udGFjdC1sZXNzIGluZnJhcmVkIHNlbnNv +ciINCj4gPiDCoAlkZXBlbmRzIG9uIEkyQw0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2lpby90 +ZW1wZXJhdHVyZS9NYWtlZmlsZQ0KPiA+IGIvZHJpdmVycy9paW8vdGVtcGVyYXR1cmUvTWFrZWZp +bGUNCj4gPiBpbmRleCA3OGMzZGUwLi5lMTU3ZWRhIDEwMDY0NA0KPiA+IC0tLSBhL2RyaXZlcnMv +aWlvL3RlbXBlcmF0dXJlL01ha2VmaWxlDQo+ID4gKysrIGIvZHJpdmVycy9paW8vdGVtcGVyYXR1 +cmUvTWFrZWZpbGUNCj4gPiBAQCAtNywzICs3LDQgQEAgb2JqLSQoQ09ORklHX01MWDkwNjE0KSAr +PSBtbHg5MDYxNC5vDQo+ID4gwqBvYmotJChDT05GSUdfVE1QMDA2KSArPSB0bXAwMDYubw0KPiA+ +IMKgb2JqLSQoQ09ORklHX1RTWVMwMSkgKz0gdHN5czAxLm8NCj4gPiDCoG9iai0kKENPTkZJR19U +U1lTMDJEKSArPSB0c3lzMDJkLm8NCj4gPiArb2JqLSQoQ09ORklHX0hJRF9TRU5TT1JfVEVNUCnC +oMKgwqArPSBoaWQtc2Vuc29yLXRlbXBlcmF0dXJlLm8NCj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVy +cy9paW8vdGVtcGVyYXR1cmUvaGlkLXNlbnNvci10ZW1wZXJhdHVyZS5jDQo+ID4gYi9kcml2ZXJz +L2lpby90ZW1wZXJhdHVyZS9oaWQtc2Vuc29yLXRlbXBlcmF0dXJlLmMNCj4gPiBuZXcgZmlsZSBt +b2RlIDEwMDY0NA0KPiA+IGluZGV4IDAwMDAwMDAuLjg0YWJkMmQNCj4gPiAtLS0gL2Rldi9udWxs +DQo+ID4gKysrIGIvZHJpdmVycy9paW8vdGVtcGVyYXR1cmUvaGlkLXNlbnNvci10ZW1wZXJhdHVy +ZS5jDQo+ID4gQEAgLTAsMCArMSwzMjYgQEANCj4gPiArLyogSElEIFNlbnNvcnMgRHJpdmVyDQo+ +ID4gKyAqIENvcHlyaWdodCAoYykgMjAxNywgSW50ZWwgQ29ycG9yYXRpb24uDQo+ID4gKyAqDQo+ +ID4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0 +ZSBpdCBhbmQvb3INCj4gPiBtb2RpZnkgaXQNCj4gPiArICogdW5kZXIgdGhlIHRlcm1zIGFuZCBj +b25kaXRpb25zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMNCj4gPiBMaWNlbnNlLA0KPiA+ICsg +KiB2ZXJzaW9uIDIsIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9u +Lg0KPiA+ICsgKg0KPiA+ICsgKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhv +cGUgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dA0KPiA+IFdJVEhPVVQNCj4gPiArICogQU5ZIFdBUlJB +TlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YNCj4gPiBNRVJDSEFOVEFC +SUxJVFkgb3INCj4gPiArICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuwqDCoFNl +ZSB0aGUgR05VIEdlbmVyYWwgUHVibGljDQo+ID4gTGljZW5zZSBmb3INCj4gPiArICogbW9yZSBk +ZXRhaWxzLg0KPiA+ICsgKg0KPiA+ICsgKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5 +IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMNCj4gPiBMaWNlbnNlIGFsb25nIHdpdGgNCj4gPiAr +ICogdGhpcyBwcm9ncmFtLg0KPiA+ICsgKg0KPiA+ICsgKi8NCj4gPiArI2luY2x1ZGUgPGxpbnV4 +L2RldmljZS5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvaGlkLXNlbnNvci1odWIuaD4NCj4gPiAr +I2luY2x1ZGUgPGxpbnV4L2lpby9idWZmZXIuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L2lpby9p +aW8uaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L2lpby90cmlnZ2VyZWRfYnVmZmVyLmg+DQo+ID4g +KyNpbmNsdWRlIDxsaW51eC9paW8vdHJpZ2dlcl9jb25zdW1lci5oPg0KPiA+ICsjaW5jbHVkZSA8 +bGludXgvbW9kdWxlLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9wbGF0Zm9ybV9kZXZpY2UuaD4N +Cj4gPiArI2luY2x1ZGUgIi4uL2NvbW1vbi9oaWQtc2Vuc29ycy9oaWQtc2Vuc29yLXRyaWdnZXIu +aCINCj4gPiArDQo+ID4gK3N0cnVjdCB0ZW1wZXJhdHVyZV9zdGF0ZSB7DQo+ID4gKwlzdHJ1Y3Qg +aGlkX3NlbnNvcl9jb21tb24gY29tbW9uX2F0dHJpYnV0ZXM7DQo+ID4gKwlzdHJ1Y3QgaGlkX3Nl +bnNvcl9odWJfYXR0cmlidXRlX2luZm8gdGVtcGVyYXR1cmVfYXR0cjsNCj4gPiArCXMzMiB0ZW1w +ZXJhdHVyZV9kYXRhOw0KPiA+ICsJaW50IHNjYWxlX3ByZV9kZWNtbDsNCj4gPiArCWludCBzY2Fs +ZV9wb3N0X2RlY21sOw0KPiA+ICsJaW50IHNjYWxlX3ByZWNpc2lvbjsNCj4gPiArCWludCB2YWx1 +ZV9vZmZzZXQ7DQo+ID4gK307DQo+ID4gKw0KPiA+ICsvKiBDaGFubmVsIGRlZmluaXRpb25zICov +DQo+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgaWlvX2NoYW5fc3BlYyB0ZW1wZXJhdHVyZV9jaGFu +bmVsc1tdID0gew0KPiA+ICsJew0KPiA+ICsJCS50eXBlID0gSUlPX1RFTVAsDQo+ID4gKwkJLmlu +Zm9fbWFza19zZXBhcmF0ZSA9IEJJVChJSU9fQ0hBTl9JTkZPX1JBVyksDQo+ID4gKwkJLmluZm9f +bWFza19zaGFyZWRfYnlfdHlwZSA9DQo+ID4gQklUKElJT19DSEFOX0lORk9fT0ZGU0VUKSB8DQo+ +ID4gKwkJCUJJVChJSU9fQ0hBTl9JTkZPX1NDQUxFKSB8DQo+ID4gKwkJCUJJVChJSU9fQ0hBTl9J +TkZPX1NBTVBfRlJFUSkgfA0KPiA+ICsJCQlCSVQoSUlPX0NIQU5fSU5GT19IWVNURVJFU0lTKSwN +Cj4gPiArCQkuc2Nhbl9pbmRleCA9IDAsDQo+ID4gKwl9DQo+ID4gK307DQo+ID4gKw0KPiA+ICsv +KiBBZGp1c3QgY2hhbm5lbCByZWFsIGJpdHMgYmFzZWQgb24gcmVwb3J0IGRlc2NyaXB0b3IgKi8N +Cj4gPiArc3RhdGljIHZvaWQgdGVtcGVyYXR1cmVfYWRqdXN0X2NoYW5uZWxfYml0X21hc2soc3Ry +dWN0DQo+ID4gaWlvX2NoYW5fc3BlYyAqY2hhbm5lbHMsDQo+ID4gKwkJCQkJaW50IGNoYW5uZWws +IGludCBzaXplKQ0KPiA+ICt7DQo+ID4gKwljaGFubmVsc1tjaGFubmVsXS5zY2FuX3R5cGUuc2ln +biA9ICdzJzsNCj4gPiArCS8qIFJlYWwgc3RvcmFnZSBiaXRzIHdpbGwgY2hhbmdlIGJhc2VkIG9u +IHRoZSByZXBvcnQgZGVzYy4NCj4gPiAqLw0KPiA+ICsJY2hhbm5lbHNbY2hhbm5lbF0uc2Nhbl90 +eXBlLnJlYWxiaXRzID0gc2l6ZSAqIDg7DQo+ID4gKwkvKiBNYXhpbXVtIHNpemUgb2YgYSBzYW1w +bGUgdG8gY2FwdHVyZSBpcyBzMzIgKi8NCj4gPiArCWNoYW5uZWxzW2NoYW5uZWxdLnNjYW5fdHlw +ZS5zdG9yYWdlYml0cyA9IHNpemVvZihzMzIpICogODsNCj4gPiArfQ0KPiA+ICsNCj4gPiArLyog +Q2hhbm5lbCByZWFkX3JhdyBoYW5kbGVyICovDQo+ID4gK3N0YXRpYyBpbnQgdGVtcGVyYXR1cmVf +cmVhZF9yYXcoc3RydWN0IGlpb19kZXYgKmluZGlvX2RldiwNCj4gPiArCQkJCXN0cnVjdCBpaW9f +Y2hhbl9zcGVjIGNvbnN0ICpjaGFuLA0KPiA+ICsJCQkJaW50ICp2YWwsIGludCAqdmFsMiwgbG9u +ZyBtYXNrKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgdGVtcGVyYXR1cmVfc3RhdGUgKnRlbXBlcmF0 +dXJlX3N0YXRlID0NCj4gPiBpaW9fcHJpdihpbmRpb19kZXYpOw0KPiA+ICsJaW50IHJldDsNCj4g +PiArDQo+ID4gKwlzd2l0Y2ggKG1hc2spIHsNCj4gPiArCWNhc2UgSUlPX0NIQU5fSU5GT19SQVc6 +DQo+ID4gKwkJaWYgKGNoYW4tPnR5cGUgPT0gSUlPX1RFTVApIHsNCj4gPiArCQkJaGlkX3NlbnNv +cl9wb3dlcl9zdGF0ZSgNCj4gPiArCQkJCSZ0ZW1wZXJhdHVyZV9zdGF0ZS0NCj4gPiA+Y29tbW9u +X2F0dHJpYnV0ZXMsIHRydWUpOw0KPiA+ICsJCQkqdmFsID0NCj4gPiBzZW5zb3JfaHViX2lucHV0 +X2F0dHJfZ2V0X3Jhd192YWx1ZSgNCj4gPiArCQkJCXRlbXBlcmF0dXJlX3N0YXRlLQ0KPiA+ID5j +b21tb25fYXR0cmlidXRlcy5oc2RldiwNCj4gPiArCQkJCUhJRF9VU0FHRV9TRU5TT1JfVEVNUEVS +QVRVUkUsDQo+ID4gKwkJCQlISURfVVNBR0VfU0VOU09SX0RBVEFfRU5WSVJPTk1FTlRBDQo+ID4g +TF9URU1QRVJBVFVSRSwNCj4gPiArCQkJCXRlbXBlcmF0dXJlX3N0YXRlLQ0KPiA+ID50ZW1wZXJh +dHVyZV9hdHRyLnJlcG9ydF9pZCwNCj4gPiArCQkJCVNFTlNPUl9IVUJfU1lOQyk7DQo+ID4gKwkJ +CWhpZF9zZW5zb3JfcG93ZXJfc3RhdGUoDQo+ID4gKwkJCQkJJnRlbXBlcmF0dXJlX3N0YXRlLQ0K +PiA+ID5jb21tb25fYXR0cmlidXRlcywNCj4gPiArCQkJCQlmYWxzZSk7DQo+ID4gKwkJfQ0KPiAN +Cj4gVGhpcyBpcyBhbiBvZGRpdHkuwqDCoElmIHlvdSBnZXQgaGVyZSB3aXRob3V0IGNoYW4tPnR5 +cGUgPT0gSUlPX1RFTVANCj4gKHdoaWNoIHlvdSBjYW4ndCwgYnV0IHlvdXIgY29kZSBpcyBraW5k +IG9mIGFzc3VtaW5nIHlvdSBjYW4pDQo+IHRoZW4geW91IGFyZSByZXR1cm5pbmcgdGhhdCB0aGUg +ZGF0YSBpcyB2YWxpZCB3aXRob3V0IHNldHRpbmcgaXQgdG8NCj4gYW55dGhpbmcuDQo+IA0KPiBJ +J2QgZmxpcCB0aGUgbG9naWMNCj4gaWYgKGNoYW4tPnR5cGUgIT0gSUlPX1RFTVApIHsNCj4gwqDC +oMKgcmV0dXJuIC1FSU5WQUw7DQo+IH0NCj4gLi4uIG5vcm1hbCBjb2RlIGZsb3cgLi4uDQo+ID4g +KwkJcmV0ID0gSUlPX1ZBTF9JTlQ7DQo+IA0KPiBUaGVyZSBpcyBub3RoaW5nIG90aGVyIHRoYW4g +YSByZXR1cm4gdG8gYmUgZG9uZSBhZnRlciB0aGlzIHNvIGp1c3QNCj4gZG8gaXQgZGlyZWN0bHkg +aGVyZSBpbnN0ZWFkLsKgwqBCYXNpYyBydWxlIG9mIHRodW1iIGluIGtlcm5lbCBjb2RlIGlzDQo+ +IHJldHVybiBhcyBlYXJseSBhcyBwb3NzaWJsZSB3aGVuIHRoZXJlIGlzIG5vIHVud2luZGluZyB0 +byBiZSBkb25lLg0KPiBTYW1lIGluIGFsbCB0aGUgYnJhbmNoZXMgb2YgdGhpcyBzd2l0Y2ggc3Rh +dGVtZW50IHBlbGFzZS4NCj4gPiArCQlicmVhazsNCj4gPiArCWNhc2UgSUlPX0NIQU5fSU5GT19T +Q0FMRToNCj4gPiArCQkqdmFsID0gdGVtcGVyYXR1cmVfc3RhdGUtPnNjYWxlX3ByZV9kZWNtbDsN +Cj4gPiArCQkqdmFsMiA9IHRlbXBlcmF0dXJlX3N0YXRlLT5zY2FsZV9wb3N0X2RlY21sOw0KPiA+ +ICsJCXJldCA9IHRlbXBlcmF0dXJlX3N0YXRlLT5zY2FsZV9wcmVjaXNpb247DQo+ID4gKwkJYnJl +YWs7DQo+ID4gKwljYXNlIElJT19DSEFOX0lORk9fT0ZGU0VUOg0KPiA+ICsJCSp2YWwgPSB0ZW1w +ZXJhdHVyZV9zdGF0ZS0+dmFsdWVfb2Zmc2V0Ow0KPiA+ICsJCXJldCA9IElJT19WQUxfSU5UOw0K +PiA+ICsJCWJyZWFrOw0KPiA+ICsJY2FzZSBJSU9fQ0hBTl9JTkZPX1NBTVBfRlJFUToNCj4gPiAr +CQlyZXQgPSBoaWRfc2Vuc29yX3JlYWRfc2FtcF9mcmVxX3ZhbHVlKA0KPiA+ICsJCQkJJnRlbXBl +cmF0dXJlX3N0YXRlLQ0KPiA+ID5jb21tb25fYXR0cmlidXRlcywNCj4gPiArCQkJCXZhbCwgdmFs +Mik7DQo+ID4gKwkJYnJlYWs7DQo+ID4gKwljYXNlIElJT19DSEFOX0lORk9fSFlTVEVSRVNJUzoN +Cj4gPiArCQlyZXQgPSBoaWRfc2Vuc29yX3JlYWRfcmF3X2h5c3RfdmFsdWUoDQo+ID4gKwkJCQkm +dGVtcGVyYXR1cmVfc3RhdGUtDQo+ID4gPmNvbW1vbl9hdHRyaWJ1dGVzLA0KPiA+ICsJCQkJdmFs +LCB2YWwyKTsNCj4gPiArCQlicmVhazsNCj4gPiArCWRlZmF1bHQ6DQo+ID4gKwkJcmV0ID0gLUVJ +TlZBTDsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwlyZXR1cm4gcmV0Ow0KPiA+ICt9DQo+ID4gKw0K +PiA+ICsvKiBDaGFubmVsIHdyaXRlX3JhdyBoYW5kbGVyICovDQo+IA0KPiBQZXJoYXBzIGRyb3Ag +dGhlIG1vcmUgb2J2aW91cyBjb21tZW50cyBhcyBub3QgbmVjZXNzYXJpbHkgcHJvdmlkaW5nDQo+ +IGFueSBhZGRpdGlvbmFsIGluZm8uwqDCoEkgZG9uJ3QgcmVhbGx5IG1pbmQgaWYgeW91IGZlZWwg +dGhleSBhcmUgdXNlZnVsDQo+IGhvd2V2ZXIgYW5kIHdhbnQgdG8ga2VlcCB0aGVtLg0KPiA+ICtz +dGF0aWMgaW50IHRlbXBlcmF0dXJlX3dyaXRlX3JhdyhzdHJ1Y3QgaWlvX2RldiAqaW5kaW9fZGV2 +LA0KPiA+ICsJCQkJc3RydWN0IGlpb19jaGFuX3NwZWMgY29uc3QgKmNoYW4sDQo+ID4gKwkJCQlp +bnQgdmFsLCBpbnQgdmFsMiwgbG9uZyBtYXNrKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgdGVtcGVy +YXR1cmVfc3RhdGUgKnRlbXBlcmF0dXJlX3N0YXRlID0NCj4gPiBpaW9fcHJpdihpbmRpb19kZXYp +Ow0KPiA+ICsJaW50IHJldDsNCj4gPiArDQo+ID4gKwlzd2l0Y2ggKG1hc2spIHsNCj4gPiArCWNh +c2UgSUlPX0NIQU5fSU5GT19TQU1QX0ZSRVE6DQo+ID4gKwkJcmV0ID0gaGlkX3NlbnNvcl93cml0 +ZV9zYW1wX2ZyZXFfdmFsdWUoDQo+ID4gKwkJCQkmdGVtcGVyYXR1cmVfc3RhdGUtDQo+ID4gPmNv +bW1vbl9hdHRyaWJ1dGVzLCB2YWwsDQo+ID4gKwkJCQl2YWwyKTsNCj4gDQo+IEFzIHdpdGggdGhl +IHJlYWRfcmF3IGFib3ZlLCByZXR1cm4gZGlyZWN0bHkgd2l0aGluIHRoZXNlIHN0YXRlbWVudHMN +Cj4gcmF0aGVyIHRoYW4NCj4gaGF2aW5nIHRvIGJvdGhlciB3aXRoIGJyZWFraW5nIG91dCBvZiB0 +aGUgc3dpdGNoIGFuZCB0aGVuIGRvaW5nIGl0Lg0KPiBUaWRpZXIgY29kZSB0aGF0IHdheS4NCj4g +DQo+IHJldHVybiBoaWRfc2Vuc29yLi4uLg0KPiA+ICsJCWJyZWFrOw0KPiA+ICsJY2FzZSBJSU9f +Q0hBTl9JTkZPX0hZU1RFUkVTSVM6DQo+ID4gKwkJcmV0ID0gaGlkX3NlbnNvcl93cml0ZV9yYXdf +aHlzdF92YWx1ZSgNCj4gPiArCQkJCSZ0ZW1wZXJhdHVyZV9zdGF0ZS0NCj4gPiA+Y29tbW9uX2F0 +dHJpYnV0ZXMsIHZhbCwNCj4gPiArCQkJCXZhbDIpOw0KPiA+ICsJCWJyZWFrOw0KPiA+ICsJZGVm +YXVsdDoNCj4gPiArCQlyZXQgPSAtRUlOVkFMOw0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCXJldHVy +biByZXQ7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgaWlvX2luZm8g +dGVtcGVyYXR1cmVfaW5mbyA9IHsNCj4gPiArCS5kcml2ZXJfbW9kdWxlID0gVEhJU19NT0RVTEUs +DQo+ID4gKwkucmVhZF9yYXcgPSAmdGVtcGVyYXR1cmVfcmVhZF9yYXcsDQo+ID4gKwkud3JpdGVf +cmF3ID0gJnRlbXBlcmF0dXJlX3dyaXRlX3JhdywNCj4gPiArfTsNCj4gPiArDQo+ID4gKy8qIENh +bGxiYWNrIGhhbmRsZXIgdG8gc2VuZCBldmVudCBhZnRlciBhbGwgc2FtcGxlcyBhcmUgcmVjZWl2 +ZWQNCj4gPiBhbmQgY2FwdHVyZWQgKi8NCj4gPiArc3RhdGljIGludCB0ZW1wZXJhdHVyZV9wcm9j +X2V2ZW50KHN0cnVjdCBoaWRfc2Vuc29yX2h1Yl9kZXZpY2UNCj4gPiAqaHNkZXYsDQo+ID4gKwkJ +CQl1bnNpZ25lZCBpbnQgdXNhZ2VfaWQsIHZvaWQgKnBkZXYpDQo+ID4gK3sNCj4gPiArCXN0cnVj +dCBpaW9fZGV2ICppbmRpb19kZXYgPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsNCj4gPiAr +CXN0cnVjdCB0ZW1wZXJhdHVyZV9zdGF0ZSAqdGVtcGVyYXR1cmVfc3RhdGUgPQ0KPiA+IGlpb19w +cml2KGluZGlvX2Rldik7DQo+ID4gKw0KPiA+ICsJaWYgKGF0b21pY19yZWFkKCZ0ZW1wZXJhdHVy +ZV9zdGF0ZS0NCj4gPiA+Y29tbW9uX2F0dHJpYnV0ZXMuZGF0YV9yZWFkeSkpDQo+ID4gKwkJaWlv +X3B1c2hfdG9fYnVmZmVycyhpbmRpb19kZXYsDQo+ID4gKwkJCQkJJnRlbXBlcmF0dXJlX3N0YXRl +LQ0KPiA+ID50ZW1wZXJhdHVyZV9kYXRhKTsNCj4gPiArCXJldHVybiAwOw0KPiA+ICt9DQo+ID4g +Kw0KPiA+ICsvKiBDYXB0dXJlIHNhbXBsZXMgaW4gbG9jYWwgc3RvcmFnZSAqLw0KPiA+ICtzdGF0 +aWMgaW50IHRlbXBlcmF0dXJlX2NhcHR1cmVfc2FtcGxlKHN0cnVjdCBoaWRfc2Vuc29yX2h1Yl9k +ZXZpY2UNCj4gPiAqaHNkZXYsDQo+ID4gKwkJCQl1bnNpZ25lZCBpbnQgdXNhZ2VfaWQsIHNpemVf +dA0KPiA+IHJhd19sZW4sDQo+ID4gKwkJCQljaGFyICpyYXdfZGF0YSwgdm9pZCAqcGRldikNCj4g +PiArew0KPiA+ICsJc3RydWN0IGlpb19kZXYgKmluZGlvX2RldiA9IHBsYXRmb3JtX2dldF9kcnZk +YXRhKHBkZXYpOw0KPiA+ICsJc3RydWN0IHRlbXBlcmF0dXJlX3N0YXRlICp0ZW1wZXJhdHVyZV9z +dGF0ZSA9DQo+ID4gaWlvX3ByaXYoaW5kaW9fZGV2KTsNCj4gPiArDQo+ID4gKwlzd2l0Y2ggKHVz +YWdlX2lkKSB7DQo+ID4gKwljYXNlIEhJRF9VU0FHRV9TRU5TT1JfREFUQV9FTlZJUk9OTUVOVEFM +X1RFTVBFUkFUVVJFOg0KPiA+ICsJCXRlbXBlcmF0dXJlX3N0YXRlLT50ZW1wZXJhdHVyZV9kYXRh +ID0gKihzMzINCj4gPiAqKXJhd19kYXRhOw0KPiA+ICsJCXJldHVybiAwOw0KPiA+ICsJZGVmYXVs +dDoNCj4gPiArCQlyZXR1cm4gLUVJTlZBTDsNCj4gPiArCX0NCj4gPiArfQ0KPiA+ICsNCj4gPiAr +LyogUGFyc2UgcmVwb3J0IHdoaWNoIGlzIHNwZWNpZmljIHRvIGFuIHVzYWdlIGlkKi8NCj4gPiAr +c3RhdGljIGludCB0ZW1wZXJhdHVyZV9wYXJzZV9yZXBvcnQoc3RydWN0IHBsYXRmb3JtX2Rldmlj +ZSAqcGRldiwNCj4gPiArCQkJCXN0cnVjdCBoaWRfc2Vuc29yX2h1Yl9kZXZpY2UNCj4gPiAqaHNk +ZXYsDQo+ID4gKwkJCQlzdHJ1Y3QgaWlvX2NoYW5fc3BlYyAqY2hhbm5lbHMsDQo+ID4gKwkJCQl1 +bnNpZ25lZCBpbnQgdXNhZ2VfaWQsDQo+ID4gKwkJCQlzdHJ1Y3QgdGVtcGVyYXR1cmVfc3RhdGUg +KnN0KQ0KPiA+ICt7DQo+ID4gKwlpbnQgcmV0Ow0KPiA+ICsNCj4gPiArCXJldCA9IHNlbnNvcl9o +dWJfaW5wdXRfZ2V0X2F0dHJpYnV0ZV9pbmZvKGhzZGV2LA0KPiA+IEhJRF9JTlBVVF9SRVBPUlQs +DQo+ID4gKwkJCXVzYWdlX2lkLA0KPiA+ICsJCQlISURfVVNBR0VfU0VOU09SX0RBVEFfRU5WSVJP +Tk1FTlRBTF9URU1QRVINCj4gPiBBVFVSRSwNCj4gPiArCQkJJnN0LT50ZW1wZXJhdHVyZV9hdHRy +KTsNCj4gPiArCWlmIChyZXQgPCAwKQ0KPiA+ICsJCXJldHVybiByZXQ7DQo+ID4gKw0KPiA+ICsJ +dGVtcGVyYXR1cmVfYWRqdXN0X2NoYW5uZWxfYml0X21hc2soY2hhbm5lbHMsIDAsDQo+ID4gKwkJ +CQkJc3QtDQo+ID4gPnRlbXBlcmF0dXJlX2F0dHIuc2l6ZSk7DQo+ID4gKw0KPiA+ICsJc3QtPnNj +YWxlX3ByZWNpc2lvbiA9IGhpZF9zZW5zb3JfZm9ybWF0X3NjYWxlKA0KPiA+ICsJCQkJSElEX1VT +QUdFX1NFTlNPUl9URU1QRVJBVFVSRSwNCj4gPiArCQkJCSZzdC0+dGVtcGVyYXR1cmVfYXR0ciwN +Cj4gPiArCQkJCSZzdC0+c2NhbGVfcHJlX2RlY21sLCAmc3QtDQo+ID4gPnNjYWxlX3Bvc3RfZGVj +bWwpOw0KPiA+ICsNCj4gPiArCS8qIFNldCBTZW5zaXRpdml0eSBmaWVsZCBpZHMsIHdoZW4gdGhl +cmUgaXMgbm8gaW5kaXZpZHVhbA0KPiA+IG1vZGlmaWVyICovDQo+ID4gKwlpZiAoc3QtPmNvbW1v +bl9hdHRyaWJ1dGVzLnNlbnNpdGl2aXR5LmluZGV4IDwgMCkNCj4gPiArCQlzZW5zb3JfaHViX2lu +cHV0X2dldF9hdHRyaWJ1dGVfaW5mbyhoc2RldiwNCj4gPiArCQkJSElEX0ZFQVRVUkVfUkVQT1JU +LCB1c2FnZV9pZCwNCj4gPiArCQkJSElEX1VTQUdFX1NFTlNPUl9EQVRBX01PRF9DSEFOR0VfU0VO +U0lUSVZJDQo+ID4gVFlfQUJTIHwNCj4gPiArCQkJSElEX1VTQUdFX1NFTlNPUl9EQVRBX0VOVklS +T05NRU5UQUxfVEVNUEVSDQo+ID4gQVRVUkUsDQo+ID4gKwkJCSZzdC0+Y29tbW9uX2F0dHJpYnV0 +ZXMuc2Vuc2l0aXZpdHkpOw0KPiA+ICsNCj4gPiArCXJldHVybiByZXQ7DQo+ID4gK30NCj4gPiAr +DQo+ID4gK3N0YXRpYyBzdHJ1Y3QgaGlkX3NlbnNvcl9odWJfY2FsbGJhY2tzIHRlbXBlcmF0dXJl +X2NhbGxiYWNrcyA9IHsNCj4gPiArCS5zZW5kX2V2ZW50ID0gJnRlbXBlcmF0dXJlX3Byb2NfZXZl +bnQsDQo+ID4gKwkuY2FwdHVyZV9zYW1wbGUgPSAmdGVtcGVyYXR1cmVfY2FwdHVyZV9zYW1wbGUs +DQo+ID4gK307DQo+ID4gKw0KPiA+ICsvKiBGdW5jdGlvbiB0byBpbml0aWFsaXplIHRoZSBwcm9j +ZXNzaW5nIGZvciB1c2FnZSBpZCAqLw0KPiA+ICtzdGF0aWMgaW50IGhpZF90ZW1wZXJhdHVyZV9w +cm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQ0KPiA+ICt7DQo+ID4gKwlzdGF0aWMg +Y29uc3QgY2hhciAqbmFtZSA9ICJ0ZW1wZXJhdHVyZSI7DQo+ID4gKwlzdHJ1Y3QgaWlvX2RldiAq +aW5kaW9fZGV2Ow0KPiA+ICsJc3RydWN0IHRlbXBlcmF0dXJlX3N0YXRlICp0ZW1wZXJhdHVyZV9z +dGF0ZTsNCj4gDQo+IE1heWJlIHNob3J0ZW4gdGhlIHZhcmlhYmxlIG5hbWUgdG8gbGVhZCB0byBz +b21lIHNob3J0ZXIgbGluZXMgbGF0ZXI/DQo+IHRlbXBfc3QgZm9yIGV4YW1wbGUgd291bGQgSSB0 +aGluayBjb252ZXkgZW5vdWdoIG1lYW5pbmcuDQo+IA0KPiA+ICsJc3RydWN0IGhpZF9zZW5zb3Jf +aHViX2RldmljZSAqaHNkZXYgPSBwZGV2LQ0KPiA+ID5kZXYucGxhdGZvcm1fZGF0YTsNCj4gPiAr +CWludCByZXQ7DQo+ID4gKw0KPiA+ICsJaW5kaW9fZGV2ID0gZGV2bV9paW9fZGV2aWNlX2FsbG9j +KCZwZGV2LT5kZXYsDQo+ID4gKwkJCQlzaXplb2Yoc3RydWN0IHRlbXBlcmF0dXJlX3N0YXRlKSk7 +DQo+IA0KPiBFdmVyIHNvIHNsaWdodCBwcmVmZXJlbmNlIGZvciBzaXplb2YoKnRlbXBlcmF0dXJl +X3N0YXRlKQ0KPiANCj4gPiArCWlmICghaW5kaW9fZGV2KQ0KPiA+ICsJCXJldHVybiAtRU5PTUVN +Ow0KPiA+ICsNCj4gPiArCXRlbXBlcmF0dXJlX3N0YXRlID0gaWlvX3ByaXYoaW5kaW9fZGV2KTsN +Cj4gPiArCXRlbXBlcmF0dXJlX3N0YXRlLT5jb21tb25fYXR0cmlidXRlcy5oc2RldiA9IGhzZGV2 +Ow0KPiA+ICsJdGVtcGVyYXR1cmVfc3RhdGUtPmNvbW1vbl9hdHRyaWJ1dGVzLnBkZXYgPSBwZGV2 +Ow0KPiA+ICsNCj4gPiArCXJldCA9IGhpZF9zZW5zb3JfcGFyc2VfY29tbW9uX2F0dHJpYnV0ZXMo +aHNkZXYsDQo+ID4gKwkJCQkJSElEX1VTQUdFX1NFTlNPUl9URU1QRVJBVFUNCj4gPiBSRSwNCj4g +PiArCQkJCQkmdGVtcGVyYXR1cmVfc3RhdGUtDQo+ID4gPmNvbW1vbl9hdHRyaWJ1dGVzKTsNCj4g +PiArCWlmIChyZXQpDQo+ID4gKwkJcmV0dXJuIHJldDsNCj4gPiArDQo+ID4gKwlpbmRpb19kZXYt +PmNoYW5uZWxzID0gZGV2bV9rbWVtZHVwKCZpbmRpb19kZXYtPmRldiwNCj4gDQo+IG1heWJlIHJl +bmFtZSBhcyB0ZW1wX2NoYW5zIGFzIHZlcmJvc2l0eSBub3QgYWRkaW5nIG11Y2ggaGVyZS4NCj4g +PiArCQkJCQl0ZW1wZXJhdHVyZV9jaGFubmVscywNCj4gPiArCQkJCQlzaXplb2YodGVtcGVyYXR1 +cmVfY2hhbm5lbA0KPiA+IHMpLA0KPiA+ICsJCQkJCUdGUF9LRVJORUwpOw0KPiA+ICsJaWYgKCFp +bmRpb19kZXYtPmNoYW5uZWxzKQ0KPiA+ICsJCXJldHVybiAtRU5PTUVNOw0KPiA+ICsNCj4gPiAr +CXJldCA9IHRlbXBlcmF0dXJlX3BhcnNlX3JlcG9ydChwZGV2LCBoc2RldiwNCj4gPiArCQkJCShz +dHJ1Y3QgaWlvX2NoYW5fc3BlYyAqKWluZGlvX2Rldi0NCj4gPiA+Y2hhbm5lbHMsDQo+IA0KPiBU +aGlzIGlzIGNhc3RpbmcgYXdheSBhIGNvbnN0LCB3aGljaCBJIGRvbid0IHBhcnRpY3VsYXJseSBs +aWtlLg0KPiBJJ2QgcHJlZmVyIHRoYXQgeW91IHVzZWQgYSBsb2NhbCB2YXJpYWJsZSwgZ290IGV2 +ZXJ0aGluZyBzZXR1cCBhcyB5b3UNCj4gbGlrZQ0KPiBhbmQgdGhlbiBhc3NpZ25lZCBpbmRpb19k +ZXYtPmNoYW5uZWxzIHRvIGl0LsKgwqBTZW1hbnRpY2FsbHkgc2xpZ2h0bHkNCj4gbmljZXIgYXMN +Cj4gYXNzdW1wdGlvbiBpcyB0aGF0IHRoZXkgYXJlIGNvbnN0IGlmIGFjY2Vzc2VkIHZpYSB0aGlz +IGVsZW1lbnQgb2YNCj4gc3RydWN0DQo+IGlpb19kZXYgKGhlcmUgd2Ugb2J2aW91c2x5IGtub3cg +d2UgY2FuIGNoYW5nZSB0aGVtIGJ1dCBpdCdzIHN0aWxsIG5vdA0KPiBuaWNlISkNCj4gDQo+ID4g +KwkJCQlISURfVVNBR0VfU0VOU09SX1RFTVBFUkFUVVJFLA0KPiA+ICsJCQkJdGVtcGVyYXR1cmVf +c3RhdGUpOw0KPiA+ICsJaWYgKHJldCkNCj4gPiArCQlyZXR1cm4gcmV0Ow0KPiA+ICsNCj4gPiAr +CWluZGlvX2Rldi0+bnVtX2NoYW5uZWxzID0NCj4gPiBBUlJBWV9TSVpFKHRlbXBlcmF0dXJlX2No +YW5uZWxzKTsNCj4gPiArCWluZGlvX2Rldi0+ZGV2LnBhcmVudCA9ICZwZGV2LT5kZXY7DQo+ID4g +KwlpbmRpb19kZXYtPmluZm8gPSAmdGVtcGVyYXR1cmVfaW5mbzsNCj4gPiArCWluZGlvX2Rldi0+ +bmFtZSA9IG5hbWU7DQo+ID4gKwlpbmRpb19kZXYtPm1vZGVzID0gSU5ESU9fRElSRUNUX01PREU7 +DQo+ID4gKw0KPiA+ICsJcmV0ID0gZGV2bV9paW9fdHJpZ2dlcmVkX2J1ZmZlcl9zZXR1cCgmcGRl +di0+ZGV2LA0KPiA+IGluZGlvX2RldiwNCj4gPiArCQkJCQkmaWlvX3BvbGxmdW5jX3N0b3JlX3Rp +bWUsDQo+IA0KPiBPZGRpdHkgaGVyZSBhcyB5b3UgZG9uJ3QgYWN0dWFsbHkgdXNlIHRoZSB0aW1l +c3RhbXAuLi4NCj4gPiArCQkJCQlOVUxMLCBOVUxMKTsNCj4gPiArCWlmIChyZXQpDQo+ID4gKwkJ +cmV0dXJuIHJldDsNCj4gPiArDQo+ID4gKwlhdG9taWNfc2V0KCZ0ZW1wZXJhdHVyZV9zdGF0ZS0N +Cj4gPiA+Y29tbW9uX2F0dHJpYnV0ZXMuZGF0YV9yZWFkeSwgMCk7DQo+ID4gKwlyZXQgPSBoaWRf +c2Vuc29yX3NldHVwX3RyaWdnZXIoaW5kaW9fZGV2LCBuYW1lLA0KPiA+ICsJCQkJJnRlbXBlcmF0 +dXJlX3N0YXRlLQ0KPiA+ID5jb21tb25fYXR0cmlidXRlcyk7DQo+ID4gKwlpZiAocmV0KQ0KPiA+ +ICsJCXJldHVybiByZXQ7DQo+ID4gKw0KPiA+ICsJcGxhdGZvcm1fc2V0X2RydmRhdGEocGRldiwg +aW5kaW9fZGV2KTsNCj4gPiArDQo+ID4gKwl0ZW1wZXJhdHVyZV9jYWxsYmFja3MucGRldiA9IHBk +ZXY7DQo+ID4gKwlyZXQgPSBzZW5zb3JfaHViX3JlZ2lzdGVyX2NhbGxiYWNrKGhzZGV2LA0KPiA+ +IEhJRF9VU0FHRV9TRU5TT1JfVEVNUEVSQVRVUkUsDQo+ID4gKwkJCQkJJnRlbXBlcmF0dXJlX2Nh +bGxiYWNrcyk7DQo+ID4gKwlpZiAocmV0KQ0KPiA+ICsJCWdvdG8gZXJyb3JfcmVtb3ZlX3RyaWdn +ZXI7DQo+ID4gKw0KPiA+ICsJcmV0ID0gZGV2bV9paW9fZGV2aWNlX3JlZ2lzdGVyKGluZGlvX2Rl +di0+ZGV2LnBhcmVudCwNCj4gPiBpbmRpb19kZXYpOw0KPiA+ICsJaWYgKHJldCkNCj4gPiArCQln +b3RvIGVycm9yX3JlbW92ZV9jYWxsYmFjazsNCj4gPiArDQo+ID4gKwlyZXR1cm4gcmV0Ow0KPiA+ +ICsNCj4gPiArZXJyb3JfcmVtb3ZlX2NhbGxiYWNrOg0KPiA+ICsJc2Vuc29yX2h1Yl9yZW1vdmVf +Y2FsbGJhY2soaHNkZXYsDQo+ID4gSElEX1VTQUdFX1NFTlNPUl9URU1QRVJBVFVSRSk7DQo+ID4g +K2Vycm9yX3JlbW92ZV90cmlnZ2VyOg0KPiA+ICsJaGlkX3NlbnNvcl9yZW1vdmVfdHJpZ2dlcigm +dGVtcGVyYXR1cmVfc3RhdGUtDQo+ID4gPmNvbW1vbl9hdHRyaWJ1dGVzKTsNCj4gPiArCXJldHVy +biByZXQ7DQo+ID4gK30NCj4gPiArDQo+ID4gKy8qIEZ1bmN0aW9uIHRvIGRlaW5pdGlhbGl6ZSB0 +aGUgcHJvY2Vzc2luZyBmb3IgdXNhZ2UgaWQgKi8NCj4gPiArc3RhdGljIGludCBoaWRfdGVtcGVy +YXR1cmVfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpDQo+ID4gK3sNCj4gPiAr +CXN0cnVjdCBoaWRfc2Vuc29yX2h1Yl9kZXZpY2UgKmhzZGV2ID0gcGRldi0NCj4gPiA+ZGV2LnBs +YXRmb3JtX2RhdGE7DQo+IA0KPiBJcyBpdCBqdXN0IG1lIHRoYXQgZmVlbHMgdGhhdCBmb3IgY29u +c2lzdGVuY2UgdGhlcmUgc2hvdWxkIGJlIGENCj4gcGxhdGZvcm1fZ2V0X3BsYXRmb3JtX2RhdGEo +KSBmdW5jdGlvbj8NCj4gQSB3ZWxsLCBjYW4ndCBzYXkgaXQgd291bGQgcmVhbGx5IGFkZCBhbnl0 +aGluZywganVzdCBteSBzZW5zZSBvZg0KPiBjb25zaXN0ZW5jeSBraWNraW5nIGluIDspDQo+IEFu +eWhvdywgbm90IHJlYWxseSBhbnl0aGluZyB0byBkbyB3aXRoIHRoaXMgZHJpdmVyIHJldmlldyBz +byBmZWVsDQo+IGZyZWUgdG8gaWdub3JlIQ0KPiANCj4gPiArCXN0cnVjdCBpaW9fZGV2ICppbmRp +b19kZXYgPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsNCj4gPiArCXN0cnVjdCB0ZW1wZXJh +dHVyZV9zdGF0ZSAqdGVtcGVyYXR1cmVfc3RhdGUgPQ0KPiA+IGlpb19wcml2KGluZGlvX2Rldik7 +DQo+ID4gKw0KPiA+ICsJc2Vuc29yX2h1Yl9yZW1vdmVfY2FsbGJhY2soaHNkZXYsDQo+ID4gSElE +X1VTQUdFX1NFTlNPUl9URU1QRVJBVFVSRSk7DQo+ID4gKwloaWRfc2Vuc29yX3JlbW92ZV90cmln +Z2VyKCZ0ZW1wZXJhdHVyZV9zdGF0ZS0NCj4gPiA+Y29tbW9uX2F0dHJpYnV0ZXMpOw0KPiA+ICsN +Cj4gPiArCXJldHVybiAwOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3Qgc3RydWN0 +IHBsYXRmb3JtX2RldmljZV9pZCBoaWRfdGVtcGVyYXR1cmVfaWRzW10gPSB7DQo+ID4gKwl7DQo+ +ID4gKwkJLyogRm9ybWF0OiBISUQtU0VOU09SLXVzYWdlX2lkX2luX2hleF9sb3dlcmNhc2UgKi8N +Cj4gPiArCQkubmFtZSA9ICJISUQtU0VOU09SLTIwMDAzMyIsDQo+ID4gKwl9LA0KPiA+ICsJeyAv +KiBzZW50aW5lbCAqLyB9DQo+ID4gK307DQo+ID4gK01PRFVMRV9ERVZJQ0VfVEFCTEUocGxhdGZv +cm0sIGhpZF90ZW1wZXJhdHVyZV9pZHMpOw0KPiA+ICsNCj4gPiArc3RhdGljIHN0cnVjdCBwbGF0 +Zm9ybV9kcml2ZXIgaGlkX3RlbXBlcmF0dXJlX3BsYXRmb3JtX2RyaXZlciA9IHsNCj4gPiArCS5p +ZF90YWJsZSA9IGhpZF90ZW1wZXJhdHVyZV9pZHMsDQo+ID4gKwkuZHJpdmVyID0gew0KPiA+ICsJ +CS5uYW1lCT0gS0JVSUxEX01PRE5BTUUsDQo+ID4gKwkJLnBtCT0gJmhpZF9zZW5zb3JfcG1fb3Bz +LA0KPiA+ICsJfSwNCj4gPiArCS5wcm9iZQkJPSBoaWRfdGVtcGVyYXR1cmVfcHJvYmUsDQo+ID4g +KwkucmVtb3ZlCQk9IGhpZF90ZW1wZXJhdHVyZV9yZW1vdmUsDQo+ID4gK307DQo+ID4gK21vZHVs +ZV9wbGF0Zm9ybV9kcml2ZXIoaGlkX3RlbXBlcmF0dXJlX3BsYXRmb3JtX2RyaXZlcik7DQo+ID4g +Kw0KPiA+ICtNT0RVTEVfREVTQ1JJUFRJT04oIkhJRCBFbnZpcm9ubWVudGFsIHRlbXBlcmF0dXJl +IHNlbnNvciIpOw0KPiA+ICtNT0RVTEVfQVVUSE9SKCJTb25nIEhvbmd5YW4gPGhvbmd5YW4uc29u +Z0BpbnRlbC5jb20+Iik7DQo+ID4gK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsNCj4gPiBkaWZm +IC0tZ2l0IGEvaW5jbHVkZS9saW51eC9oaWQtc2Vuc29yLWlkcy5oIGIvaW5jbHVkZS9saW51eC9o +aWQtDQo+ID4gc2Vuc29yLWlkcy5oDQo+ID4gaW5kZXggYmFiODM3NS4uZWNlYzk3OCAxMDA2NDQN +Cj4gPiAtLS0gYS9pbmNsdWRlL2xpbnV4L2hpZC1zZW5zb3ItaWRzLmgNCj4gPiArKysgYi9pbmNs +dWRlL2xpbnV4L2hpZC1zZW5zb3ItaWRzLmgNCj4gPiBAQCAtNDUsNiArNDUsMTAgQEANCj4gPiDC +oCNkZWZpbmUNCj4gPiBISURfVVNBR0VfU0VOU09SX0RBVEFfQVRNT1NQSEVSSUNfUFJFU1NVUkXC +oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgMHgyMDA0MzANCj4gPiDCoCNkZWZpbmUNCj4gPiBI +SURfVVNBR0VfU0VOU09SX0FUTU9TUEhFUklDX1BSRVNTVVJFwqDCoMKgwqDCoMKgwqDCoMKgwqDC +oMKgwqDCoMKgwqDCoMKgwqAweDIwMDQzMQ0KPiA+IMKgDQo+ID4gKy8qIFRlbXByZXR1cmUgKDIw +MDAzMykgKi8NCj4gPiArI2RlZmluZQlISURfVVNBR0VfU0VOU09SX1RFTVBFUkFUVVJFCQkJDQo+ +ID4gCTB4MjAwMDMzDQo+ID4gKyNkZWZpbmUJSElEX1VTQUdFX1NFTlNPUl9EQVRBX0VOVklST05N +RU5UQUxfVEVNUEVSQVRVUkUJDQo+ID4gCTB4MjAwNDM0DQo+ID4gKw0KPiA+IMKgLyogR3lybyAz +RDogKDIwMDA3NikgKi8NCj4gPiDCoCNkZWZpbmUgSElEX1VTQUdFX1NFTlNPUl9HWVJPXzNECQkJ +CTB4DQo+ID4gMjAwMDc2DQo+ID4gwqAjZGVmaW5lIEhJRF9VU0FHRV9TRU5TT1JfREFUQV9BTkdM +X1ZFTE9DSVRZCQkJDQo+ID4gMHgyMDA0NTYNCj4gPiANCj4gDQo+IA== diff --git a/a/content_digest b/N1/content_digest index 9e109d9..987db68 100644 --- a/a/content_digest +++ b/N1/content_digest @@ -11,577 +11,333 @@ "Cc\0jikos@kernel.org <jikos@kernel.org>\0" "\00:1\0" "b\0" - "On Sun, 2017-02-19 at 11:48 +0000, Jonathan Cameron wrote:\n" - "> On 13/02/17 09:49, Song Hongyan wrote:\n" - "> > Environmental temperature sensor is a hid defined sensor,\n" - "> > it measures temperature.\n" - "> > \n" - "> > More information can be found in:\n" - "> > http://www.usb.org/developers/hidpage/HUTRR39b.pdf\n" - "> > \n" - "> > According to IIO ABI definition, IIO_TEMP data output unit is\n" - "> > milli degrees Celsius. Add the unit convert from degree to milli\n" - "> > degree.\n" - "> > \n" - "> > Signed-off-by: Song Hongyan <hongyan.song@intel.com>\n" - "> \n" - "> Hi Song,\n" - "> \n" - "> I'm afraid I haven't really been taking a close look at the previous\n" - "> versions so a few comments inline from me that might otherwise have\n" - "> come on earlier versions.\n" - "> \n" - "> I will be looking for a reviewed-by or Ack from Srinivas on this\n" - "> before taking it (mostly to reflect the effort he has put in on those\n" - "> earlier reviews!)\n" - "Hongyan,\n" - "\n" - "You can add\n" - "\n" - "Acked-by: Srinivas Pandruvada <srinivas.pandruvada@linux.intel.com>\n" - "\n" - "after addressing Jonathan's comments.\n" - "\n" - "Thanks,\n" - "Srinivas\n" - "\n" - "> \n" - "> Jonathan\n" - "> > ---\n" - "> > \302\240.../iio/common/hid-sensors/hid-sensor-attributes.c |\302\240\302\240\302\2403 +\n" - "> > \302\240drivers/iio/temperature/Kconfig\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240|\302\240\302\24014 +\n" - "> > \302\240drivers/iio/temperature/Makefile\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240|\302\240\302\240\302\2401 +\n" - "> > \302\240drivers/iio/temperature/hid-sensor-temperature.c\302\240\302\240\302\240| 326\n" - "> > +++++++++++++++++++++\n" - "> > \302\240include/linux/hid-sensor-ids.h\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240|\302\240\302\240\302\2404 +\n" - "> > \302\2405 files changed, 348 insertions(+)\n" - "> > \302\240create mode 100644 drivers/iio/temperature/hid-sensor-\n" - "> > temperature.c\n" - "> > \n" - "> > diff --git a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c \n" - "> > b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c\n" - "> > index 7ef94a9..68c2bb0 100644\n" - "> > --- a/drivers/iio/common/hid-sensors/hid-sensor-attributes.c\n" - "> > +++ b/drivers/iio/common/hid-sensors/hid-sensor-attributes.c\n" - "> > @@ -58,6 +58,9 @@\n" - "> > \302\240\n" - "> > \302\240\t{HID_USAGE_SENSOR_PRESSURE, 0, 100, 0},\n" - "> > \302\240\t{HID_USAGE_SENSOR_PRESSURE, HID_USAGE_SENSOR_UNITS_PASCAL,\n" - "> > 0, 1000000},\n" - "> > +\n" - "> > +\t{HID_USAGE_SENSOR_TEMPERATURE, 0, 1000, 0},\n" - "> > +\t{HID_USAGE_SENSOR_TEMPERATURE,\n" - "> > HID_USAGE_SENSOR_UNITS_DEGREES, 1000, 0},\n" - "> > \302\240};\n" - "> > \302\240\n" - "> > \302\240static int pow_10(unsigned power)\n" - "> > diff --git a/drivers/iio/temperature/Kconfig\n" - "> > b/drivers/iio/temperature/Kconfig\n" - "> > index 5ea77a7..5f7b9f7 100644\n" - "> > --- a/drivers/iio/temperature/Kconfig\n" - "> > +++ b/drivers/iio/temperature/Kconfig\n" - "> > @@ -19,6 +19,20 @@ config MAXIM_THERMOCOUPLE\n" - "> > \302\240\t\302\240\302\240This driver can also be built as a module. If so, the\n" - "> > module will\n" - "> > \302\240\t\302\240\302\240be called maxim_thermocouple.\n" - "> > \302\240\n" - "> > +config HID_SENSOR_TEMP\n" - "> > +\ttristate \"HID Environmental temperature sensor\"\n" - "> > +\tdepends on HID_SENSOR_HUB\n" - "> > +\tselect IIO_BUFFER\n" - "> > +\tselect IIO_TRIGGERED_BUFFER\n" - "> > +\tselect HID_SENSOR_IIO_COMMON\n" - "> > +\tselect HID_SENSOR_IIO_TRIGGER\n" - "> > +\thelp\n" - "> > +\t\302\240\302\240Say yes here to build support for the HID SENSOR\n" - "> > +\t\302\240\302\240temperature driver\n" - "> > +\n" - "> > +\t\302\240\302\240To compile this driver as a module, choose M here: the\n" - "> > module\n" - "> > +\t\302\240\302\240will be called hid-sensor-temperature.\n" - "> > +\n" - "> > \302\240config MLX90614\n" - "> > \302\240\ttristate \"MLX90614 contact-less infrared sensor\"\n" - "> > \302\240\tdepends on I2C\n" - "> > diff --git a/drivers/iio/temperature/Makefile\n" - "> > b/drivers/iio/temperature/Makefile\n" - "> > index 78c3de0..e157eda 100644\n" - "> > --- a/drivers/iio/temperature/Makefile\n" - "> > +++ b/drivers/iio/temperature/Makefile\n" - "> > @@ -7,3 +7,4 @@ obj-$(CONFIG_MLX90614) += mlx90614.o\n" - "> > \302\240obj-$(CONFIG_TMP006) += tmp006.o\n" - "> > \302\240obj-$(CONFIG_TSYS01) += tsys01.o\n" - "> > \302\240obj-$(CONFIG_TSYS02D) += tsys02d.o\n" - "> > +obj-$(CONFIG_HID_SENSOR_TEMP)\302\240\302\240\302\240+= hid-sensor-temperature.o\n" - "> > diff --git a/drivers/iio/temperature/hid-sensor-temperature.c\n" - "> > b/drivers/iio/temperature/hid-sensor-temperature.c\n" - "> > new file mode 100644\n" - "> > index 0000000..84abd2d\n" - "> > --- /dev/null\n" - "> > +++ b/drivers/iio/temperature/hid-sensor-temperature.c\n" - "> > @@ -0,0 +1,326 @@\n" - "> > +/* HID Sensors Driver\n" - "> > + * Copyright (c) 2017, Intel Corporation.\n" - "> > + *\n" - "> > + * This program is free software; you can redistribute it and/or\n" - "> > modify it\n" - "> > + * under the terms and conditions of the GNU General Public\n" - "> > License,\n" - "> > + * version 2, as published by the Free Software Foundation.\n" - "> > + *\n" - "> > + * This program is distributed in the hope it will be useful, but\n" - "> > WITHOUT\n" - "> > + * ANY WARRANTY; without even the implied warranty of\n" - "> > MERCHANTABILITY or\n" - "> > + * FITNESS FOR A PARTICULAR PURPOSE.\302\240\302\240See the GNU General Public\n" - "> > License for\n" - "> > + * more details.\n" - "> > + *\n" - "> > + * You should have received a copy of the GNU General Public\n" - "> > License along with\n" - "> > + * this program.\n" - "> > + *\n" - "> > + */\n" - "> > +#include <linux/device.h>\n" - "> > +#include <linux/hid-sensor-hub.h>\n" - "> > +#include <linux/iio/buffer.h>\n" - "> > +#include <linux/iio/iio.h>\n" - "> > +#include <linux/iio/triggered_buffer.h>\n" - "> > +#include <linux/iio/trigger_consumer.h>\n" - "> > +#include <linux/module.h>\n" - "> > +#include <linux/platform_device.h>\n" - "> > +#include \"../common/hid-sensors/hid-sensor-trigger.h\"\n" - "> > +\n" - "> > +struct temperature_state {\n" - "> > +\tstruct hid_sensor_common common_attributes;\n" - "> > +\tstruct hid_sensor_hub_attribute_info temperature_attr;\n" - "> > +\ts32 temperature_data;\n" - "> > +\tint scale_pre_decml;\n" - "> > +\tint scale_post_decml;\n" - "> > +\tint scale_precision;\n" - "> > +\tint value_offset;\n" - "> > +};\n" - "> > +\n" - "> > +/* Channel definitions */\n" - "> > +static const struct iio_chan_spec temperature_channels[] = {\n" - "> > +\t{\n" - "> > +\t\t.type = IIO_TEMP,\n" - "> > +\t\t.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),\n" - "> > +\t\t.info_mask_shared_by_type =\n" - "> > BIT(IIO_CHAN_INFO_OFFSET) |\n" - "> > +\t\t\tBIT(IIO_CHAN_INFO_SCALE) |\n" - "> > +\t\t\tBIT(IIO_CHAN_INFO_SAMP_FREQ) |\n" - "> > +\t\t\tBIT(IIO_CHAN_INFO_HYSTERESIS),\n" - "> > +\t\t.scan_index = 0,\n" - "> > +\t}\n" - "> > +};\n" - "> > +\n" - "> > +/* Adjust channel real bits based on report descriptor */\n" - "> > +static void temperature_adjust_channel_bit_mask(struct\n" - "> > iio_chan_spec *channels,\n" - "> > +\t\t\t\t\tint channel, int size)\n" - "> > +{\n" - "> > +\tchannels[channel].scan_type.sign = 's';\n" - "> > +\t/* Real storage bits will change based on the report desc.\n" - "> > */\n" - "> > +\tchannels[channel].scan_type.realbits = size * 8;\n" - "> > +\t/* Maximum size of a sample to capture is s32 */\n" - "> > +\tchannels[channel].scan_type.storagebits = sizeof(s32) * 8;\n" - "> > +}\n" - "> > +\n" - "> > +/* Channel read_raw handler */\n" - "> > +static int temperature_read_raw(struct iio_dev *indio_dev,\n" - "> > +\t\t\t\tstruct iio_chan_spec const *chan,\n" - "> > +\t\t\t\tint *val, int *val2, long mask)\n" - "> > +{\n" - "> > +\tstruct temperature_state *temperature_state =\n" - "> > iio_priv(indio_dev);\n" - "> > +\tint ret;\n" - "> > +\n" - "> > +\tswitch (mask) {\n" - "> > +\tcase IIO_CHAN_INFO_RAW:\n" - "> > +\t\tif (chan->type == IIO_TEMP) {\n" - "> > +\t\t\thid_sensor_power_state(\n" - "> > +\t\t\t\t&temperature_state-\n" - "> > >common_attributes, true);\n" - "> > +\t\t\t*val =\n" - "> > sensor_hub_input_attr_get_raw_value(\n" - "> > +\t\t\t\ttemperature_state-\n" - "> > >common_attributes.hsdev,\n" - "> > +\t\t\t\tHID_USAGE_SENSOR_TEMPERATURE,\n" - "> > +\t\t\t\tHID_USAGE_SENSOR_DATA_ENVIRONMENTA\n" - "> > L_TEMPERATURE,\n" - "> > +\t\t\t\ttemperature_state-\n" - "> > >temperature_attr.report_id,\n" - "> > +\t\t\t\tSENSOR_HUB_SYNC);\n" - "> > +\t\t\thid_sensor_power_state(\n" - "> > +\t\t\t\t\t&temperature_state-\n" - "> > >common_attributes,\n" - "> > +\t\t\t\t\tfalse);\n" - "> > +\t\t}\n" - "> \n" - "> This is an oddity.\302\240\302\240If you get here without chan->type == IIO_TEMP\n" - "> (which you can't, but your code is kind of assuming you can)\n" - "> then you are returning that the data is valid without setting it to\n" - "> anything.\n" - "> \n" - "> I'd flip the logic\n" - "> if (chan->type != IIO_TEMP) {\n" - "> \302\240\302\240\302\240return -EINVAL;\n" - "> }\n" - "> ... normal code flow ...\n" - "> > +\t\tret = IIO_VAL_INT;\n" - "> \n" - "> There is nothing other than a return to be done after this so just\n" - "> do it directly here instead.\302\240\302\240Basic rule of thumb in kernel code is\n" - "> return as early as possible when there is no unwinding to be done.\n" - "> Same in all the branches of this switch statement pelase.\n" - "> > +\t\tbreak;\n" - "> > +\tcase IIO_CHAN_INFO_SCALE:\n" - "> > +\t\t*val = temperature_state->scale_pre_decml;\n" - "> > +\t\t*val2 = temperature_state->scale_post_decml;\n" - "> > +\t\tret = temperature_state->scale_precision;\n" - "> > +\t\tbreak;\n" - "> > +\tcase IIO_CHAN_INFO_OFFSET:\n" - "> > +\t\t*val = temperature_state->value_offset;\n" - "> > +\t\tret = IIO_VAL_INT;\n" - "> > +\t\tbreak;\n" - "> > +\tcase IIO_CHAN_INFO_SAMP_FREQ:\n" - "> > +\t\tret = hid_sensor_read_samp_freq_value(\n" - "> > +\t\t\t\t&temperature_state-\n" - "> > >common_attributes,\n" - "> > +\t\t\t\tval, val2);\n" - "> > +\t\tbreak;\n" - "> > +\tcase IIO_CHAN_INFO_HYSTERESIS:\n" - "> > +\t\tret = hid_sensor_read_raw_hyst_value(\n" - "> > +\t\t\t\t&temperature_state-\n" - "> > >common_attributes,\n" - "> > +\t\t\t\tval, val2);\n" - "> > +\t\tbreak;\n" - "> > +\tdefault:\n" - "> > +\t\tret = -EINVAL;\n" - "> > +\t}\n" - "> > +\n" - "> > +\treturn ret;\n" - "> > +}\n" - "> > +\n" - "> > +/* Channel write_raw handler */\n" - "> \n" - "> Perhaps drop the more obvious comments as not necessarily providing\n" - "> any additional info.\302\240\302\240I don't really mind if you feel they are useful\n" - "> however and want to keep them.\n" - "> > +static int temperature_write_raw(struct iio_dev *indio_dev,\n" - "> > +\t\t\t\tstruct iio_chan_spec const *chan,\n" - "> > +\t\t\t\tint val, int val2, long mask)\n" - "> > +{\n" - "> > +\tstruct temperature_state *temperature_state =\n" - "> > iio_priv(indio_dev);\n" - "> > +\tint ret;\n" - "> > +\n" - "> > +\tswitch (mask) {\n" - "> > +\tcase IIO_CHAN_INFO_SAMP_FREQ:\n" - "> > +\t\tret = hid_sensor_write_samp_freq_value(\n" - "> > +\t\t\t\t&temperature_state-\n" - "> > >common_attributes, val,\n" - "> > +\t\t\t\tval2);\n" - "> \n" - "> As with the read_raw above, return directly within these statements\n" - "> rather than\n" - "> having to bother with breaking out of the switch and then doing it.\n" - "> Tidier code that way.\n" - "> \n" - "> return hid_sensor....\n" - "> > +\t\tbreak;\n" - "> > +\tcase IIO_CHAN_INFO_HYSTERESIS:\n" - "> > +\t\tret = hid_sensor_write_raw_hyst_value(\n" - "> > +\t\t\t\t&temperature_state-\n" - "> > >common_attributes, val,\n" - "> > +\t\t\t\tval2);\n" - "> > +\t\tbreak;\n" - "> > +\tdefault:\n" - "> > +\t\tret = -EINVAL;\n" - "> > +\t}\n" - "> > +\n" - "> > +\treturn ret;\n" - "> > +}\n" - "> > +\n" - "> > +static const struct iio_info temperature_info = {\n" - "> > +\t.driver_module = THIS_MODULE,\n" - "> > +\t.read_raw = &temperature_read_raw,\n" - "> > +\t.write_raw = &temperature_write_raw,\n" - "> > +};\n" - "> > +\n" - "> > +/* Callback handler to send event after all samples are received\n" - "> > and captured */\n" - "> > +static int temperature_proc_event(struct hid_sensor_hub_device\n" - "> > *hsdev,\n" - "> > +\t\t\t\tunsigned int usage_id, void *pdev)\n" - "> > +{\n" - "> > +\tstruct iio_dev *indio_dev = platform_get_drvdata(pdev);\n" - "> > +\tstruct temperature_state *temperature_state =\n" - "> > iio_priv(indio_dev);\n" - "> > +\n" - "> > +\tif (atomic_read(&temperature_state-\n" - "> > >common_attributes.data_ready))\n" - "> > +\t\tiio_push_to_buffers(indio_dev,\n" - "> > +\t\t\t\t\t&temperature_state-\n" - "> > >temperature_data);\n" - "> > +\treturn 0;\n" - "> > +}\n" - "> > +\n" - "> > +/* Capture samples in local storage */\n" - "> > +static int temperature_capture_sample(struct hid_sensor_hub_device\n" - "> > *hsdev,\n" - "> > +\t\t\t\tunsigned int usage_id, size_t\n" - "> > raw_len,\n" - "> > +\t\t\t\tchar *raw_data, void *pdev)\n" - "> > +{\n" - "> > +\tstruct iio_dev *indio_dev = platform_get_drvdata(pdev);\n" - "> > +\tstruct temperature_state *temperature_state =\n" - "> > iio_priv(indio_dev);\n" - "> > +\n" - "> > +\tswitch (usage_id) {\n" - "> > +\tcase HID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE:\n" - "> > +\t\ttemperature_state->temperature_data = *(s32\n" - "> > *)raw_data;\n" - "> > +\t\treturn 0;\n" - "> > +\tdefault:\n" - "> > +\t\treturn -EINVAL;\n" - "> > +\t}\n" - "> > +}\n" - "> > +\n" - "> > +/* Parse report which is specific to an usage id*/\n" - "> > +static int temperature_parse_report(struct platform_device *pdev,\n" - "> > +\t\t\t\tstruct hid_sensor_hub_device\n" - "> > *hsdev,\n" - "> > +\t\t\t\tstruct iio_chan_spec *channels,\n" - "> > +\t\t\t\tunsigned int usage_id,\n" - "> > +\t\t\t\tstruct temperature_state *st)\n" - "> > +{\n" - "> > +\tint ret;\n" - "> > +\n" - "> > +\tret = sensor_hub_input_get_attribute_info(hsdev,\n" - "> > HID_INPUT_REPORT,\n" - "> > +\t\t\tusage_id,\n" - "> > +\t\t\tHID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPER\n" - "> > ATURE,\n" - "> > +\t\t\t&st->temperature_attr);\n" - "> > +\tif (ret < 0)\n" - "> > +\t\treturn ret;\n" - "> > +\n" - "> > +\ttemperature_adjust_channel_bit_mask(channels, 0,\n" - "> > +\t\t\t\t\tst-\n" - "> > >temperature_attr.size);\n" - "> > +\n" - "> > +\tst->scale_precision = hid_sensor_format_scale(\n" - "> > +\t\t\t\tHID_USAGE_SENSOR_TEMPERATURE,\n" - "> > +\t\t\t\t&st->temperature_attr,\n" - "> > +\t\t\t\t&st->scale_pre_decml, &st-\n" - "> > >scale_post_decml);\n" - "> > +\n" - "> > +\t/* Set Sensitivity field ids, when there is no individual\n" - "> > modifier */\n" - "> > +\tif (st->common_attributes.sensitivity.index < 0)\n" - "> > +\t\tsensor_hub_input_get_attribute_info(hsdev,\n" - "> > +\t\t\tHID_FEATURE_REPORT, usage_id,\n" - "> > +\t\t\tHID_USAGE_SENSOR_DATA_MOD_CHANGE_SENSITIVI\n" - "> > TY_ABS |\n" - "> > +\t\t\tHID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPER\n" - "> > ATURE,\n" - "> > +\t\t\t&st->common_attributes.sensitivity);\n" - "> > +\n" - "> > +\treturn ret;\n" - "> > +}\n" - "> > +\n" - "> > +static struct hid_sensor_hub_callbacks temperature_callbacks = {\n" - "> > +\t.send_event = &temperature_proc_event,\n" - "> > +\t.capture_sample = &temperature_capture_sample,\n" - "> > +};\n" - "> > +\n" - "> > +/* Function to initialize the processing for usage id */\n" - "> > +static int hid_temperature_probe(struct platform_device *pdev)\n" - "> > +{\n" - "> > +\tstatic const char *name = \"temperature\";\n" - "> > +\tstruct iio_dev *indio_dev;\n" - "> > +\tstruct temperature_state *temperature_state;\n" - "> \n" - "> Maybe shorten the variable name to lead to some shorter lines later?\n" - "> temp_st for example would I think convey enough meaning.\n" - "> \n" - "> > +\tstruct hid_sensor_hub_device *hsdev = pdev-\n" - "> > >dev.platform_data;\n" - "> > +\tint ret;\n" - "> > +\n" - "> > +\tindio_dev = devm_iio_device_alloc(&pdev->dev,\n" - "> > +\t\t\t\tsizeof(struct temperature_state));\n" - "> \n" - "> Ever so slight preference for sizeof(*temperature_state)\n" - "> \n" - "> > +\tif (!indio_dev)\n" - "> > +\t\treturn -ENOMEM;\n" - "> > +\n" - "> > +\ttemperature_state = iio_priv(indio_dev);\n" - "> > +\ttemperature_state->common_attributes.hsdev = hsdev;\n" - "> > +\ttemperature_state->common_attributes.pdev = pdev;\n" - "> > +\n" - "> > +\tret = hid_sensor_parse_common_attributes(hsdev,\n" - "> > +\t\t\t\t\tHID_USAGE_SENSOR_TEMPERATU\n" - "> > RE,\n" - "> > +\t\t\t\t\t&temperature_state-\n" - "> > >common_attributes);\n" - "> > +\tif (ret)\n" - "> > +\t\treturn ret;\n" - "> > +\n" - "> > +\tindio_dev->channels = devm_kmemdup(&indio_dev->dev,\n" - "> \n" - "> maybe rename as temp_chans as verbosity not adding much here.\n" - "> > +\t\t\t\t\ttemperature_channels,\n" - "> > +\t\t\t\t\tsizeof(temperature_channel\n" - "> > s),\n" - "> > +\t\t\t\t\tGFP_KERNEL);\n" - "> > +\tif (!indio_dev->channels)\n" - "> > +\t\treturn -ENOMEM;\n" - "> > +\n" - "> > +\tret = temperature_parse_report(pdev, hsdev,\n" - "> > +\t\t\t\t(struct iio_chan_spec *)indio_dev-\n" - "> > >channels,\n" - "> \n" - "> This is casting away a const, which I don't particularly like.\n" - "> I'd prefer that you used a local variable, got everthing setup as you\n" - "> like\n" - "> and then assigned indio_dev->channels to it.\302\240\302\240Semantically slightly\n" - "> nicer as\n" - "> assumption is that they are const if accessed via this element of\n" - "> struct\n" - "> iio_dev (here we obviously know we can change them but it's still not\n" - "> nice!)\n" - "> \n" - "> > +\t\t\t\tHID_USAGE_SENSOR_TEMPERATURE,\n" - "> > +\t\t\t\ttemperature_state);\n" - "> > +\tif (ret)\n" - "> > +\t\treturn ret;\n" - "> > +\n" - "> > +\tindio_dev->num_channels =\n" - "> > ARRAY_SIZE(temperature_channels);\n" - "> > +\tindio_dev->dev.parent = &pdev->dev;\n" - "> > +\tindio_dev->info = &temperature_info;\n" - "> > +\tindio_dev->name = name;\n" - "> > +\tindio_dev->modes = INDIO_DIRECT_MODE;\n" - "> > +\n" - "> > +\tret = devm_iio_triggered_buffer_setup(&pdev->dev,\n" - "> > indio_dev,\n" - "> > +\t\t\t\t\t&iio_pollfunc_store_time,\n" - "> \n" - "> Oddity here as you don't actually use the timestamp...\n" - "> > +\t\t\t\t\tNULL, NULL);\n" - "> > +\tif (ret)\n" - "> > +\t\treturn ret;\n" - "> > +\n" - "> > +\tatomic_set(&temperature_state-\n" - "> > >common_attributes.data_ready, 0);\n" - "> > +\tret = hid_sensor_setup_trigger(indio_dev, name,\n" - "> > +\t\t\t\t&temperature_state-\n" - "> > >common_attributes);\n" - "> > +\tif (ret)\n" - "> > +\t\treturn ret;\n" - "> > +\n" - "> > +\tplatform_set_drvdata(pdev, indio_dev);\n" - "> > +\n" - "> > +\ttemperature_callbacks.pdev = pdev;\n" - "> > +\tret = sensor_hub_register_callback(hsdev,\n" - "> > HID_USAGE_SENSOR_TEMPERATURE,\n" - "> > +\t\t\t\t\t&temperature_callbacks);\n" - "> > +\tif (ret)\n" - "> > +\t\tgoto error_remove_trigger;\n" - "> > +\n" - "> > +\tret = devm_iio_device_register(indio_dev->dev.parent,\n" - "> > indio_dev);\n" - "> > +\tif (ret)\n" - "> > +\t\tgoto error_remove_callback;\n" - "> > +\n" - "> > +\treturn ret;\n" - "> > +\n" - "> > +error_remove_callback:\n" - "> > +\tsensor_hub_remove_callback(hsdev,\n" - "> > HID_USAGE_SENSOR_TEMPERATURE);\n" - "> > +error_remove_trigger:\n" - "> > +\thid_sensor_remove_trigger(&temperature_state-\n" - "> > >common_attributes);\n" - "> > +\treturn ret;\n" - "> > +}\n" - "> > +\n" - "> > +/* Function to deinitialize the processing for usage id */\n" - "> > +static int hid_temperature_remove(struct platform_device *pdev)\n" - "> > +{\n" - "> > +\tstruct hid_sensor_hub_device *hsdev = pdev-\n" - "> > >dev.platform_data;\n" - "> \n" - "> Is it just me that feels that for consistence there should be a\n" - "> platform_get_platform_data() function?\n" - "> A well, can't say it would really add anything, just my sense of\n" - "> consistency kicking in ;)\n" - "> Anyhow, not really anything to do with this driver review so feel\n" - "> free to ignore!\n" - "> \n" - "> > +\tstruct iio_dev *indio_dev = platform_get_drvdata(pdev);\n" - "> > +\tstruct temperature_state *temperature_state =\n" - "> > iio_priv(indio_dev);\n" - "> > +\n" - "> > +\tsensor_hub_remove_callback(hsdev,\n" - "> > HID_USAGE_SENSOR_TEMPERATURE);\n" - "> > +\thid_sensor_remove_trigger(&temperature_state-\n" - "> > >common_attributes);\n" - "> > +\n" - "> > +\treturn 0;\n" - "> > +}\n" - "> > +\n" - "> > +static const struct platform_device_id hid_temperature_ids[] = {\n" - "> > +\t{\n" - "> > +\t\t/* Format: HID-SENSOR-usage_id_in_hex_lowercase */\n" - "> > +\t\t.name = \"HID-SENSOR-200033\",\n" - "> > +\t},\n" - "> > +\t{ /* sentinel */ }\n" - "> > +};\n" - "> > +MODULE_DEVICE_TABLE(platform, hid_temperature_ids);\n" - "> > +\n" - "> > +static struct platform_driver hid_temperature_platform_driver = {\n" - "> > +\t.id_table = hid_temperature_ids,\n" - "> > +\t.driver = {\n" - "> > +\t\t.name\t= KBUILD_MODNAME,\n" - "> > +\t\t.pm\t= &hid_sensor_pm_ops,\n" - "> > +\t},\n" - "> > +\t.probe\t\t= hid_temperature_probe,\n" - "> > +\t.remove\t\t= hid_temperature_remove,\n" - "> > +};\n" - "> > +module_platform_driver(hid_temperature_platform_driver);\n" - "> > +\n" - "> > +MODULE_DESCRIPTION(\"HID Environmental temperature sensor\");\n" - "> > +MODULE_AUTHOR(\"Song Hongyan <hongyan.song@intel.com>\");\n" - "> > +MODULE_LICENSE(\"GPL v2\");\n" - "> > diff --git a/include/linux/hid-sensor-ids.h b/include/linux/hid-\n" - "> > sensor-ids.h\n" - "> > index bab8375..ecec978 100644\n" - "> > --- a/include/linux/hid-sensor-ids.h\n" - "> > +++ b/include/linux/hid-sensor-ids.h\n" - "> > @@ -45,6 +45,10 @@\n" - "> > \302\240#define\n" - "> > HID_USAGE_SENSOR_DATA_ATMOSPHERIC_PRESSURE\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\2400x200430\n" - "> > \302\240#define\n" - "> > HID_USAGE_SENSOR_ATMOSPHERIC_PRESSURE\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\240\302\2400x200431\n" - "> > \302\240\n" - "> > +/* Tempreture (200033) */\n" - "> > +#define\tHID_USAGE_SENSOR_TEMPERATURE\t\t\t\n" - "> > \t0x200033\n" - "> > +#define\tHID_USAGE_SENSOR_DATA_ENVIRONMENTAL_TEMPERATURE\t\n" - "> > \t0x200434\n" - "> > +\n" - "> > \302\240/* Gyro 3D: (200076) */\n" - "> > \302\240#define HID_USAGE_SENSOR_GYRO_3D\t\t\t\t0x\n" - "> > 200076\n" - "> > \302\240#define HID_USAGE_SENSOR_DATA_ANGL_VELOCITY\t\t\t\n" - "> > 0x200456\n" - "> > \n" - "> \n" - > + "T24gU3VuLCAyMDE3LTAyLTE5IGF0IDExOjQ4ICswMDAwLCBKb25hdGhhbiBDYW1lcm9uIHdyb3Rl\n" + "Og0KPiBPbiAxMy8wMi8xNyAwOTo0OSwgU29uZyBIb25neWFuIHdyb3RlOg0KPiA+IEVudmlyb25t\n" + "ZW50YWwgdGVtcGVyYXR1cmUgc2Vuc29yIGlzIGEgaGlkIGRlZmluZWQgc2Vuc29yLA0KPiA+IGl0\n" + "IG1lYXN1cmVzIHRlbXBlcmF0dXJlLg0KPiA+IA0KPiA+IE1vcmUgaW5mb3JtYXRpb24gY2FuIGJl\n" + "IGZvdW5kIGluOg0KPiA+IGh0dHA6Ly93d3cudXNiLm9yZy9kZXZlbG9wZXJzL2hpZHBhZ2UvSFVU\n" + "UlIzOWIucGRmDQo+ID4gDQo+ID4gQWNjb3JkaW5nIHRvIElJTyBBQkkgZGVmaW5pdGlvbiwgSUlP\n" + "X1RFTVAgZGF0YSBvdXRwdXQgdW5pdCBpcw0KPiA+IG1pbGxpIGRlZ3JlZXMgQ2Vsc2l1cy4gQWRk\n" + "IHRoZSB1bml0IGNvbnZlcnQgZnJvbSBkZWdyZWUgdG8gbWlsbGkNCj4gPiBkZWdyZWUuDQo+ID4g\n" + "DQo+ID4gU2lnbmVkLW9mZi1ieTogU29uZyBIb25neWFuIDxob25neWFuLnNvbmdAaW50ZWwuY29t\n" + "Pg0KPiANCj4gSGkgU29uZywNCj4gDQo+IEknbSBhZnJhaWQgSSBoYXZlbid0IHJlYWxseSBiZWVu\n" + "IHRha2luZyBhIGNsb3NlIGxvb2sgYXQgdGhlIHByZXZpb3VzDQo+IHZlcnNpb25zIHNvIGEgZmV3\n" + "IGNvbW1lbnRzIGlubGluZSBmcm9tIG1lIHRoYXQgbWlnaHQgb3RoZXJ3aXNlIGhhdmUNCj4gY29t\n" + "ZSBvbiBlYXJsaWVyIHZlcnNpb25zLg0KPiANCj4gSSB3aWxsIGJlIGxvb2tpbmcgZm9yIGEgcmV2\n" + "aWV3ZWQtYnkgb3IgQWNrIGZyb20gU3Jpbml2YXMgb24gdGhpcw0KPiBiZWZvcmUgdGFraW5nIGl0\n" + "IChtb3N0bHkgdG8gcmVmbGVjdCB0aGUgZWZmb3J0IGhlIGhhcyBwdXQgaW4gb24gdGhvc2UNCj4g\n" + "ZWFybGllciByZXZpZXdzISkNCkhvbmd5YW4sDQoNCllvdSBjYW4gYWRkDQoNCkFja2VkLWJ5OiBT\n" + "cmluaXZhcyBQYW5kcnV2YWRhIDxzcmluaXZhcy5wYW5kcnV2YWRhQGxpbnV4LmludGVsLmNvbT4N\n" + "Cg0KYWZ0ZXIgYWRkcmVzc2luZyBKb25hdGhhbidzIGNvbW1lbnRzLg0KDQpUaGFua3MsDQpTcmlu\n" + "aXZhcw0KDQo+IA0KPiBKb25hdGhhbg0KPiA+IC0tLQ0KPiA+IMKgLi4uL2lpby9jb21tb24vaGlk\n" + "LXNlbnNvcnMvaGlkLXNlbnNvci1hdHRyaWJ1dGVzLmMgfMKgwqDCoDMgKw0KPiA+IMKgZHJpdmVy\n" + "cy9paW8vdGVtcGVyYXR1cmUvS2NvbmZpZ8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg\n" + "wqDCoMKgwqB8wqDCoDE0ICsNCj4gPiDCoGRyaXZlcnMvaWlvL3RlbXBlcmF0dXJlL01ha2VmaWxl\n" + "wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB8wqDCoMKgMSArDQo+ID4gwqBk\n" + "cml2ZXJzL2lpby90ZW1wZXJhdHVyZS9oaWQtc2Vuc29yLXRlbXBlcmF0dXJlLmPCoMKgwqB8IDMy\n" + "Ng0KPiA+ICsrKysrKysrKysrKysrKysrKysrKw0KPiA+IMKgaW5jbHVkZS9saW51eC9oaWQtc2Vu\n" + "c29yLWlkcy5owqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgfMKgwqDC\n" + "oDQgKw0KPiA+IMKgNSBmaWxlcyBjaGFuZ2VkLCAzNDggaW5zZXJ0aW9ucygrKQ0KPiA+IMKgY3Jl\n" + "YXRlIG1vZGUgMTAwNjQ0IGRyaXZlcnMvaWlvL3RlbXBlcmF0dXJlL2hpZC1zZW5zb3ItDQo+ID4g\n" + "dGVtcGVyYXR1cmUuYw0KPiA+IA0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2lpby9jb21tb24v\n" + "aGlkLXNlbnNvcnMvaGlkLXNlbnNvci1hdHRyaWJ1dGVzLmMgDQo+ID4gYi9kcml2ZXJzL2lpby9j\n" + "b21tb24vaGlkLXNlbnNvcnMvaGlkLXNlbnNvci1hdHRyaWJ1dGVzLmMNCj4gPiBpbmRleCA3ZWY5\n" + "NGE5Li42OGMyYmIwIDEwMDY0NA0KPiA+IC0tLSBhL2RyaXZlcnMvaWlvL2NvbW1vbi9oaWQtc2Vu\n" + "c29ycy9oaWQtc2Vuc29yLWF0dHJpYnV0ZXMuYw0KPiA+ICsrKyBiL2RyaXZlcnMvaWlvL2NvbW1v\n" + "bi9oaWQtc2Vuc29ycy9oaWQtc2Vuc29yLWF0dHJpYnV0ZXMuYw0KPiA+IEBAIC01OCw2ICs1OCw5\n" + "IEBADQo+ID4gwqANCj4gPiDCoAl7SElEX1VTQUdFX1NFTlNPUl9QUkVTU1VSRSwgMCwgMTAwLCAw\n" + "fSwNCj4gPiDCoAl7SElEX1VTQUdFX1NFTlNPUl9QUkVTU1VSRSwgSElEX1VTQUdFX1NFTlNPUl9V\n" + "TklUU19QQVNDQUwsDQo+ID4gMCwgMTAwMDAwMH0sDQo+ID4gKw0KPiA+ICsJe0hJRF9VU0FHRV9T\n" + "RU5TT1JfVEVNUEVSQVRVUkUsIDAsIDEwMDAsIDB9LA0KPiA+ICsJe0hJRF9VU0FHRV9TRU5TT1Jf\n" + "VEVNUEVSQVRVUkUsDQo+ID4gSElEX1VTQUdFX1NFTlNPUl9VTklUU19ERUdSRUVTLCAxMDAwLCAw\n" + "fSwNCj4gPiDCoH07DQo+ID4gwqANCj4gPiDCoHN0YXRpYyBpbnQgcG93XzEwKHVuc2lnbmVkIHBv\n" + "d2VyKQ0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2lpby90ZW1wZXJhdHVyZS9LY29uZmlnDQo+\n" + "ID4gYi9kcml2ZXJzL2lpby90ZW1wZXJhdHVyZS9LY29uZmlnDQo+ID4gaW5kZXggNWVhNzdhNy4u\n" + "NWY3YjlmNyAxMDA2NDQNCj4gPiAtLS0gYS9kcml2ZXJzL2lpby90ZW1wZXJhdHVyZS9LY29uZmln\n" + "DQo+ID4gKysrIGIvZHJpdmVycy9paW8vdGVtcGVyYXR1cmUvS2NvbmZpZw0KPiA+IEBAIC0xOSw2\n" + "ICsxOSwyMCBAQCBjb25maWcgTUFYSU1fVEhFUk1PQ09VUExFDQo+ID4gwqAJwqDCoFRoaXMgZHJp\n" + "dmVyIGNhbiBhbHNvIGJlIGJ1aWx0IGFzIGEgbW9kdWxlLiBJZiBzbywgdGhlDQo+ID4gbW9kdWxl\n" + "IHdpbGwNCj4gPiDCoAnCoMKgYmUgY2FsbGVkIG1heGltX3RoZXJtb2NvdXBsZS4NCj4gPiDCoA0K\n" + "PiA+ICtjb25maWcgSElEX1NFTlNPUl9URU1QDQo+ID4gKwl0cmlzdGF0ZSAiSElEIEVudmlyb25t\n" + "ZW50YWwgdGVtcGVyYXR1cmUgc2Vuc29yIg0KPiA+ICsJZGVwZW5kcyBvbiBISURfU0VOU09SX0hV\n" + "Qg0KPiA+ICsJc2VsZWN0IElJT19CVUZGRVINCj4gPiArCXNlbGVjdCBJSU9fVFJJR0dFUkVEX0JV\n" + "RkZFUg0KPiA+ICsJc2VsZWN0IEhJRF9TRU5TT1JfSUlPX0NPTU1PTg0KPiA+ICsJc2VsZWN0IEhJ\n" + "RF9TRU5TT1JfSUlPX1RSSUdHRVINCj4gPiArCWhlbHANCj4gPiArCcKgwqBTYXkgeWVzIGhlcmUg\n" + "dG8gYnVpbGQgc3VwcG9ydCBmb3IgdGhlIEhJRCBTRU5TT1INCj4gPiArCcKgwqB0ZW1wZXJhdHVy\n" + "ZSBkcml2ZXINCj4gPiArDQo+ID4gKwnCoMKgVG8gY29tcGlsZSB0aGlzIGRyaXZlciBhcyBhIG1v\n" + "ZHVsZSwgY2hvb3NlIE0gaGVyZTogdGhlDQo+ID4gbW9kdWxlDQo+ID4gKwnCoMKgd2lsbCBiZSBj\n" + "YWxsZWQgaGlkLXNlbnNvci10ZW1wZXJhdHVyZS4NCj4gPiArDQo+ID4gwqBjb25maWcgTUxYOTA2\n" + "MTQNCj4gPiDCoAl0cmlzdGF0ZSAiTUxYOTA2MTQgY29udGFjdC1sZXNzIGluZnJhcmVkIHNlbnNv\n" + "ciINCj4gPiDCoAlkZXBlbmRzIG9uIEkyQw0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL2lpby90\n" + "ZW1wZXJhdHVyZS9NYWtlZmlsZQ0KPiA+IGIvZHJpdmVycy9paW8vdGVtcGVyYXR1cmUvTWFrZWZp\n" + "bGUNCj4gPiBpbmRleCA3OGMzZGUwLi5lMTU3ZWRhIDEwMDY0NA0KPiA+IC0tLSBhL2RyaXZlcnMv\n" + "aWlvL3RlbXBlcmF0dXJlL01ha2VmaWxlDQo+ID4gKysrIGIvZHJpdmVycy9paW8vdGVtcGVyYXR1\n" + "cmUvTWFrZWZpbGUNCj4gPiBAQCAtNywzICs3LDQgQEAgb2JqLSQoQ09ORklHX01MWDkwNjE0KSAr\n" + "PSBtbHg5MDYxNC5vDQo+ID4gwqBvYmotJChDT05GSUdfVE1QMDA2KSArPSB0bXAwMDYubw0KPiA+\n" + "IMKgb2JqLSQoQ09ORklHX1RTWVMwMSkgKz0gdHN5czAxLm8NCj4gPiDCoG9iai0kKENPTkZJR19U\n" + "U1lTMDJEKSArPSB0c3lzMDJkLm8NCj4gPiArb2JqLSQoQ09ORklHX0hJRF9TRU5TT1JfVEVNUCnC\n" + "oMKgwqArPSBoaWQtc2Vuc29yLXRlbXBlcmF0dXJlLm8NCj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVy\n" + "cy9paW8vdGVtcGVyYXR1cmUvaGlkLXNlbnNvci10ZW1wZXJhdHVyZS5jDQo+ID4gYi9kcml2ZXJz\n" + "L2lpby90ZW1wZXJhdHVyZS9oaWQtc2Vuc29yLXRlbXBlcmF0dXJlLmMNCj4gPiBuZXcgZmlsZSBt\n" + "b2RlIDEwMDY0NA0KPiA+IGluZGV4IDAwMDAwMDAuLjg0YWJkMmQNCj4gPiAtLS0gL2Rldi9udWxs\n" + "DQo+ID4gKysrIGIvZHJpdmVycy9paW8vdGVtcGVyYXR1cmUvaGlkLXNlbnNvci10ZW1wZXJhdHVy\n" + "ZS5jDQo+ID4gQEAgLTAsMCArMSwzMjYgQEANCj4gPiArLyogSElEIFNlbnNvcnMgRHJpdmVyDQo+\n" + "ID4gKyAqIENvcHlyaWdodCAoYykgMjAxNywgSW50ZWwgQ29ycG9yYXRpb24uDQo+ID4gKyAqDQo+\n" + "ID4gKyAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0\n" + "ZSBpdCBhbmQvb3INCj4gPiBtb2RpZnkgaXQNCj4gPiArICogdW5kZXIgdGhlIHRlcm1zIGFuZCBj\n" + "b25kaXRpb25zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMNCj4gPiBMaWNlbnNlLA0KPiA+ICsg\n" + "KiB2ZXJzaW9uIDIsIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9u\n" + "Lg0KPiA+ICsgKg0KPiA+ICsgKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhv\n" + "cGUgaXQgd2lsbCBiZSB1c2VmdWwsIGJ1dA0KPiA+IFdJVEhPVVQNCj4gPiArICogQU5ZIFdBUlJB\n" + "TlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YNCj4gPiBNRVJDSEFOVEFC\n" + "SUxJVFkgb3INCj4gPiArICogRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuwqDCoFNl\n" + "ZSB0aGUgR05VIEdlbmVyYWwgUHVibGljDQo+ID4gTGljZW5zZSBmb3INCj4gPiArICogbW9yZSBk\n" + "ZXRhaWxzLg0KPiA+ICsgKg0KPiA+ICsgKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5\n" + "IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMNCj4gPiBMaWNlbnNlIGFsb25nIHdpdGgNCj4gPiAr\n" + "ICogdGhpcyBwcm9ncmFtLg0KPiA+ICsgKg0KPiA+ICsgKi8NCj4gPiArI2luY2x1ZGUgPGxpbnV4\n" + "L2RldmljZS5oPg0KPiA+ICsjaW5jbHVkZSA8bGludXgvaGlkLXNlbnNvci1odWIuaD4NCj4gPiAr\n" + "I2luY2x1ZGUgPGxpbnV4L2lpby9idWZmZXIuaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L2lpby9p\n" + "aW8uaD4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L2lpby90cmlnZ2VyZWRfYnVmZmVyLmg+DQo+ID4g\n" + "KyNpbmNsdWRlIDxsaW51eC9paW8vdHJpZ2dlcl9jb25zdW1lci5oPg0KPiA+ICsjaW5jbHVkZSA8\n" + "bGludXgvbW9kdWxlLmg+DQo+ID4gKyNpbmNsdWRlIDxsaW51eC9wbGF0Zm9ybV9kZXZpY2UuaD4N\n" + "Cj4gPiArI2luY2x1ZGUgIi4uL2NvbW1vbi9oaWQtc2Vuc29ycy9oaWQtc2Vuc29yLXRyaWdnZXIu\n" + "aCINCj4gPiArDQo+ID4gK3N0cnVjdCB0ZW1wZXJhdHVyZV9zdGF0ZSB7DQo+ID4gKwlzdHJ1Y3Qg\n" + "aGlkX3NlbnNvcl9jb21tb24gY29tbW9uX2F0dHJpYnV0ZXM7DQo+ID4gKwlzdHJ1Y3QgaGlkX3Nl\n" + "bnNvcl9odWJfYXR0cmlidXRlX2luZm8gdGVtcGVyYXR1cmVfYXR0cjsNCj4gPiArCXMzMiB0ZW1w\n" + "ZXJhdHVyZV9kYXRhOw0KPiA+ICsJaW50IHNjYWxlX3ByZV9kZWNtbDsNCj4gPiArCWludCBzY2Fs\n" + "ZV9wb3N0X2RlY21sOw0KPiA+ICsJaW50IHNjYWxlX3ByZWNpc2lvbjsNCj4gPiArCWludCB2YWx1\n" + "ZV9vZmZzZXQ7DQo+ID4gK307DQo+ID4gKw0KPiA+ICsvKiBDaGFubmVsIGRlZmluaXRpb25zICov\n" + "DQo+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgaWlvX2NoYW5fc3BlYyB0ZW1wZXJhdHVyZV9jaGFu\n" + "bmVsc1tdID0gew0KPiA+ICsJew0KPiA+ICsJCS50eXBlID0gSUlPX1RFTVAsDQo+ID4gKwkJLmlu\n" + "Zm9fbWFza19zZXBhcmF0ZSA9IEJJVChJSU9fQ0hBTl9JTkZPX1JBVyksDQo+ID4gKwkJLmluZm9f\n" + "bWFza19zaGFyZWRfYnlfdHlwZSA9DQo+ID4gQklUKElJT19DSEFOX0lORk9fT0ZGU0VUKSB8DQo+\n" + "ID4gKwkJCUJJVChJSU9fQ0hBTl9JTkZPX1NDQUxFKSB8DQo+ID4gKwkJCUJJVChJSU9fQ0hBTl9J\n" + "TkZPX1NBTVBfRlJFUSkgfA0KPiA+ICsJCQlCSVQoSUlPX0NIQU5fSU5GT19IWVNURVJFU0lTKSwN\n" + "Cj4gPiArCQkuc2Nhbl9pbmRleCA9IDAsDQo+ID4gKwl9DQo+ID4gK307DQo+ID4gKw0KPiA+ICsv\n" + "KiBBZGp1c3QgY2hhbm5lbCByZWFsIGJpdHMgYmFzZWQgb24gcmVwb3J0IGRlc2NyaXB0b3IgKi8N\n" + "Cj4gPiArc3RhdGljIHZvaWQgdGVtcGVyYXR1cmVfYWRqdXN0X2NoYW5uZWxfYml0X21hc2soc3Ry\n" + "dWN0DQo+ID4gaWlvX2NoYW5fc3BlYyAqY2hhbm5lbHMsDQo+ID4gKwkJCQkJaW50IGNoYW5uZWws\n" + "IGludCBzaXplKQ0KPiA+ICt7DQo+ID4gKwljaGFubmVsc1tjaGFubmVsXS5zY2FuX3R5cGUuc2ln\n" + "biA9ICdzJzsNCj4gPiArCS8qIFJlYWwgc3RvcmFnZSBiaXRzIHdpbGwgY2hhbmdlIGJhc2VkIG9u\n" + "IHRoZSByZXBvcnQgZGVzYy4NCj4gPiAqLw0KPiA+ICsJY2hhbm5lbHNbY2hhbm5lbF0uc2Nhbl90\n" + "eXBlLnJlYWxiaXRzID0gc2l6ZSAqIDg7DQo+ID4gKwkvKiBNYXhpbXVtIHNpemUgb2YgYSBzYW1w\n" + "bGUgdG8gY2FwdHVyZSBpcyBzMzIgKi8NCj4gPiArCWNoYW5uZWxzW2NoYW5uZWxdLnNjYW5fdHlw\n" + "ZS5zdG9yYWdlYml0cyA9IHNpemVvZihzMzIpICogODsNCj4gPiArfQ0KPiA+ICsNCj4gPiArLyog\n" + "Q2hhbm5lbCByZWFkX3JhdyBoYW5kbGVyICovDQo+ID4gK3N0YXRpYyBpbnQgdGVtcGVyYXR1cmVf\n" + "cmVhZF9yYXcoc3RydWN0IGlpb19kZXYgKmluZGlvX2RldiwNCj4gPiArCQkJCXN0cnVjdCBpaW9f\n" + "Y2hhbl9zcGVjIGNvbnN0ICpjaGFuLA0KPiA+ICsJCQkJaW50ICp2YWwsIGludCAqdmFsMiwgbG9u\n" + "ZyBtYXNrKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgdGVtcGVyYXR1cmVfc3RhdGUgKnRlbXBlcmF0\n" + "dXJlX3N0YXRlID0NCj4gPiBpaW9fcHJpdihpbmRpb19kZXYpOw0KPiA+ICsJaW50IHJldDsNCj4g\n" + "PiArDQo+ID4gKwlzd2l0Y2ggKG1hc2spIHsNCj4gPiArCWNhc2UgSUlPX0NIQU5fSU5GT19SQVc6\n" + "DQo+ID4gKwkJaWYgKGNoYW4tPnR5cGUgPT0gSUlPX1RFTVApIHsNCj4gPiArCQkJaGlkX3NlbnNv\n" + "cl9wb3dlcl9zdGF0ZSgNCj4gPiArCQkJCSZ0ZW1wZXJhdHVyZV9zdGF0ZS0NCj4gPiA+Y29tbW9u\n" + "X2F0dHJpYnV0ZXMsIHRydWUpOw0KPiA+ICsJCQkqdmFsID0NCj4gPiBzZW5zb3JfaHViX2lucHV0\n" + "X2F0dHJfZ2V0X3Jhd192YWx1ZSgNCj4gPiArCQkJCXRlbXBlcmF0dXJlX3N0YXRlLQ0KPiA+ID5j\n" + "b21tb25fYXR0cmlidXRlcy5oc2RldiwNCj4gPiArCQkJCUhJRF9VU0FHRV9TRU5TT1JfVEVNUEVS\n" + "QVRVUkUsDQo+ID4gKwkJCQlISURfVVNBR0VfU0VOU09SX0RBVEFfRU5WSVJPTk1FTlRBDQo+ID4g\n" + "TF9URU1QRVJBVFVSRSwNCj4gPiArCQkJCXRlbXBlcmF0dXJlX3N0YXRlLQ0KPiA+ID50ZW1wZXJh\n" + "dHVyZV9hdHRyLnJlcG9ydF9pZCwNCj4gPiArCQkJCVNFTlNPUl9IVUJfU1lOQyk7DQo+ID4gKwkJ\n" + "CWhpZF9zZW5zb3JfcG93ZXJfc3RhdGUoDQo+ID4gKwkJCQkJJnRlbXBlcmF0dXJlX3N0YXRlLQ0K\n" + "PiA+ID5jb21tb25fYXR0cmlidXRlcywNCj4gPiArCQkJCQlmYWxzZSk7DQo+ID4gKwkJfQ0KPiAN\n" + "Cj4gVGhpcyBpcyBhbiBvZGRpdHkuwqDCoElmIHlvdSBnZXQgaGVyZSB3aXRob3V0IGNoYW4tPnR5\n" + "cGUgPT0gSUlPX1RFTVANCj4gKHdoaWNoIHlvdSBjYW4ndCwgYnV0IHlvdXIgY29kZSBpcyBraW5k\n" + "IG9mIGFzc3VtaW5nIHlvdSBjYW4pDQo+IHRoZW4geW91IGFyZSByZXR1cm5pbmcgdGhhdCB0aGUg\n" + "ZGF0YSBpcyB2YWxpZCB3aXRob3V0IHNldHRpbmcgaXQgdG8NCj4gYW55dGhpbmcuDQo+IA0KPiBJ\n" + "J2QgZmxpcCB0aGUgbG9naWMNCj4gaWYgKGNoYW4tPnR5cGUgIT0gSUlPX1RFTVApIHsNCj4gwqDC\n" + "oMKgcmV0dXJuIC1FSU5WQUw7DQo+IH0NCj4gLi4uIG5vcm1hbCBjb2RlIGZsb3cgLi4uDQo+ID4g\n" + "KwkJcmV0ID0gSUlPX1ZBTF9JTlQ7DQo+IA0KPiBUaGVyZSBpcyBub3RoaW5nIG90aGVyIHRoYW4g\n" + "YSByZXR1cm4gdG8gYmUgZG9uZSBhZnRlciB0aGlzIHNvIGp1c3QNCj4gZG8gaXQgZGlyZWN0bHkg\n" + "aGVyZSBpbnN0ZWFkLsKgwqBCYXNpYyBydWxlIG9mIHRodW1iIGluIGtlcm5lbCBjb2RlIGlzDQo+\n" + "IHJldHVybiBhcyBlYXJseSBhcyBwb3NzaWJsZSB3aGVuIHRoZXJlIGlzIG5vIHVud2luZGluZyB0\n" + "byBiZSBkb25lLg0KPiBTYW1lIGluIGFsbCB0aGUgYnJhbmNoZXMgb2YgdGhpcyBzd2l0Y2ggc3Rh\n" + "dGVtZW50IHBlbGFzZS4NCj4gPiArCQlicmVhazsNCj4gPiArCWNhc2UgSUlPX0NIQU5fSU5GT19T\n" + "Q0FMRToNCj4gPiArCQkqdmFsID0gdGVtcGVyYXR1cmVfc3RhdGUtPnNjYWxlX3ByZV9kZWNtbDsN\n" + "Cj4gPiArCQkqdmFsMiA9IHRlbXBlcmF0dXJlX3N0YXRlLT5zY2FsZV9wb3N0X2RlY21sOw0KPiA+\n" + "ICsJCXJldCA9IHRlbXBlcmF0dXJlX3N0YXRlLT5zY2FsZV9wcmVjaXNpb247DQo+ID4gKwkJYnJl\n" + "YWs7DQo+ID4gKwljYXNlIElJT19DSEFOX0lORk9fT0ZGU0VUOg0KPiA+ICsJCSp2YWwgPSB0ZW1w\n" + "ZXJhdHVyZV9zdGF0ZS0+dmFsdWVfb2Zmc2V0Ow0KPiA+ICsJCXJldCA9IElJT19WQUxfSU5UOw0K\n" + "PiA+ICsJCWJyZWFrOw0KPiA+ICsJY2FzZSBJSU9fQ0hBTl9JTkZPX1NBTVBfRlJFUToNCj4gPiAr\n" + "CQlyZXQgPSBoaWRfc2Vuc29yX3JlYWRfc2FtcF9mcmVxX3ZhbHVlKA0KPiA+ICsJCQkJJnRlbXBl\n" + "cmF0dXJlX3N0YXRlLQ0KPiA+ID5jb21tb25fYXR0cmlidXRlcywNCj4gPiArCQkJCXZhbCwgdmFs\n" + "Mik7DQo+ID4gKwkJYnJlYWs7DQo+ID4gKwljYXNlIElJT19DSEFOX0lORk9fSFlTVEVSRVNJUzoN\n" + "Cj4gPiArCQlyZXQgPSBoaWRfc2Vuc29yX3JlYWRfcmF3X2h5c3RfdmFsdWUoDQo+ID4gKwkJCQkm\n" + "dGVtcGVyYXR1cmVfc3RhdGUtDQo+ID4gPmNvbW1vbl9hdHRyaWJ1dGVzLA0KPiA+ICsJCQkJdmFs\n" + "LCB2YWwyKTsNCj4gPiArCQlicmVhazsNCj4gPiArCWRlZmF1bHQ6DQo+ID4gKwkJcmV0ID0gLUVJ\n" + "TlZBTDsNCj4gPiArCX0NCj4gPiArDQo+ID4gKwlyZXR1cm4gcmV0Ow0KPiA+ICt9DQo+ID4gKw0K\n" + "PiA+ICsvKiBDaGFubmVsIHdyaXRlX3JhdyBoYW5kbGVyICovDQo+IA0KPiBQZXJoYXBzIGRyb3Ag\n" + "dGhlIG1vcmUgb2J2aW91cyBjb21tZW50cyBhcyBub3QgbmVjZXNzYXJpbHkgcHJvdmlkaW5nDQo+\n" + "IGFueSBhZGRpdGlvbmFsIGluZm8uwqDCoEkgZG9uJ3QgcmVhbGx5IG1pbmQgaWYgeW91IGZlZWwg\n" + "dGhleSBhcmUgdXNlZnVsDQo+IGhvd2V2ZXIgYW5kIHdhbnQgdG8ga2VlcCB0aGVtLg0KPiA+ICtz\n" + "dGF0aWMgaW50IHRlbXBlcmF0dXJlX3dyaXRlX3JhdyhzdHJ1Y3QgaWlvX2RldiAqaW5kaW9fZGV2\n" + "LA0KPiA+ICsJCQkJc3RydWN0IGlpb19jaGFuX3NwZWMgY29uc3QgKmNoYW4sDQo+ID4gKwkJCQlp\n" + "bnQgdmFsLCBpbnQgdmFsMiwgbG9uZyBtYXNrKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgdGVtcGVy\n" + "YXR1cmVfc3RhdGUgKnRlbXBlcmF0dXJlX3N0YXRlID0NCj4gPiBpaW9fcHJpdihpbmRpb19kZXYp\n" + "Ow0KPiA+ICsJaW50IHJldDsNCj4gPiArDQo+ID4gKwlzd2l0Y2ggKG1hc2spIHsNCj4gPiArCWNh\n" + "c2UgSUlPX0NIQU5fSU5GT19TQU1QX0ZSRVE6DQo+ID4gKwkJcmV0ID0gaGlkX3NlbnNvcl93cml0\n" + "ZV9zYW1wX2ZyZXFfdmFsdWUoDQo+ID4gKwkJCQkmdGVtcGVyYXR1cmVfc3RhdGUtDQo+ID4gPmNv\n" + "bW1vbl9hdHRyaWJ1dGVzLCB2YWwsDQo+ID4gKwkJCQl2YWwyKTsNCj4gDQo+IEFzIHdpdGggdGhl\n" + "IHJlYWRfcmF3IGFib3ZlLCByZXR1cm4gZGlyZWN0bHkgd2l0aGluIHRoZXNlIHN0YXRlbWVudHMN\n" + "Cj4gcmF0aGVyIHRoYW4NCj4gaGF2aW5nIHRvIGJvdGhlciB3aXRoIGJyZWFraW5nIG91dCBvZiB0\n" + "aGUgc3dpdGNoIGFuZCB0aGVuIGRvaW5nIGl0Lg0KPiBUaWRpZXIgY29kZSB0aGF0IHdheS4NCj4g\n" + "DQo+IHJldHVybiBoaWRfc2Vuc29yLi4uLg0KPiA+ICsJCWJyZWFrOw0KPiA+ICsJY2FzZSBJSU9f\n" + "Q0hBTl9JTkZPX0hZU1RFUkVTSVM6DQo+ID4gKwkJcmV0ID0gaGlkX3NlbnNvcl93cml0ZV9yYXdf\n" + "aHlzdF92YWx1ZSgNCj4gPiArCQkJCSZ0ZW1wZXJhdHVyZV9zdGF0ZS0NCj4gPiA+Y29tbW9uX2F0\n" + "dHJpYnV0ZXMsIHZhbCwNCj4gPiArCQkJCXZhbDIpOw0KPiA+ICsJCWJyZWFrOw0KPiA+ICsJZGVm\n" + "YXVsdDoNCj4gPiArCQlyZXQgPSAtRUlOVkFMOw0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCXJldHVy\n" + "biByZXQ7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyBjb25zdCBzdHJ1Y3QgaWlvX2luZm8g\n" + "dGVtcGVyYXR1cmVfaW5mbyA9IHsNCj4gPiArCS5kcml2ZXJfbW9kdWxlID0gVEhJU19NT0RVTEUs\n" + "DQo+ID4gKwkucmVhZF9yYXcgPSAmdGVtcGVyYXR1cmVfcmVhZF9yYXcsDQo+ID4gKwkud3JpdGVf\n" + "cmF3ID0gJnRlbXBlcmF0dXJlX3dyaXRlX3JhdywNCj4gPiArfTsNCj4gPiArDQo+ID4gKy8qIENh\n" + "bGxiYWNrIGhhbmRsZXIgdG8gc2VuZCBldmVudCBhZnRlciBhbGwgc2FtcGxlcyBhcmUgcmVjZWl2\n" + "ZWQNCj4gPiBhbmQgY2FwdHVyZWQgKi8NCj4gPiArc3RhdGljIGludCB0ZW1wZXJhdHVyZV9wcm9j\n" + "X2V2ZW50KHN0cnVjdCBoaWRfc2Vuc29yX2h1Yl9kZXZpY2UNCj4gPiAqaHNkZXYsDQo+ID4gKwkJ\n" + "CQl1bnNpZ25lZCBpbnQgdXNhZ2VfaWQsIHZvaWQgKnBkZXYpDQo+ID4gK3sNCj4gPiArCXN0cnVj\n" + "dCBpaW9fZGV2ICppbmRpb19kZXYgPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsNCj4gPiAr\n" + "CXN0cnVjdCB0ZW1wZXJhdHVyZV9zdGF0ZSAqdGVtcGVyYXR1cmVfc3RhdGUgPQ0KPiA+IGlpb19w\n" + "cml2KGluZGlvX2Rldik7DQo+ID4gKw0KPiA+ICsJaWYgKGF0b21pY19yZWFkKCZ0ZW1wZXJhdHVy\n" + "ZV9zdGF0ZS0NCj4gPiA+Y29tbW9uX2F0dHJpYnV0ZXMuZGF0YV9yZWFkeSkpDQo+ID4gKwkJaWlv\n" + "X3B1c2hfdG9fYnVmZmVycyhpbmRpb19kZXYsDQo+ID4gKwkJCQkJJnRlbXBlcmF0dXJlX3N0YXRl\n" + "LQ0KPiA+ID50ZW1wZXJhdHVyZV9kYXRhKTsNCj4gPiArCXJldHVybiAwOw0KPiA+ICt9DQo+ID4g\n" + "Kw0KPiA+ICsvKiBDYXB0dXJlIHNhbXBsZXMgaW4gbG9jYWwgc3RvcmFnZSAqLw0KPiA+ICtzdGF0\n" + "aWMgaW50IHRlbXBlcmF0dXJlX2NhcHR1cmVfc2FtcGxlKHN0cnVjdCBoaWRfc2Vuc29yX2h1Yl9k\n" + "ZXZpY2UNCj4gPiAqaHNkZXYsDQo+ID4gKwkJCQl1bnNpZ25lZCBpbnQgdXNhZ2VfaWQsIHNpemVf\n" + "dA0KPiA+IHJhd19sZW4sDQo+ID4gKwkJCQljaGFyICpyYXdfZGF0YSwgdm9pZCAqcGRldikNCj4g\n" + "PiArew0KPiA+ICsJc3RydWN0IGlpb19kZXYgKmluZGlvX2RldiA9IHBsYXRmb3JtX2dldF9kcnZk\n" + "YXRhKHBkZXYpOw0KPiA+ICsJc3RydWN0IHRlbXBlcmF0dXJlX3N0YXRlICp0ZW1wZXJhdHVyZV9z\n" + "dGF0ZSA9DQo+ID4gaWlvX3ByaXYoaW5kaW9fZGV2KTsNCj4gPiArDQo+ID4gKwlzd2l0Y2ggKHVz\n" + "YWdlX2lkKSB7DQo+ID4gKwljYXNlIEhJRF9VU0FHRV9TRU5TT1JfREFUQV9FTlZJUk9OTUVOVEFM\n" + "X1RFTVBFUkFUVVJFOg0KPiA+ICsJCXRlbXBlcmF0dXJlX3N0YXRlLT50ZW1wZXJhdHVyZV9kYXRh\n" + "ID0gKihzMzINCj4gPiAqKXJhd19kYXRhOw0KPiA+ICsJCXJldHVybiAwOw0KPiA+ICsJZGVmYXVs\n" + "dDoNCj4gPiArCQlyZXR1cm4gLUVJTlZBTDsNCj4gPiArCX0NCj4gPiArfQ0KPiA+ICsNCj4gPiAr\n" + "LyogUGFyc2UgcmVwb3J0IHdoaWNoIGlzIHNwZWNpZmljIHRvIGFuIHVzYWdlIGlkKi8NCj4gPiAr\n" + "c3RhdGljIGludCB0ZW1wZXJhdHVyZV9wYXJzZV9yZXBvcnQoc3RydWN0IHBsYXRmb3JtX2Rldmlj\n" + "ZSAqcGRldiwNCj4gPiArCQkJCXN0cnVjdCBoaWRfc2Vuc29yX2h1Yl9kZXZpY2UNCj4gPiAqaHNk\n" + "ZXYsDQo+ID4gKwkJCQlzdHJ1Y3QgaWlvX2NoYW5fc3BlYyAqY2hhbm5lbHMsDQo+ID4gKwkJCQl1\n" + "bnNpZ25lZCBpbnQgdXNhZ2VfaWQsDQo+ID4gKwkJCQlzdHJ1Y3QgdGVtcGVyYXR1cmVfc3RhdGUg\n" + "KnN0KQ0KPiA+ICt7DQo+ID4gKwlpbnQgcmV0Ow0KPiA+ICsNCj4gPiArCXJldCA9IHNlbnNvcl9o\n" + "dWJfaW5wdXRfZ2V0X2F0dHJpYnV0ZV9pbmZvKGhzZGV2LA0KPiA+IEhJRF9JTlBVVF9SRVBPUlQs\n" + "DQo+ID4gKwkJCXVzYWdlX2lkLA0KPiA+ICsJCQlISURfVVNBR0VfU0VOU09SX0RBVEFfRU5WSVJP\n" + "Tk1FTlRBTF9URU1QRVINCj4gPiBBVFVSRSwNCj4gPiArCQkJJnN0LT50ZW1wZXJhdHVyZV9hdHRy\n" + "KTsNCj4gPiArCWlmIChyZXQgPCAwKQ0KPiA+ICsJCXJldHVybiByZXQ7DQo+ID4gKw0KPiA+ICsJ\n" + "dGVtcGVyYXR1cmVfYWRqdXN0X2NoYW5uZWxfYml0X21hc2soY2hhbm5lbHMsIDAsDQo+ID4gKwkJ\n" + "CQkJc3QtDQo+ID4gPnRlbXBlcmF0dXJlX2F0dHIuc2l6ZSk7DQo+ID4gKw0KPiA+ICsJc3QtPnNj\n" + "YWxlX3ByZWNpc2lvbiA9IGhpZF9zZW5zb3JfZm9ybWF0X3NjYWxlKA0KPiA+ICsJCQkJSElEX1VT\n" + "QUdFX1NFTlNPUl9URU1QRVJBVFVSRSwNCj4gPiArCQkJCSZzdC0+dGVtcGVyYXR1cmVfYXR0ciwN\n" + "Cj4gPiArCQkJCSZzdC0+c2NhbGVfcHJlX2RlY21sLCAmc3QtDQo+ID4gPnNjYWxlX3Bvc3RfZGVj\n" + "bWwpOw0KPiA+ICsNCj4gPiArCS8qIFNldCBTZW5zaXRpdml0eSBmaWVsZCBpZHMsIHdoZW4gdGhl\n" + "cmUgaXMgbm8gaW5kaXZpZHVhbA0KPiA+IG1vZGlmaWVyICovDQo+ID4gKwlpZiAoc3QtPmNvbW1v\n" + "bl9hdHRyaWJ1dGVzLnNlbnNpdGl2aXR5LmluZGV4IDwgMCkNCj4gPiArCQlzZW5zb3JfaHViX2lu\n" + "cHV0X2dldF9hdHRyaWJ1dGVfaW5mbyhoc2RldiwNCj4gPiArCQkJSElEX0ZFQVRVUkVfUkVQT1JU\n" + "LCB1c2FnZV9pZCwNCj4gPiArCQkJSElEX1VTQUdFX1NFTlNPUl9EQVRBX01PRF9DSEFOR0VfU0VO\n" + "U0lUSVZJDQo+ID4gVFlfQUJTIHwNCj4gPiArCQkJSElEX1VTQUdFX1NFTlNPUl9EQVRBX0VOVklS\n" + "T05NRU5UQUxfVEVNUEVSDQo+ID4gQVRVUkUsDQo+ID4gKwkJCSZzdC0+Y29tbW9uX2F0dHJpYnV0\n" + "ZXMuc2Vuc2l0aXZpdHkpOw0KPiA+ICsNCj4gPiArCXJldHVybiByZXQ7DQo+ID4gK30NCj4gPiAr\n" + "DQo+ID4gK3N0YXRpYyBzdHJ1Y3QgaGlkX3NlbnNvcl9odWJfY2FsbGJhY2tzIHRlbXBlcmF0dXJl\n" + "X2NhbGxiYWNrcyA9IHsNCj4gPiArCS5zZW5kX2V2ZW50ID0gJnRlbXBlcmF0dXJlX3Byb2NfZXZl\n" + "bnQsDQo+ID4gKwkuY2FwdHVyZV9zYW1wbGUgPSAmdGVtcGVyYXR1cmVfY2FwdHVyZV9zYW1wbGUs\n" + "DQo+ID4gK307DQo+ID4gKw0KPiA+ICsvKiBGdW5jdGlvbiB0byBpbml0aWFsaXplIHRoZSBwcm9j\n" + "ZXNzaW5nIGZvciB1c2FnZSBpZCAqLw0KPiA+ICtzdGF0aWMgaW50IGhpZF90ZW1wZXJhdHVyZV9w\n" + "cm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQ0KPiA+ICt7DQo+ID4gKwlzdGF0aWMg\n" + "Y29uc3QgY2hhciAqbmFtZSA9ICJ0ZW1wZXJhdHVyZSI7DQo+ID4gKwlzdHJ1Y3QgaWlvX2RldiAq\n" + "aW5kaW9fZGV2Ow0KPiA+ICsJc3RydWN0IHRlbXBlcmF0dXJlX3N0YXRlICp0ZW1wZXJhdHVyZV9z\n" + "dGF0ZTsNCj4gDQo+IE1heWJlIHNob3J0ZW4gdGhlIHZhcmlhYmxlIG5hbWUgdG8gbGVhZCB0byBz\n" + "b21lIHNob3J0ZXIgbGluZXMgbGF0ZXI/DQo+IHRlbXBfc3QgZm9yIGV4YW1wbGUgd291bGQgSSB0\n" + "aGluayBjb252ZXkgZW5vdWdoIG1lYW5pbmcuDQo+IA0KPiA+ICsJc3RydWN0IGhpZF9zZW5zb3Jf\n" + "aHViX2RldmljZSAqaHNkZXYgPSBwZGV2LQ0KPiA+ID5kZXYucGxhdGZvcm1fZGF0YTsNCj4gPiAr\n" + "CWludCByZXQ7DQo+ID4gKw0KPiA+ICsJaW5kaW9fZGV2ID0gZGV2bV9paW9fZGV2aWNlX2FsbG9j\n" + "KCZwZGV2LT5kZXYsDQo+ID4gKwkJCQlzaXplb2Yoc3RydWN0IHRlbXBlcmF0dXJlX3N0YXRlKSk7\n" + "DQo+IA0KPiBFdmVyIHNvIHNsaWdodCBwcmVmZXJlbmNlIGZvciBzaXplb2YoKnRlbXBlcmF0dXJl\n" + "X3N0YXRlKQ0KPiANCj4gPiArCWlmICghaW5kaW9fZGV2KQ0KPiA+ICsJCXJldHVybiAtRU5PTUVN\n" + "Ow0KPiA+ICsNCj4gPiArCXRlbXBlcmF0dXJlX3N0YXRlID0gaWlvX3ByaXYoaW5kaW9fZGV2KTsN\n" + "Cj4gPiArCXRlbXBlcmF0dXJlX3N0YXRlLT5jb21tb25fYXR0cmlidXRlcy5oc2RldiA9IGhzZGV2\n" + "Ow0KPiA+ICsJdGVtcGVyYXR1cmVfc3RhdGUtPmNvbW1vbl9hdHRyaWJ1dGVzLnBkZXYgPSBwZGV2\n" + "Ow0KPiA+ICsNCj4gPiArCXJldCA9IGhpZF9zZW5zb3JfcGFyc2VfY29tbW9uX2F0dHJpYnV0ZXMo\n" + "aHNkZXYsDQo+ID4gKwkJCQkJSElEX1VTQUdFX1NFTlNPUl9URU1QRVJBVFUNCj4gPiBSRSwNCj4g\n" + "PiArCQkJCQkmdGVtcGVyYXR1cmVfc3RhdGUtDQo+ID4gPmNvbW1vbl9hdHRyaWJ1dGVzKTsNCj4g\n" + "PiArCWlmIChyZXQpDQo+ID4gKwkJcmV0dXJuIHJldDsNCj4gPiArDQo+ID4gKwlpbmRpb19kZXYt\n" + "PmNoYW5uZWxzID0gZGV2bV9rbWVtZHVwKCZpbmRpb19kZXYtPmRldiwNCj4gDQo+IG1heWJlIHJl\n" + "bmFtZSBhcyB0ZW1wX2NoYW5zIGFzIHZlcmJvc2l0eSBub3QgYWRkaW5nIG11Y2ggaGVyZS4NCj4g\n" + "PiArCQkJCQl0ZW1wZXJhdHVyZV9jaGFubmVscywNCj4gPiArCQkJCQlzaXplb2YodGVtcGVyYXR1\n" + "cmVfY2hhbm5lbA0KPiA+IHMpLA0KPiA+ICsJCQkJCUdGUF9LRVJORUwpOw0KPiA+ICsJaWYgKCFp\n" + "bmRpb19kZXYtPmNoYW5uZWxzKQ0KPiA+ICsJCXJldHVybiAtRU5PTUVNOw0KPiA+ICsNCj4gPiAr\n" + "CXJldCA9IHRlbXBlcmF0dXJlX3BhcnNlX3JlcG9ydChwZGV2LCBoc2RldiwNCj4gPiArCQkJCShz\n" + "dHJ1Y3QgaWlvX2NoYW5fc3BlYyAqKWluZGlvX2Rldi0NCj4gPiA+Y2hhbm5lbHMsDQo+IA0KPiBU\n" + "aGlzIGlzIGNhc3RpbmcgYXdheSBhIGNvbnN0LCB3aGljaCBJIGRvbid0IHBhcnRpY3VsYXJseSBs\n" + "aWtlLg0KPiBJJ2QgcHJlZmVyIHRoYXQgeW91IHVzZWQgYSBsb2NhbCB2YXJpYWJsZSwgZ290IGV2\n" + "ZXJ0aGluZyBzZXR1cCBhcyB5b3UNCj4gbGlrZQ0KPiBhbmQgdGhlbiBhc3NpZ25lZCBpbmRpb19k\n" + "ZXYtPmNoYW5uZWxzIHRvIGl0LsKgwqBTZW1hbnRpY2FsbHkgc2xpZ2h0bHkNCj4gbmljZXIgYXMN\n" + "Cj4gYXNzdW1wdGlvbiBpcyB0aGF0IHRoZXkgYXJlIGNvbnN0IGlmIGFjY2Vzc2VkIHZpYSB0aGlz\n" + "IGVsZW1lbnQgb2YNCj4gc3RydWN0DQo+IGlpb19kZXYgKGhlcmUgd2Ugb2J2aW91c2x5IGtub3cg\n" + "d2UgY2FuIGNoYW5nZSB0aGVtIGJ1dCBpdCdzIHN0aWxsIG5vdA0KPiBuaWNlISkNCj4gDQo+ID4g\n" + "KwkJCQlISURfVVNBR0VfU0VOU09SX1RFTVBFUkFUVVJFLA0KPiA+ICsJCQkJdGVtcGVyYXR1cmVf\n" + "c3RhdGUpOw0KPiA+ICsJaWYgKHJldCkNCj4gPiArCQlyZXR1cm4gcmV0Ow0KPiA+ICsNCj4gPiAr\n" + "CWluZGlvX2Rldi0+bnVtX2NoYW5uZWxzID0NCj4gPiBBUlJBWV9TSVpFKHRlbXBlcmF0dXJlX2No\n" + "YW5uZWxzKTsNCj4gPiArCWluZGlvX2Rldi0+ZGV2LnBhcmVudCA9ICZwZGV2LT5kZXY7DQo+ID4g\n" + "KwlpbmRpb19kZXYtPmluZm8gPSAmdGVtcGVyYXR1cmVfaW5mbzsNCj4gPiArCWluZGlvX2Rldi0+\n" + "bmFtZSA9IG5hbWU7DQo+ID4gKwlpbmRpb19kZXYtPm1vZGVzID0gSU5ESU9fRElSRUNUX01PREU7\n" + "DQo+ID4gKw0KPiA+ICsJcmV0ID0gZGV2bV9paW9fdHJpZ2dlcmVkX2J1ZmZlcl9zZXR1cCgmcGRl\n" + "di0+ZGV2LA0KPiA+IGluZGlvX2RldiwNCj4gPiArCQkJCQkmaWlvX3BvbGxmdW5jX3N0b3JlX3Rp\n" + "bWUsDQo+IA0KPiBPZGRpdHkgaGVyZSBhcyB5b3UgZG9uJ3QgYWN0dWFsbHkgdXNlIHRoZSB0aW1l\n" + "c3RhbXAuLi4NCj4gPiArCQkJCQlOVUxMLCBOVUxMKTsNCj4gPiArCWlmIChyZXQpDQo+ID4gKwkJ\n" + "cmV0dXJuIHJldDsNCj4gPiArDQo+ID4gKwlhdG9taWNfc2V0KCZ0ZW1wZXJhdHVyZV9zdGF0ZS0N\n" + "Cj4gPiA+Y29tbW9uX2F0dHJpYnV0ZXMuZGF0YV9yZWFkeSwgMCk7DQo+ID4gKwlyZXQgPSBoaWRf\n" + "c2Vuc29yX3NldHVwX3RyaWdnZXIoaW5kaW9fZGV2LCBuYW1lLA0KPiA+ICsJCQkJJnRlbXBlcmF0\n" + "dXJlX3N0YXRlLQ0KPiA+ID5jb21tb25fYXR0cmlidXRlcyk7DQo+ID4gKwlpZiAocmV0KQ0KPiA+\n" + "ICsJCXJldHVybiByZXQ7DQo+ID4gKw0KPiA+ICsJcGxhdGZvcm1fc2V0X2RydmRhdGEocGRldiwg\n" + "aW5kaW9fZGV2KTsNCj4gPiArDQo+ID4gKwl0ZW1wZXJhdHVyZV9jYWxsYmFja3MucGRldiA9IHBk\n" + "ZXY7DQo+ID4gKwlyZXQgPSBzZW5zb3JfaHViX3JlZ2lzdGVyX2NhbGxiYWNrKGhzZGV2LA0KPiA+\n" + "IEhJRF9VU0FHRV9TRU5TT1JfVEVNUEVSQVRVUkUsDQo+ID4gKwkJCQkJJnRlbXBlcmF0dXJlX2Nh\n" + "bGxiYWNrcyk7DQo+ID4gKwlpZiAocmV0KQ0KPiA+ICsJCWdvdG8gZXJyb3JfcmVtb3ZlX3RyaWdn\n" + "ZXI7DQo+ID4gKw0KPiA+ICsJcmV0ID0gZGV2bV9paW9fZGV2aWNlX3JlZ2lzdGVyKGluZGlvX2Rl\n" + "di0+ZGV2LnBhcmVudCwNCj4gPiBpbmRpb19kZXYpOw0KPiA+ICsJaWYgKHJldCkNCj4gPiArCQln\n" + "b3RvIGVycm9yX3JlbW92ZV9jYWxsYmFjazsNCj4gPiArDQo+ID4gKwlyZXR1cm4gcmV0Ow0KPiA+\n" + "ICsNCj4gPiArZXJyb3JfcmVtb3ZlX2NhbGxiYWNrOg0KPiA+ICsJc2Vuc29yX2h1Yl9yZW1vdmVf\n" + "Y2FsbGJhY2soaHNkZXYsDQo+ID4gSElEX1VTQUdFX1NFTlNPUl9URU1QRVJBVFVSRSk7DQo+ID4g\n" + "K2Vycm9yX3JlbW92ZV90cmlnZ2VyOg0KPiA+ICsJaGlkX3NlbnNvcl9yZW1vdmVfdHJpZ2dlcigm\n" + "dGVtcGVyYXR1cmVfc3RhdGUtDQo+ID4gPmNvbW1vbl9hdHRyaWJ1dGVzKTsNCj4gPiArCXJldHVy\n" + "biByZXQ7DQo+ID4gK30NCj4gPiArDQo+ID4gKy8qIEZ1bmN0aW9uIHRvIGRlaW5pdGlhbGl6ZSB0\n" + "aGUgcHJvY2Vzc2luZyBmb3IgdXNhZ2UgaWQgKi8NCj4gPiArc3RhdGljIGludCBoaWRfdGVtcGVy\n" + "YXR1cmVfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpDQo+ID4gK3sNCj4gPiAr\n" + "CXN0cnVjdCBoaWRfc2Vuc29yX2h1Yl9kZXZpY2UgKmhzZGV2ID0gcGRldi0NCj4gPiA+ZGV2LnBs\n" + "YXRmb3JtX2RhdGE7DQo+IA0KPiBJcyBpdCBqdXN0IG1lIHRoYXQgZmVlbHMgdGhhdCBmb3IgY29u\n" + "c2lzdGVuY2UgdGhlcmUgc2hvdWxkIGJlIGENCj4gcGxhdGZvcm1fZ2V0X3BsYXRmb3JtX2RhdGEo\n" + "KSBmdW5jdGlvbj8NCj4gQSB3ZWxsLCBjYW4ndCBzYXkgaXQgd291bGQgcmVhbGx5IGFkZCBhbnl0\n" + "aGluZywganVzdCBteSBzZW5zZSBvZg0KPiBjb25zaXN0ZW5jeSBraWNraW5nIGluIDspDQo+IEFu\n" + "eWhvdywgbm90IHJlYWxseSBhbnl0aGluZyB0byBkbyB3aXRoIHRoaXMgZHJpdmVyIHJldmlldyBz\n" + "byBmZWVsDQo+IGZyZWUgdG8gaWdub3JlIQ0KPiANCj4gPiArCXN0cnVjdCBpaW9fZGV2ICppbmRp\n" + "b19kZXYgPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsNCj4gPiArCXN0cnVjdCB0ZW1wZXJh\n" + "dHVyZV9zdGF0ZSAqdGVtcGVyYXR1cmVfc3RhdGUgPQ0KPiA+IGlpb19wcml2KGluZGlvX2Rldik7\n" + "DQo+ID4gKw0KPiA+ICsJc2Vuc29yX2h1Yl9yZW1vdmVfY2FsbGJhY2soaHNkZXYsDQo+ID4gSElE\n" + "X1VTQUdFX1NFTlNPUl9URU1QRVJBVFVSRSk7DQo+ID4gKwloaWRfc2Vuc29yX3JlbW92ZV90cmln\n" + "Z2VyKCZ0ZW1wZXJhdHVyZV9zdGF0ZS0NCj4gPiA+Y29tbW9uX2F0dHJpYnV0ZXMpOw0KPiA+ICsN\n" + "Cj4gPiArCXJldHVybiAwOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgY29uc3Qgc3RydWN0\n" + "IHBsYXRmb3JtX2RldmljZV9pZCBoaWRfdGVtcGVyYXR1cmVfaWRzW10gPSB7DQo+ID4gKwl7DQo+\n" + "ID4gKwkJLyogRm9ybWF0OiBISUQtU0VOU09SLXVzYWdlX2lkX2luX2hleF9sb3dlcmNhc2UgKi8N\n" + "Cj4gPiArCQkubmFtZSA9ICJISUQtU0VOU09SLTIwMDAzMyIsDQo+ID4gKwl9LA0KPiA+ICsJeyAv\n" + "KiBzZW50aW5lbCAqLyB9DQo+ID4gK307DQo+ID4gK01PRFVMRV9ERVZJQ0VfVEFCTEUocGxhdGZv\n" + "cm0sIGhpZF90ZW1wZXJhdHVyZV9pZHMpOw0KPiA+ICsNCj4gPiArc3RhdGljIHN0cnVjdCBwbGF0\n" + "Zm9ybV9kcml2ZXIgaGlkX3RlbXBlcmF0dXJlX3BsYXRmb3JtX2RyaXZlciA9IHsNCj4gPiArCS5p\n" + "ZF90YWJsZSA9IGhpZF90ZW1wZXJhdHVyZV9pZHMsDQo+ID4gKwkuZHJpdmVyID0gew0KPiA+ICsJ\n" + "CS5uYW1lCT0gS0JVSUxEX01PRE5BTUUsDQo+ID4gKwkJLnBtCT0gJmhpZF9zZW5zb3JfcG1fb3Bz\n" + "LA0KPiA+ICsJfSwNCj4gPiArCS5wcm9iZQkJPSBoaWRfdGVtcGVyYXR1cmVfcHJvYmUsDQo+ID4g\n" + "KwkucmVtb3ZlCQk9IGhpZF90ZW1wZXJhdHVyZV9yZW1vdmUsDQo+ID4gK307DQo+ID4gK21vZHVs\n" + "ZV9wbGF0Zm9ybV9kcml2ZXIoaGlkX3RlbXBlcmF0dXJlX3BsYXRmb3JtX2RyaXZlcik7DQo+ID4g\n" + "Kw0KPiA+ICtNT0RVTEVfREVTQ1JJUFRJT04oIkhJRCBFbnZpcm9ubWVudGFsIHRlbXBlcmF0dXJl\n" + "IHNlbnNvciIpOw0KPiA+ICtNT0RVTEVfQVVUSE9SKCJTb25nIEhvbmd5YW4gPGhvbmd5YW4uc29u\n" + "Z0BpbnRlbC5jb20+Iik7DQo+ID4gK01PRFVMRV9MSUNFTlNFKCJHUEwgdjIiKTsNCj4gPiBkaWZm\n" + "IC0tZ2l0IGEvaW5jbHVkZS9saW51eC9oaWQtc2Vuc29yLWlkcy5oIGIvaW5jbHVkZS9saW51eC9o\n" + "aWQtDQo+ID4gc2Vuc29yLWlkcy5oDQo+ID4gaW5kZXggYmFiODM3NS4uZWNlYzk3OCAxMDA2NDQN\n" + "Cj4gPiAtLS0gYS9pbmNsdWRlL2xpbnV4L2hpZC1zZW5zb3ItaWRzLmgNCj4gPiArKysgYi9pbmNs\n" + "dWRlL2xpbnV4L2hpZC1zZW5zb3ItaWRzLmgNCj4gPiBAQCAtNDUsNiArNDUsMTAgQEANCj4gPiDC\n" + "oCNkZWZpbmUNCj4gPiBISURfVVNBR0VfU0VOU09SX0RBVEFfQVRNT1NQSEVSSUNfUFJFU1NVUkXC\n" + "oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgMHgyMDA0MzANCj4gPiDCoCNkZWZpbmUNCj4gPiBI\n" + "SURfVVNBR0VfU0VOU09SX0FUTU9TUEhFUklDX1BSRVNTVVJFwqDCoMKgwqDCoMKgwqDCoMKgwqDC\n" + "oMKgwqDCoMKgwqDCoMKgwqAweDIwMDQzMQ0KPiA+IMKgDQo+ID4gKy8qIFRlbXByZXR1cmUgKDIw\n" + "MDAzMykgKi8NCj4gPiArI2RlZmluZQlISURfVVNBR0VfU0VOU09SX1RFTVBFUkFUVVJFCQkJDQo+\n" + "ID4gCTB4MjAwMDMzDQo+ID4gKyNkZWZpbmUJSElEX1VTQUdFX1NFTlNPUl9EQVRBX0VOVklST05N\n" + "RU5UQUxfVEVNUEVSQVRVUkUJDQo+ID4gCTB4MjAwNDM0DQo+ID4gKw0KPiA+IMKgLyogR3lybyAz\n" + "RDogKDIwMDA3NikgKi8NCj4gPiDCoCNkZWZpbmUgSElEX1VTQUdFX1NFTlNPUl9HWVJPXzNECQkJ\n" + "CTB4DQo+ID4gMjAwMDc2DQo+ID4gwqAjZGVmaW5lIEhJRF9VU0FHRV9TRU5TT1JfREFUQV9BTkdM\n" + X1ZFTE9DSVRZCQkJDQo+ID4gMHgyMDA0NTYNCj4gPiANCj4gDQo+IA== -bd6bd97e99467694d69f51485669a13db8b124ceb84ed0a2260d5e08b51cb705 +b400859db824ea79bcad9fc43b74b13364aaa25ec60bdd69764fb845e1497c6b
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.