LyogZW50ZXJub3dfcGNpLmMsdiAwLjk5IDIwMDEvMTAvMDIKICoKICogZW50ZXJub3dfcGNpLmMgICAgICAgQ2FyZC1zcGVjaWZpYyByb3V0aW5lcyBmb3IKICogICAgICAgICAgICAgICAgICAgICAgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhYgogKiAgICAgICAgICAgICAgICAgICAgICBHZXJkZXMgQUcgUG93ZXIgSVNETiBQQ0kKICogICAgICAgICAgICAgICAgICAgICAgV29lcmx0cm9uaWMgU0EgMTYgUENJCiAqICAgICAgICAgICAgICAgICAgICAgIChiYXNlZCBvbiBIaVNheCBkcml2ZXIgYnkgS2Fyc3RlbiBLZWlsKQogKgogKiBBdXRob3IgICAgICAgICAgICAgICBDaHJpc3RvcGggRXJzZmVsZCA8aW5mb0Bmb3JtdWxhLW4uZGU+CiAqICAgICAgICAgICAgICAgICAgICAgIEZvcm11bGEtbiBFdXJvcGUgQUcgKHd3dy5mb3JtdWxhLW4uY29tKQogKiAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c2x5IEdlcmRlcyBBRwogKgogKgogKiAgICAgICAgICAgICAgICAgICAgICBUaGlzIGZpbGUgaXMgKGMpIHVuZGVyIEdOVSBQVUJMSUMgTElDRU5TRQogKgogKiBOb3RlczoKICogVGhpcyBkcml2ZXIgaW50ZXJmYWNlcyB0byBuZXRqZXQuYyB3aGljaCBwZXJmb3JtcyBCLWNoYW5uZWwKICogcHJvY2Vzc2luZy4KICoKICogVmVyc2lvbiAwLjk5IGlzIHRoZSBmaXJzdCByZWxlYXNlIG9mIHRoaXMgZHJpdmVyIGFuZCB0aGVyZSBhcmUKICogY2VydGFpbmx5IGEgZmV3IGJ1Z3MuCiAqIEl0IGlzbid0IHRlc3RldCBvbiBsaW51eCAyLjQgeWV0LCBzbyBjb25zaWRlciB0aGlzIGNvZGUgdG8gYmUKICogYmV0YS4KICoKICogUGxlYXNlIGRvbid0IHJlcG9ydCBtZSBhbnkgbWFsZnVuY3Rpb24gd2l0aG91dCBzZW5kaW5nCiAqIChjb21wcmVzc2VkKSBkZWJ1Zy1sb2dzLgogKiBJdCB3b3VsZCBiZSBuZWFybHkgaW1wb3NzaWJsZSB0byByZXRyYWNlIGl0LgogKgogKiBMb2cgRC1jaGFubmVsLXByb2Nlc3NpbmcgYXMgZm9sbG93czoKICoKICogMS4gTG9hZCBoaXNheCB3aXRoIGNhcmQtc3BlY2lmaWMgcGFyYW1ldGVycywgdGhpcyBleGFtcGxlIGlzdCBmb3IKICogICAgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhbmQgY29tcGF0aWJsZQogKiAgICAoZi5lLiBHZXJkZXMgUG93ZXIgSVNETiBQQ0kpCiAqCiAqICAgIG1vZHByb2JlIGhpc2F4IHR5cGU9NDEgcHJvdG9jb2w9MiBpZD1nZXJkZXMKICoKICogICAgaWYgeW91IGNob3NlIGFuIG90aGVyIHZhbHVlIGZvciBpZCwgeW91IG5lZWQgdG8gbW9kaWZ5IHRoZQogKiAgICBjb2RlIGJlbG93LCB0b28uCiAqCiAqIDIuIHNldCBkZWJ1Zy1sZXZlbAogKgogKiAgICBoaXNheGN0cmwgZ2VyZGVzIDEgMHgzZmYKICogICAgaGlzYXhjdHJsIGdlcmRlcyAxMSAweDRmCiAqICAgIGNhdCAvZGV2L2lzZG5jdHJsID4+IH4vbG9nICYKICoKICogUGxlYXNlIHRha2UgYWxzbyBhIGxvb2sgaW50byAvdmFyL2xvZy9tZXNzYWdlcyBpZiB0aGVyZSBpcwogKiBhbnl0aGluZyBpbXBvcnRhbmQgY29uY2VybmluZyBISVNBWC4KICoKICoKICogQ3JlZGl0czoKICogUHJvZ3JhbW1pbmcgdGhlIGRyaXZlciBmb3IgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhbmQKICogbmVjZXNzYXJ5IHRoZSBkcml2ZXIgZm9yIHRoZSB1c2VkIEFtZCA3OTMwIEQtY2hhbm5lbC1jb250cm9sbGVyCiAqIHdhcyBzcG5zb3JlZCBieSBGb3JtdWxhLW4gRXVyb3BlIEFHLgogKiBUaGFua3MgdG8gS2Fyc3RlbiBLZWlsIGFuZCBQZXRyIE5vdmFrLCB3aG8gZ2F2ZSBtZSBzdXBwb3J0IGluCiAqIEhpc2F4LXNwZWNpZmljIHF1ZXN0aW9ucy4KICogSSB3YW50IHNvIHNheSBzcGVjaWFsIHRoYW5rcyB0byBDYXJsLUZyaWVkcmljaCBCcmF1biwgd2hvIGhhZCB0bwogKiBhbnN3ZXIgYSBsb3Qgb2YgcXVlc3Rpb25zIGFib3V0IGdlbmVyYWxseSBJU0ROIGFuZCBhYm91dCBoYW5kbGluZwogKiBvZiB0aGUgQW1kLUNoaXAuCiAqCiAqLwoKCiNpbmNsdWRlIDxsaW51eC9jb25maWcuaD4KI2luY2x1ZGUgImhpc2F4LmgiCiNpbmNsdWRlICJpc2FjLmgiCiNpbmNsdWRlICJpc2RubDEuaCIKI2luY2x1ZGUgImFtZDc5MzBfZm4uaCIKI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPgojaW5jbHVkZSA8bGludXgvcHBwX2RlZnMuaD4KI2luY2x1ZGUgPGxpbnV4L3BjaS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSAibmV0amV0LmgiCgoKCnN0YXRpYyBjb25zdCBjaGFyICplbnRlcm5vd19wY2lfcmV2ID0gIiRSZXZpc2lvbjogMS4xLjQuNSAkIjsKCgovKiBm/HIgUG93ZXJJU0ROIFBDSSAqLwojZGVmaW5lIFRKX0FNRF9JUlEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHgyMAojZGVmaW5lIFRKX0xFRDEgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg0MAojZGVmaW5lIFRKX0xFRDIgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHg4MAoKCi8qIERhcyBGZW5zdGVyIHp1bSBBTUQuLi4KICogQWIgQWRyZXNzZSBody5uamV0LmJhc2UgKyBUSl9BTURfUE9SVCB3ZXJkZW4gdm9tIEFNRCBqZXdlaWxzIDggQml0IGluCiAqIGRlbiBUaWdlckpldCBpL28tUmF1bSBnZW1hcHB0CiAqIC0+IDB4MDEgZGVzIEFNRCBiZWkgaHcubmpldC5iYXNlICsgMEM0ICovCiNkZWZpbmUgVEpfQU1EX1BPUlQgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAweEMwCgoKCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKiBJL08tSW50ZXJmYWNlIGZ1bmN0aW9ucyAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCgoKLyogY3MtPnJlYWRpc2FjLCBtYWNybyByQnl0ZUFNRCAqLwpzdGF0aWMgdW5zaWduZWQgY2hhcgpSZWFkQnl0ZUFtZDc5MzAoc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzLCB1bnNpZ25lZCBjaGFyIG9mZnNldCkKewoJLyogZGlyZWt0ZXMgUmVnaXN0ZXIgKi8KCWlmKG9mZnNldCA8IDgpCgkJcmV0dXJuIChpbmIoY3MtPmh3Lm5qZXQuaXNhYyArIDQqb2Zmc2V0KSk7CgoJLyogaW5kaXJla3RlcyBSZWdpc3RlciAqLwoJZWxzZSB7CgkJb3V0YihvZmZzZXQsIGNzLT5ody5uamV0LmlzYWMgKyA0KkFNRF9DUik7CgkJcmV0dXJuKGluYihjcy0+aHcubmpldC5pc2FjICsgNCpBTURfRFIpKTsKCX0KfQoKLyogY3MtPndyaXRlaXNhYywgbWFjcm8gd0J5dGVBTUQgKi8Kc3RhdGljIHZvaWQKV3JpdGVCeXRlQW1kNzkzMChzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MsIHVuc2lnbmVkIGNoYXIgb2Zmc2V0LCB1bnNpZ25lZCBjaGFyIHZhbHVlKQp7CgkvKiBkaXJla3RlcyBSZWdpc3RlciAqLwoJaWYob2Zmc2V0IDwgOCkKCQlvdXRiKHZhbHVlLCBjcy0+aHcubmpldC5pc2FjICsgNCpvZmZzZXQpOwoKCS8qIGluZGlyZWt0ZXMgUmVnaXN0ZXIgKi8KCWVsc2UgewoJCW91dGIob2Zmc2V0LCBjcy0+aHcubmpldC5pc2FjICsgNCpBTURfQ1IpOwoJCW91dGIodmFsdWUsIGNzLT5ody5uamV0LmlzYWMgKyA0KkFNRF9EUik7Cgl9Cn0KCgpzdGF0aWMgdm9pZAplbnBjaV9zZXRJcnFNYXNrKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcywgdW5zaWduZWQgY2hhciB2YWwpIHsKICAgICAgICBpZiAoIXZhbCkKCSAgICAgICAgb3V0YigweDAwLCBjcy0+aHcubmpldC5iYXNlK05FVEpFVF9JUlFNQVNLMSk7CiAgICAgICAgZWxzZQoJICAgICAgICBvdXRiKFRKX0FNRF9JUlEsIGNzLT5ody5uamV0LmJhc2UrTkVUSkVUX0lSUU1BU0sxKTsKfQoKCnN0YXRpYyB1bnNpZ25lZCBjaGFyIGR1bW15cnIoc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzLCBpbnQgY2hhbiwgdW5zaWduZWQgY2hhciBvZmYpCnsKICAgICAgICByZXR1cm4oNSk7Cn0KCnN0YXRpYyB2b2lkIGR1bW15d3Ioc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzLCBpbnQgY2hhbiwgdW5zaWduZWQgY2hhciBvZmYsIHVuc2lnbmVkIGNoYXIgdmFsdWUpCnsKCn0KCgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwoKCnN0YXRpYyB2b2lkCnJlc2V0X2VucGNpKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcykKewoJaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJCWRlYnVnbDEoY3MsICJlbnRlcjpub3cgUENJOiByZXNldCIpOwoKCS8qIFJlc2V0IG9uLCAoYWxzbyBmb3IgQU1EKSAqLwoJY3MtPmh3Lm5qZXQuY3RybF9yZWcgPSAweDA3OwoJb3V0Yihjcy0+aHcubmpldC5jdHJsX3JlZywgY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9DVFJMKTsKCW1kZWxheSgyMCk7CgkvKiBSZXNldCBvZmYgKi8KCWNzLT5ody5uamV0LmN0cmxfcmVnID0gMHgzMDsKCW91dGIoY3MtPmh3Lm5qZXQuY3RybF9yZWcsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQ1RSTCk7CgkvKiAyMG1zIGRlbGF5ICovCgltZGVsYXkoMjApOwoJY3MtPmh3Lm5qZXQuYXV4ZCA9IDA7ICAvLyBMRUQtc3RhdHVzCgljcy0+aHcubmpldC5kbWFjdHJsID0gMDsKCW91dGIoflRKX0FNRF9JUlEsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQVVYQ1RSTCk7CglvdXRiKFRKX0FNRF9JUlEsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfSVJRTUFTSzEpOwoJb3V0Yihjcy0+aHcubmpldC5hdXhkLCBjcy0+aHcubmpldC5hdXhhKTsgLy8gTEVEIG9mZgp9CgoKc3RhdGljIGludAplbnBjaV9jYXJkX21zZyhzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MsIGludCBtdCwgdm9pZCAqYXJnKQp7Cgl1X2xvbmcgZmxhZ3M7CiAgICAgICAgdW5zaWduZWQgY2hhciAqY2hhbjsKCglpZiAoY3MtPmRlYnVnICYgTDFfREVCX0lTQUMpCgkJZGVidWdsMShjcywgImVudGVyOm5vdyBQQ0k6IGNhcmRfbXNnOiAweCUwNFgiLCBtdCk7CgogICAgICAgIHN3aXRjaCAobXQpIHsKCQljYXNlIENBUkRfUkVTRVQ6CgkJCXNwaW5fbG9ja19pcnFzYXZlKCZjcy0+bG9jaywgZmxhZ3MpOwoJCQlyZXNldF9lbnBjaShjcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIEFtZDc5MzBfaW5pdChjcyk7CiAgICAgICAgICAgICAgICAgICAgICAgIHNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNzLT5sb2NrLCBmbGFncyk7CgkJCWJyZWFrOwoJCWNhc2UgQ0FSRF9SRUxFQVNFOgoJCQlyZWxlYXNlX2lvX25ldGpldChjcyk7CgkJCWJyZWFrOwoJCWNhc2UgQ0FSRF9JTklUOgoJCQlyZXNldF9lbnBjaShjcyk7CgkJCWluaXR0aWdlcihjcyk7CgkJCS8qIGlycSBtdXN0IGJlIG9uIGhlcmUgKi8KCQkJQW1kNzkzMF9pbml0KGNzKTsKCQkJYnJlYWs7CgkJY2FzZSBDQVJEX1RFU1Q6CgkJCWJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBNRExfQVNTSUdOOgogICAgICAgICAgICAgICAgICAgICAgICAvKiBURUkgYXNzaWduZWQsIExFRDEgb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgY3MtPmh3Lm5qZXQuYXV4ZCA9IFRKX0FNRF9JUlEgPDwgMTsKICAgICAgICAgICAgICAgICAgICAgICAgb3V0Yihjcy0+aHcubmpldC5hdXhkLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0FVWERBVEEpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgTURMX1JFTU9WRToKICAgICAgICAgICAgICAgICAgICAgICAgLyogVEVJIHJlbW92ZWQsIExFRHMgb2ZmICovCgkgICAgICAgICAgICAgICAgY3MtPmh3Lm5qZXQuYXV4ZCA9IDA7CiAgICAgICAgICAgICAgICAgICAgICAgIG91dGIoMHgwMCwgY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9BVVhEQVRBKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIE1ETF9CQ19BU1NJR046CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIGFjdGl2YXRlIEItY2hhbm5lbCAqLwogICAgICAgICAgICAgICAgICAgICAgICBjaGFuID0gKHVuc2lnbmVkIGNoYXIgKilhcmc7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3MtPmRlYnVnICYgTDFfREVCX0lTQUMpCgkJICAgICAgICAgICAgICAgIGRlYnVnbDEoY3MsICJlbnRlcjpub3cgUENJOiBhc3NpZ24gcGh5cy4gQkMgJWQgaW4gQU1EIExNUjEiLCAqY2hhbik7CgogICAgICAgICAgICAgICAgICAgICAgICBjcy0+ZGMuYW1kNzkzMC5waF9jb21tYW5kKGNzLCAoY3MtPmRjLmFtZDc5MzAubG1yMSB8ICgqY2hhbiArIDEpKSwgIk1ETF9CQ19BU1NJR04iKTsKICAgICAgICAgICAgICAgICAgICAgICAgLyogYXQgbGVhc3Qgb25lIGItY2hhbm5lbCBpbiB1c2UsIExFRCAyIG9uICovCiAgICAgICAgICAgICAgICAgICAgICAgIGNzLT5ody5uamV0LmF1eGQgfD0gVEpfQU1EX0lSUSA8PCAyOwogICAgICAgICAgICAgICAgICAgICAgICBvdXRiKGNzLT5ody5uamV0LmF1eGQsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQVVYREFUQSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBNRExfQkNfUkVMRUFTRToKICAgICAgICAgICAgICAgICAgICAgICAgLyogZGVhY3RpdmF0ZSBCLWNoYW5uZWwgKi8KICAgICAgICAgICAgICAgICAgICAgICAgY2hhbiA9ICh1bnNpZ25lZCBjaGFyICopYXJnOwoKICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNzLT5kZWJ1ZyAmIEwxX0RFQl9JU0FDKQoJCSAgICAgICAgICAgICAgICBkZWJ1Z2wxKGNzLCAiZW50ZXI6bm93IFBDSTogcmVsZWFzZSBwaHlzLiBCQyAlZCBpbiBBbWQgTE1SMSIsICpjaGFuKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNzLT5kYy5hbWQ3OTMwLnBoX2NvbW1hbmQoY3MsIChjcy0+ZGMuYW1kNzkzMC5sbXIxICYgfigqY2hhbiArIDEpKSwgIk1ETF9CQ19SRUxFQVNFIik7CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIG5vIGItY2hhbm5lbCBhY3RpdmUgLT4gTEVEMiBvZmYgKi8KICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCEoY3MtPmRjLmFtZDc5MzAubG1yMSAmIDMpKSB7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3MtPmh3Lm5qZXQuYXV4ZCAmPSB+KFRKX0FNRF9JUlEgPDwgMik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3V0Yihjcy0+aHcubmpldC5hdXhkLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0FVWERBVEEpOwogICAgICAgICAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgZGVmYXVsdDoKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgoJfQoJcmV0dXJuKDApOwp9CgpzdGF0aWMgaXJxcmV0dXJuX3QKZW5wY2lfaW50ZXJydXB0KGludCBpbnRubywgdm9pZCAqZGV2X2lkLCBzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzID0gZGV2X2lkOwoJdW5zaWduZWQgY2hhciBzMHZhbCwgczF2YWwsIGlyOwoJdV9sb25nIGZsYWdzOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZjcy0+bG9jaywgZmxhZ3MpOwoJczF2YWwgPSBpbmIoY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9JUlFTVEFUMSk7CgogICAgICAgIC8qIEFNRCB0aHJldyBhbiBpbnRlcnJ1cHQgKi8KCWlmICghKHMxdmFsICYgVEpfQU1EX0lSUSkpIHsKICAgICAgICAgICAgICAgIC8qIHJlYWQgYW5kIGNsZWFyIGludGVycnVwdC1yZWdpc3RlciAqLwoJCWlyID0gUmVhZEJ5dGVBbWQ3OTMwKGNzLCAweDAwKTsKCQlBbWQ3OTMwX2ludGVycnVwdChjcywgaXIpOwoJCXMxdmFsID0gMTsKCX0gZWxzZQoJCXMxdmFsID0gMDsKCXMwdmFsID0gaW5iKGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfSVJRU1RBVDApOwoJaWYgKChzMHZhbCB8IHMxdmFsKT09MCkgeyAvLyBzaGFyZWQgSVJRCgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3MtPmxvY2ssIGZsYWdzKTsKCQlyZXR1cm4gSVJRX05PTkU7Cgl9IAoJaWYgKHMwdmFsKQoJCW91dGIoczB2YWwsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfSVJRU1RBVDApOwoKCS8qIERNQS1JbnRlcnJ1cHQ6IEItY2hhbm5lbC1zdHVmZiAqLwoJLyogc2V0IGJpdHMgaW4gc3ZhbCB0byBpbmRpY2F0ZSB3aGljaCBwYWdlIGlzIGZyZWUgKi8KCWlmIChpbmwoY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9ETUFfV1JJVEVfQURSKSA8CgkJaW5sKGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfRE1BX1dSSVRFX0lSUSkpCgkJLyogdGhlIDJuZCB3cml0ZSBwYWdlIGlzIGZyZWUgKi8KCQlzMHZhbCA9IDB4MDg7CgllbHNlCS8qIHRoZSAxc3Qgd3JpdGUgcGFnZSBpcyBmcmVlICovCgkJczB2YWwgPSAweDA0OwoJaWYgKGlubChjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0RNQV9SRUFEX0FEUikgPAoJCWlubChjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0RNQV9SRUFEX0lSUSkpCgkJLyogdGhlIDJuZCByZWFkIHBhZ2UgaXMgZnJlZSAqLwoJCXMwdmFsID0gczB2YWwgfCAweDAyOwoJZWxzZQkvKiB0aGUgMXN0IHJlYWQgcGFnZSBpcyBmcmVlICovCgkJczB2YWwgPSBzMHZhbCB8IDB4MDE7CglpZiAoczB2YWwgIT0gY3MtPmh3Lm5qZXQubGFzdF9pczApIC8qIHdlIGhhdmUgYSBETUEgaW50ZXJydXB0ICovCgl7CgkJaWYgKHRlc3RfYW5kX3NldF9iaXQoRkxHX0xPQ0tfQVRPTUlDLCAmY3MtPkhXX0ZsYWdzKSkgewoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjcy0+bG9jaywgZmxhZ3MpOwoJCQlyZXR1cm4gSVJRX0hBTkRMRUQ7CgkJfQoJCWNzLT5ody5uamV0LmlycXN0YXQwID0gczB2YWw7CgkJaWYgKChjcy0+aHcubmpldC5pcnFzdGF0MCAmIE5FVEpFVF9JUlFNMF9SRUFEKSAhPQoJCQkoY3MtPmh3Lm5qZXQubGFzdF9pczAgJiBORVRKRVRfSVJRTTBfUkVBRCkpCgkJCS8qIHdlIGhhdmUgYSByZWFkIGRtYSBpbnQgKi8KCQkJcmVhZF90aWdlcihjcyk7CgkJaWYgKChjcy0+aHcubmpldC5pcnFzdGF0MCAmIE5FVEpFVF9JUlFNMF9XUklURSkgIT0KCQkJKGNzLT5ody5uamV0Lmxhc3RfaXMwICYgTkVUSkVUX0lSUU0wX1dSSVRFKSkKCQkJLyogd2UgaGF2ZSBhIHdyaXRlIGRtYSBpbnQgKi8KCQkJd3JpdGVfdGlnZXIoY3MpOwoJCXRlc3RfYW5kX2NsZWFyX2JpdChGTEdfTE9DS19BVE9NSUMsICZjcy0+SFdfRmxhZ3MpOwoJfQoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3MtPmxvY2ssIGZsYWdzKTsKCXJldHVybiBJUlFfSEFORExFRDsKfQoKCnN0YXRpYyBzdHJ1Y3QgcGNpX2RldiAqZGV2X25ldGpldCBfX2luaXRkYXRhID0gTlVMTDsKCi8qIGNhbGxlZCBieSBjb25maWcuYyAqLwppbnQgX19pbml0CnNldHVwX2VudGVybm93X3BjaShzdHJ1Y3QgSXNkbkNhcmQgKmNhcmQpCnsKCWludCBieXRlY250OwoJc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzID0gY2FyZC0+Y3M7CgljaGFyIHRtcFs2NF07CgojaWZkZWYgQ09ORklHX1BDSQojaWZkZWYgX19CSUdfRU5ESUFOCiNlcnJvciAibm90IHJ1bm5pbmcgb24gYmlnIGVuZGlhbiBtYWNoaW5lcyBub3ciCiNlbmRpZgogICAgICAgIHN0cmNweSh0bXAsIGVudGVybm93X3BjaV9yZXYpOwoJcHJpbnRrKEtFUk5fSU5GTyAiSGlTYXg6IEZvcm11bGEtbiBFdXJvcGUgQUcgZW50ZXI6bm93IElTRE4gUENJIGRyaXZlciBSZXYuICVzXG4iLCBIaVNheF9nZXRyZXYodG1wKSk7CglpZiAoY3MtPnR5cCAhPSBJU0ROX0NUWVBFX0VOVEVSTk9XKQoJCXJldHVybigwKTsKCXRlc3RfYW5kX2NsZWFyX2JpdChGTEdfTE9DS19BVE9NSUMsICZjcy0+SFdfRmxhZ3MpOwoKCWZvciAoIDs7ICkKCXsKCQlpZiAoKGRldl9uZXRqZXQgPSBwY2lfZmluZF9kZXZpY2UoUENJX1ZFTkRPUl9JRF9USUdFUkpFVCwKCQkJUENJX0RFVklDRV9JRF9USUdFUkpFVF8zMDAsICBkZXZfbmV0amV0KSkpIHsKCQkJaWYgKHBjaV9lbmFibGVfZGV2aWNlKGRldl9uZXRqZXQpKQoJCQkJcmV0dXJuKDApOwoJCQljcy0+aXJxID0gZGV2X25ldGpldC0+aXJxOwoJCQlpZiAoIWNzLT5pcnEpIHsKCQkJCXByaW50ayhLRVJOX1dBUk5JTkcgImVudGVyOm5vdyBQQ0k6IE5vIElSUSBmb3IgUENJIGNhcmQgZm91bmRcbiIpOwoJCQkJcmV0dXJuKDApOwoJCQl9CgkJCWNzLT5ody5uamV0LmJhc2UgPSBwY2lfcmVzb3VyY2Vfc3RhcnQoZGV2X25ldGpldCwgMCk7CgkJCWlmICghY3MtPmh3Lm5qZXQuYmFzZSkgewoJCQkJcHJpbnRrKEtFUk5fV0FSTklORyAiZW50ZXI6bm93IFBDSTogTm8gSU8tQWRyIGZvciBQQ0kgY2FyZCBmb3VuZFxuIik7CgkJCQlyZXR1cm4oMCk7CgkJCX0KICAgICAgICAgICAgICAgICAgICAgICAgLyogY2hlY2tzIFN1Yi1WZW5kb3IgSUQgYmVjYXVzZSBzeXN0ZW0gY3Jhc2hlcyB3aXRoIFRyYXZlcnNlLUNhcmQgKi8KCQkJaWYgKChkZXZfbmV0amV0LT5zdWJzeXN0ZW1fdmVuZG9yICE9IDB4NTUpIHx8CgkJCQkoZGV2X25ldGpldC0+c3Vic3lzdGVtX2RldmljZSAhPSAweDAyKSkgewoJCQkJcHJpbnRrKEtFUk5fV0FSTklORyAiZW50ZXI6bm93OiBZb3UgdHJpZWQgdG8gbG9hZCB0aGlzIGRyaXZlciB3aXRoIGFuIGluY29tcGF0aWJsZSBUaWdlckpldC1jYXJkXG4iKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBwcmludGsoS0VSTl9XQVJOSU5HICJVc2UgdHlwZT0yMCBmb3IgVHJhdmVyc2UgTmV0SmV0IFBDSSBDYXJkLlxuIik7CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuKDApOwogICAgICAgICAgICAgICAgICAgICAgICB9CgkJfSBlbHNlIHsKICAgICAgICAgICAgICAgICAgICAgICAgcHJpbnRrKEtFUk5fV0FSTklORyAiZW50ZXI6bm93IFBDSTogTm8gUENJIGNhcmQgZm91bmRcbiIpOwoJCQlyZXR1cm4oMCk7CgkJfQoKCQljcy0+aHcubmpldC5hdXhhID0gY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9BVVhEQVRBOwoJCWNzLT5ody5uamV0LmlzYWMgPSBjcy0+aHcubmpldC5iYXNlICsgMHhDMDsgLy8gRmVuc3RlciB6dW0gQU1ECgoJCS8qIFJlc2V0IGFuICovCgkJY3MtPmh3Lm5qZXQuY3RybF9yZWcgPSAweDA3OyAgLy8gZ2XkbmRlcnQgdm9uIDB4ZmYKCQlvdXRiKGNzLT5ody5uamV0LmN0cmxfcmVnLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0NUUkwpOwoJCS8qIDIwIG1zIFBhdXNlICovCgkJbWRlbGF5KDIwKTsKCgkJY3MtPmh3Lm5qZXQuY3RybF9yZWcgPSAweDMwOyAgLyogUmVzZXQgT2ZmIGFuZCBzdGF0dXMgcmVhZCBjbGVhciAqLwoJCW91dGIoY3MtPmh3Lm5qZXQuY3RybF9yZWcsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQ1RSTCk7CgkJbWRlbGF5KDEwKTsKCgkJY3MtPmh3Lm5qZXQuYXV4ZCA9IDB4MDA7IC8vIHdhciAweGMwCgkJY3MtPmh3Lm5qZXQuZG1hY3RybCA9IDA7CgoJCW91dGIoflRKX0FNRF9JUlEsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQVVYQ1RSTCk7CgkJb3V0YihUSl9BTURfSVJRLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0lSUU1BU0sxKTsKCQlvdXRiKGNzLT5ody5uamV0LmF1eGQsIGNzLT5ody5uamV0LmF1eGEpOwoKCQlicmVhazsKCX0KI2Vsc2UKCglwcmludGsoS0VSTl9XQVJOSU5HICJlbnRlcjpub3cgUENJOiBOT19QQ0lfQklPU1xuIik7CglwcmludGsoS0VSTl9XQVJOSU5HICJlbnRlcjpub3cgUENJOiB1bmFibGUgdG8gY29uZmlnIEZvcm11bGEtbiBlbnRlcjpub3cgSVNETiBQQ0kgYWJcbiIpOwoJcmV0dXJuICgwKTsKCiNlbmRpZiAvKiBDT05GSUdfUENJICovCgoJYnl0ZWNudCA9IDI1NjsKCglwcmludGsoS0VSTl9JTkZPCgkJImVudGVyOm5vdyBQQ0k6IFBDSSBjYXJkIGNvbmZpZ3VyZWQgYXQgMHglbHggSVJRICVkXG4iLAoJCWNzLT5ody5uamV0LmJhc2UsIGNzLT5pcnEpOwoJaWYgKCFyZXF1ZXN0X3JlZ2lvbihjcy0+aHcubmpldC5iYXNlLCBieXRlY250LCAiRm5fSVNETiIpKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORwoJCQkgICAiSGlTYXg6ICVzIGNvbmZpZyBwb3J0ICVseC0lbHggYWxyZWFkeSBpbiB1c2VcbiIsCgkJCSAgIENhcmRUeXBlW2NhcmQtPnR5cF0sCgkJCSAgIGNzLT5ody5uamV0LmJhc2UsCgkJCSAgIGNzLT5ody5uamV0LmJhc2UgKyBieXRlY250KTsKCQlyZXR1cm4gKDApOwoJfQoJc2V0dXBfQW1kNzkzMChjcyk7Cgljcy0+aHcubmpldC5sYXN0X2lzMCA9IDA7CiAgICAgICAgLyogbWFjcm8gckJ5dGVBTUQgKi8KICAgICAgICBjcy0+cmVhZGlzYWMgPSAmUmVhZEJ5dGVBbWQ3OTMwOwogICAgICAgIC8qIG1hY3JvIHdCeXRlQU1EICovCiAgICAgICAgY3MtPndyaXRlaXNhYyA9ICZXcml0ZUJ5dGVBbWQ3OTMwOwogICAgICAgIGNzLT5kYy5hbWQ3OTMwLnNldElycU1hc2sgPSAmZW5wY2lfc2V0SXJxTWFzazsKCiAgICAgICAgY3MtPkJDX1JlYWRfUmVnICA9ICZkdW1teXJyOwoJY3MtPkJDX1dyaXRlX1JlZyA9ICZkdW1teXdyOwoJY3MtPkJDX1NlbmRfRGF0YSA9ICZuZXRqZXRfZmlsbF9kbWE7Cgljcy0+Y2FyZG1zZyA9ICZlbnBjaV9jYXJkX21zZzsKCWNzLT5pcnFfZnVuYyA9ICZlbnBjaV9pbnRlcnJ1cHQ7Cgljcy0+aXJxX2ZsYWdzIHw9IFNBX1NISVJROwoKICAgICAgICByZXR1cm4gKDEpOwp9Cg==