LyogZW50ZXJub3dfcGNpLmMsdiAwLjk5IDIwMDEvMTAvMDIKICoKICogZW50ZXJub3dfcGNpLmMgICAgICAgQ2FyZC1zcGVjaWZpYyByb3V0aW5lcyBmb3IKICogICAgICAgICAgICAgICAgICAgICAgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhYgogKiAgICAgICAgICAgICAgICAgICAgICBHZXJkZXMgQUcgUG93ZXIgSVNETiBQQ0kKICogICAgICAgICAgICAgICAgICAgICAgV29lcmx0cm9uaWMgU0EgMTYgUENJCiAqICAgICAgICAgICAgICAgICAgICAgIChiYXNlZCBvbiBIaVNheCBkcml2ZXIgYnkgS2Fyc3RlbiBLZWlsKQogKgogKiBBdXRob3IgICAgICAgICAgICAgICBDaHJpc3RvcGggRXJzZmVsZCA8aW5mb0Bmb3JtdWxhLW4uZGU+CiAqICAgICAgICAgICAgICAgICAgICAgIEZvcm11bGEtbiBFdXJvcGUgQUcgKHd3dy5mb3JtdWxhLW4uY29tKQogKiAgICAgICAgICAgICAgICAgICAgICBwcmV2aW91c2x5IEdlcmRlcyBBRwogKgogKgogKiAgICAgICAgICAgICAgICAgICAgICBUaGlzIGZpbGUgaXMgKGMpIHVuZGVyIEdOVSBQVUJMSUMgTElDRU5TRQogKgogKiBOb3RlczoKICogVGhpcyBkcml2ZXIgaW50ZXJmYWNlcyB0byBuZXRqZXQuYyB3aGljaCBwZXJmb3JtcyBCLWNoYW5uZWwKICogcHJvY2Vzc2luZy4KICoKICogVmVyc2lvbiAwLjk5IGlzIHRoZSBmaXJzdCByZWxlYXNlIG9mIHRoaXMgZHJpdmVyIGFuZCB0aGVyZSBhcmUKICogY2VydGFpbmx5IGEgZmV3IGJ1Z3MuCiAqIEl0IGlzbid0IHRlc3RldCBvbiBsaW51eCAyLjQgeWV0LCBzbyBjb25zaWRlciB0aGlzIGNvZGUgdG8gYmUKICogYmV0YS4KICoKICogUGxlYXNlIGRvbid0IHJlcG9ydCBtZSBhbnkgbWFsZnVuY3Rpb24gd2l0aG91dCBzZW5kaW5nCiAqIChjb21wcmVzc2VkKSBkZWJ1Zy1sb2dzLgogKiBJdCB3b3VsZCBiZSBuZWFybHkgaW1wb3NzaWJsZSB0byByZXRyYWNlIGl0LgogKgogKiBMb2cgRC1jaGFubmVsLXByb2Nlc3NpbmcgYXMgZm9sbG93czoKICoKICogMS4gTG9hZCBoaXNheCB3aXRoIGNhcmQtc3BlY2lmaWMgcGFyYW1ldGVycywgdGhpcyBleGFtcGxlIGlzdCBmb3IKICogICAgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhbmQgY29tcGF0aWJsZQogKiAgICAoZi5lLiBHZXJkZXMgUG93ZXIgSVNETiBQQ0kpCiAqCiAqICAgIG1vZHByb2JlIGhpc2F4IHR5cGU9NDEgcHJvdG9jb2w9MiBpZD1nZXJkZXMKICoKICogICAgaWYgeW91IGNob3NlIGFuIG90aGVyIHZhbHVlIGZvciBpZCwgeW91IG5lZWQgdG8gbW9kaWZ5IHRoZQogKiAgICBjb2RlIGJlbG93LCB0b28uCiAqCiAqIDIuIHNldCBkZWJ1Zy1sZXZlbAogKgogKiAgICBoaXNheGN0cmwgZ2VyZGVzIDEgMHgzZmYKICogICAgaGlzYXhjdHJsIGdlcmRlcyAxMSAweDRmCiAqICAgIGNhdCAvZGV2L2lzZG5jdHJsID4+IH4vbG9nICYKICoKICogUGxlYXNlIHRha2UgYWxzbyBhIGxvb2sgaW50byAvdmFyL2xvZy9tZXNzYWdlcyBpZiB0aGVyZSBpcwogKiBhbnl0aGluZyBpbXBvcnRhbmQgY29uY2VybmluZyBISVNBWC4KICoKICoKICogQ3JlZGl0czoKICogUHJvZ3JhbW1pbmcgdGhlIGRyaXZlciBmb3IgRm9ybXVsYS1uIGVudGVyOm5vdyBJU0ROIFBDSSBhbmQKICogbmVjZXNzYXJ5IHRoZSBkcml2ZXIgZm9yIHRoZSB1c2VkIEFtZCA3OTMwIEQtY2hhbm5lbC1jb250cm9sbGVyCiAqIHdhcyBzcG5zb3JlZCBieSBGb3JtdWxhLW4gRXVyb3BlIEFHLgogKiBUaGFua3MgdG8gS2Fyc3RlbiBLZWlsIGFuZCBQZXRyIE5vdmFrLCB3aG8gZ2F2ZSBtZSBzdXBwb3J0IGluCiAqIEhpc2F4LXNwZWNpZmljIHF1ZXN0aW9ucy4KICogSSB3YW50IHNvIHNheSBzcGVjaWFsIHRoYW5rcyB0byBDYXJsLUZyaWVkcmljaCBCcmF1biwgd2hvIGhhZCB0bwogKiBhbnN3ZXIgYSBsb3Qgb2YgcXVlc3Rpb25zIGFib3V0IGdlbmVyYWxseSBJU0ROIGFuZCBhYm91dCBoYW5kbGluZwogKiBvZiB0aGUgQW1kLUNoaXAuCiAqCiAqLwoKCiNpbmNsdWRlICJoaXNheC5oIgojaW5jbHVkZSAiaXNhYy5oIgojaW5jbHVkZSAiaXNkbmwxLmgiCiNpbmNsdWRlICJhbWQ3OTMwX2ZuLmgiCiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L3BwcF9kZWZzLmg+CiNpbmNsdWRlIDxsaW51eC9wY2kuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgIm5ldGpldC5oIgoKCgpzdGF0aWMgY29uc3QgY2hhciAqZW50ZXJub3dfcGNpX3JldiA9ICIkUmV2aXNpb246IDEuMS40LjUgJCI7CgoKLyogZm9yIFBvd2VySVNETiBQQ0kgKi8KI2RlZmluZSBUSl9BTURfSVJRICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4MjAKI2RlZmluZSBUSl9MRUQxICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4NDAKI2RlZmluZSBUSl9MRUQyICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDB4ODAKCgovKiBUaGUgd2luZG93IHRvIFt0aGVdIEFNRCBbY2hpcF0uLi4KICogRnJvbSBhZGRyZXNzIGh3Lm5qZXQuYmFzZSArIFRKX0FNRF9QT1JUIG9ud2FyZHMsIHRoZSBBTUQKICogbWFwcyBbY29uc2VjdXRpdmUvbXVsdGlwbGVdIDggYml0cyBpbnRvIHRoZSBUaWdlckpldCBJL08gc3BhY2UKICogLT4gMHgwMSBvZiB0aGUgQU1EIGF0IGh3Lm5qZXQuYmFzZSArIDBDNCAqLwojZGVmaW5lIFRKX0FNRF9QT1JUICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgMHhDMAoKCgovKiAqKioqKioqKioqKioqKioqKioqKioqKioqKiogSS9PLUludGVyZmFjZSBmdW5jdGlvbnMgKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiAqLwoKCi8qIGNzLT5yZWFkaXNhYywgbWFjcm8gckJ5dGVBTUQgKi8Kc3RhdGljIHVuc2lnbmVkIGNoYXIKUmVhZEJ5dGVBbWQ3OTMwKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcywgdW5zaWduZWQgY2hhciBvZmZzZXQpCnsKCS8qIGRpcmVjdCByZWdpc3RlciAqLwoJaWYob2Zmc2V0IDwgOCkKCQlyZXR1cm4gKGluYihjcy0+aHcubmpldC5pc2FjICsgNCpvZmZzZXQpKTsKCgkvKiBpbmRpcmVjdCByZWdpc3RlciAqLwoJZWxzZSB7CgkJb3V0YihvZmZzZXQsIGNzLT5ody5uamV0LmlzYWMgKyA0KkFNRF9DUik7CgkJcmV0dXJuKGluYihjcy0+aHcubmpldC5pc2FjICsgNCpBTURfRFIpKTsKCX0KfQoKLyogY3MtPndyaXRlaXNhYywgbWFjcm8gd0J5dGVBTUQgKi8Kc3RhdGljIHZvaWQKV3JpdGVCeXRlQW1kNzkzMChzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MsIHVuc2lnbmVkIGNoYXIgb2Zmc2V0LCB1bnNpZ25lZCBjaGFyIHZhbHVlKQp7CgkvKiBkaXJlY3QgcmVnaXN0ZXIgKi8KCWlmKG9mZnNldCA8IDgpCgkJb3V0Yih2YWx1ZSwgY3MtPmh3Lm5qZXQuaXNhYyArIDQqb2Zmc2V0KTsKCgkvKiBpbmRpcmVjdCByZWdpc3RlciAqLwoJZWxzZSB7CgkJb3V0YihvZmZzZXQsIGNzLT5ody5uamV0LmlzYWMgKyA0KkFNRF9DUik7CgkJb3V0Yih2YWx1ZSwgY3MtPmh3Lm5qZXQuaXNhYyArIDQqQU1EX0RSKTsKCX0KfQoKCnN0YXRpYyB2b2lkCmVucGNpX3NldElycU1hc2soc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzLCB1bnNpZ25lZCBjaGFyIHZhbCkgewogICAgICAgIGlmICghdmFsKQoJICAgICAgICBvdXRiKDB4MDAsIGNzLT5ody5uamV0LmJhc2UrTkVUSkVUX0lSUU1BU0sxKTsKICAgICAgICBlbHNlCgkgICAgICAgIG91dGIoVEpfQU1EX0lSUSwgY3MtPmh3Lm5qZXQuYmFzZStORVRKRVRfSVJRTUFTSzEpOwp9CgoKc3RhdGljIHVuc2lnbmVkIGNoYXIgZHVtbXlycihzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MsIGludCBjaGFuLCB1bnNpZ25lZCBjaGFyIG9mZikKewogICAgICAgIHJldHVybig1KTsKfQoKc3RhdGljIHZvaWQgZHVtbXl3cihzdHJ1Y3QgSXNkbkNhcmRTdGF0ZSAqY3MsIGludCBjaGFuLCB1bnNpZ25lZCBjaGFyIG9mZiwgdW5zaWduZWQgY2hhciB2YWx1ZSkKewoKfQoKCi8qICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqICovCgoKc3RhdGljIHZvaWQKcmVzZXRfZW5wY2koc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzKQp7CglpZiAoY3MtPmRlYnVnICYgTDFfREVCX0lTQUMpCgkJZGVidWdsMShjcywgImVudGVyOm5vdyBQQ0k6IHJlc2V0Iik7CgoJLyogUmVzZXQgb24sIChhbHNvIGZvciBBTUQpICovCgljcy0+aHcubmpldC5jdHJsX3JlZyA9IDB4MDc7CglvdXRiKGNzLT5ody5uamV0LmN0cmxfcmVnLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0NUUkwpOwoJbWRlbGF5KDIwKTsKCS8qIFJlc2V0IG9mZiAqLwoJY3MtPmh3Lm5qZXQuY3RybF9yZWcgPSAweDMwOwoJb3V0Yihjcy0+aHcubmpldC5jdHJsX3JlZywgY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9DVFJMKTsKCS8qIDIwbXMgZGVsYXkgKi8KCW1kZWxheSgyMCk7Cgljcy0+aHcubmpldC5hdXhkID0gMDsgIC8vIExFRC1zdGF0dXMKCWNzLT5ody5uamV0LmRtYWN0cmwgPSAwOwoJb3V0Yih+VEpfQU1EX0lSUSwgY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9BVVhDVFJMKTsKCW91dGIoVEpfQU1EX0lSUSwgY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9JUlFNQVNLMSk7CglvdXRiKGNzLT5ody5uamV0LmF1eGQsIGNzLT5ody5uamV0LmF1eGEpOyAvLyBMRUQgb2ZmCn0KCgpzdGF0aWMgaW50CmVucGNpX2NhcmRfbXNnKHN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcywgaW50IG10LCB2b2lkICphcmcpCnsKCXVfbG9uZyBmbGFnczsKICAgICAgICB1bnNpZ25lZCBjaGFyICpjaGFuOwoKCWlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQlkZWJ1Z2wxKGNzLCAiZW50ZXI6bm93IFBDSTogY2FyZF9tc2c6IDB4JTA0WCIsIG10KTsKCiAgICAgICAgc3dpdGNoIChtdCkgewoJCWNhc2UgQ0FSRF9SRVNFVDoKCQkJc3Bpbl9sb2NrX2lycXNhdmUoJmNzLT5sb2NrLCBmbGFncyk7CgkJCXJlc2V0X2VucGNpKGNzKTsKICAgICAgICAgICAgICAgICAgICAgICAgQW1kNzkzMF9pbml0KGNzKTsKICAgICAgICAgICAgICAgICAgICAgICAgc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3MtPmxvY2ssIGZsYWdzKTsKCQkJYnJlYWs7CgkJY2FzZSBDQVJEX1JFTEVBU0U6CgkJCXJlbGVhc2VfaW9fbmV0amV0KGNzKTsKCQkJYnJlYWs7CgkJY2FzZSBDQVJEX0lOSVQ6CgkJCXJlc2V0X2VucGNpKGNzKTsKCQkJaW5pdHRpZ2VyKGNzKTsKCQkJLyogaXJxIG11c3QgYmUgb24gaGVyZSAqLwoJCQlBbWQ3OTMwX2luaXQoY3MpOwoJCQlicmVhazsKCQljYXNlIENBUkRfVEVTVDoKCQkJYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIE1ETF9BU1NJR046CiAgICAgICAgICAgICAgICAgICAgICAgIC8qIFRFSSBhc3NpZ25lZCwgTEVEMSBvbiAqLwogICAgICAgICAgICAgICAgICAgICAgICBjcy0+aHcubmpldC5hdXhkID0gVEpfQU1EX0lSUSA8PCAxOwogICAgICAgICAgICAgICAgICAgICAgICBvdXRiKGNzLT5ody5uamV0LmF1eGQsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQVVYREFUQSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICAgICAgY2FzZSBNRExfUkVNT1ZFOgogICAgICAgICAgICAgICAgICAgICAgICAvKiBURUkgcmVtb3ZlZCwgTEVEcyBvZmYgKi8KCSAgICAgICAgICAgICAgICBjcy0+aHcubmpldC5hdXhkID0gMDsKICAgICAgICAgICAgICAgICAgICAgICAgb3V0YigweDAwLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0FVWERBVEEpOwogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKICAgICAgICAgICAgICAgIGNhc2UgTURMX0JDX0FTU0lHTjoKICAgICAgICAgICAgICAgICAgICAgICAgLyogYWN0aXZhdGUgQi1jaGFubmVsICovCiAgICAgICAgICAgICAgICAgICAgICAgIGNoYW4gPSAodW5zaWduZWQgY2hhciAqKWFyZzsKCiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjcy0+ZGVidWcgJiBMMV9ERUJfSVNBQykKCQkgICAgICAgICAgICAgICAgZGVidWdsMShjcywgImVudGVyOm5vdyBQQ0k6IGFzc2lnbiBwaHlzLiBCQyAlZCBpbiBBTUQgTE1SMSIsICpjaGFuKTsKCiAgICAgICAgICAgICAgICAgICAgICAgIGNzLT5kYy5hbWQ3OTMwLnBoX2NvbW1hbmQoY3MsIChjcy0+ZGMuYW1kNzkzMC5sbXIxIHwgKCpjaGFuICsgMSkpLCAiTURMX0JDX0FTU0lHTiIpOwogICAgICAgICAgICAgICAgICAgICAgICAvKiBhdCBsZWFzdCBvbmUgYi1jaGFubmVsIGluIHVzZSwgTEVEIDIgb24gKi8KICAgICAgICAgICAgICAgICAgICAgICAgY3MtPmh3Lm5qZXQuYXV4ZCB8PSBUSl9BTURfSVJRIDw8IDI7CiAgICAgICAgICAgICAgICAgICAgICAgIG91dGIoY3MtPmh3Lm5qZXQuYXV4ZCwgY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9BVVhEQVRBKTsKICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBjYXNlIE1ETF9CQ19SRUxFQVNFOgogICAgICAgICAgICAgICAgICAgICAgICAvKiBkZWFjdGl2YXRlIEItY2hhbm5lbCAqLwogICAgICAgICAgICAgICAgICAgICAgICBjaGFuID0gKHVuc2lnbmVkIGNoYXIgKilhcmc7CgogICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3MtPmRlYnVnICYgTDFfREVCX0lTQUMpCgkJICAgICAgICAgICAgICAgIGRlYnVnbDEoY3MsICJlbnRlcjpub3cgUENJOiByZWxlYXNlIHBoeXMuIEJDICVkIGluIEFtZCBMTVIxIiwgKmNoYW4pOwoKICAgICAgICAgICAgICAgICAgICAgICAgY3MtPmRjLmFtZDc5MzAucGhfY29tbWFuZChjcywgKGNzLT5kYy5hbWQ3OTMwLmxtcjEgJiB+KCpjaGFuICsgMSkpLCAiTURMX0JDX1JFTEVBU0UiKTsKICAgICAgICAgICAgICAgICAgICAgICAgLyogbm8gYi1jaGFubmVsIGFjdGl2ZSAtPiBMRUQyIG9mZiAqLwogICAgICAgICAgICAgICAgICAgICAgICBpZiAoIShjcy0+ZGMuYW1kNzkzMC5sbXIxICYgMykpIHsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcy0+aHcubmpldC5hdXhkICY9IH4oVEpfQU1EX0lSUSA8PCAyKTsKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBvdXRiKGNzLT5ody5uamV0LmF1eGQsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQVVYREFUQSk7CiAgICAgICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgICAgICBkZWZhdWx0OgogICAgICAgICAgICAgICAgICAgICAgICBicmVhazsKCgl9CglyZXR1cm4oMCk7Cn0KCnN0YXRpYyBpcnFyZXR1cm5fdAplbnBjaV9pbnRlcnJ1cHQoaW50IGludG5vLCB2b2lkICpkZXZfaWQpCnsKCXN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcyA9IGRldl9pZDsKCXVuc2lnbmVkIGNoYXIgczB2YWwsIHMxdmFsLCBpcjsKCXVfbG9uZyBmbGFnczsKCglzcGluX2xvY2tfaXJxc2F2ZSgmY3MtPmxvY2ssIGZsYWdzKTsKCXMxdmFsID0gaW5iKGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfSVJRU1RBVDEpOwoKICAgICAgICAvKiBBTUQgdGhyZXcgYW4gaW50ZXJydXB0ICovCglpZiAoIShzMXZhbCAmIFRKX0FNRF9JUlEpKSB7CiAgICAgICAgICAgICAgICAvKiByZWFkIGFuZCBjbGVhciBpbnRlcnJ1cHQtcmVnaXN0ZXIgKi8KCQlpciA9IFJlYWRCeXRlQW1kNzkzMChjcywgMHgwMCk7CgkJQW1kNzkzMF9pbnRlcnJ1cHQoY3MsIGlyKTsKCQlzMXZhbCA9IDE7Cgl9IGVsc2UKCQlzMXZhbCA9IDA7CglzMHZhbCA9IGluYihjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0lSUVNUQVQwKTsKCWlmICgoczB2YWwgfCBzMXZhbCk9PTApIHsgLy8gc2hhcmVkIElSUQoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNzLT5sb2NrLCBmbGFncyk7CgkJcmV0dXJuIElSUV9OT05FOwoJfSAKCWlmIChzMHZhbCkKCQlvdXRiKHMwdmFsLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0lSUVNUQVQwKTsKCgkvKiBETUEtSW50ZXJydXB0OiBCLWNoYW5uZWwtc3R1ZmYgKi8KCS8qIHNldCBiaXRzIGluIHN2YWwgdG8gaW5kaWNhdGUgd2hpY2ggcGFnZSBpcyBmcmVlICovCglpZiAoaW5sKGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfRE1BX1dSSVRFX0FEUikgPAoJCWlubChjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0RNQV9XUklURV9JUlEpKQoJCS8qIHRoZSAybmQgd3JpdGUgcGFnZSBpcyBmcmVlICovCgkJczB2YWwgPSAweDA4OwoJZWxzZQkvKiB0aGUgMXN0IHdyaXRlIHBhZ2UgaXMgZnJlZSAqLwoJCXMwdmFsID0gMHgwNDsKCWlmIChpbmwoY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9ETUFfUkVBRF9BRFIpIDwKCQlpbmwoY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9ETUFfUkVBRF9JUlEpKQoJCS8qIHRoZSAybmQgcmVhZCBwYWdlIGlzIGZyZWUgKi8KCQlzMHZhbCA9IHMwdmFsIHwgMHgwMjsKCWVsc2UJLyogdGhlIDFzdCByZWFkIHBhZ2UgaXMgZnJlZSAqLwoJCXMwdmFsID0gczB2YWwgfCAweDAxOwoJaWYgKHMwdmFsICE9IGNzLT5ody5uamV0Lmxhc3RfaXMwKSAvKiB3ZSBoYXZlIGEgRE1BIGludGVycnVwdCAqLwoJewoJCWlmICh0ZXN0X2FuZF9zZXRfYml0KEZMR19MT0NLX0FUT01JQywgJmNzLT5IV19GbGFncykpIHsKCQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmY3MtPmxvY2ssIGZsYWdzKTsKCQkJcmV0dXJuIElSUV9IQU5ETEVEOwoJCX0KCQljcy0+aHcubmpldC5pcnFzdGF0MCA9IHMwdmFsOwoJCWlmICgoY3MtPmh3Lm5qZXQuaXJxc3RhdDAgJiBORVRKRVRfSVJRTTBfUkVBRCkgIT0KCQkJKGNzLT5ody5uamV0Lmxhc3RfaXMwICYgTkVUSkVUX0lSUU0wX1JFQUQpKQoJCQkvKiB3ZSBoYXZlIGEgcmVhZCBkbWEgaW50ICovCgkJCXJlYWRfdGlnZXIoY3MpOwoJCWlmICgoY3MtPmh3Lm5qZXQuaXJxc3RhdDAgJiBORVRKRVRfSVJRTTBfV1JJVEUpICE9CgkJCShjcy0+aHcubmpldC5sYXN0X2lzMCAmIE5FVEpFVF9JUlFNMF9XUklURSkpCgkJCS8qIHdlIGhhdmUgYSB3cml0ZSBkbWEgaW50ICovCgkJCXdyaXRlX3RpZ2VyKGNzKTsKCQl0ZXN0X2FuZF9jbGVhcl9iaXQoRkxHX0xPQ0tfQVRPTUlDLCAmY3MtPkhXX0ZsYWdzKTsKCX0KCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmNzLT5sb2NrLCBmbGFncyk7CglyZXR1cm4gSVJRX0hBTkRMRUQ7Cn0KCnN0YXRpYyBpbnQgX19kZXZpbml0IGVuX3BjaV9wcm9iZShzdHJ1Y3QgcGNpX2RldiAqZGV2X25ldGpldCwKCQkJCSAgc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzKQp7CglpZiAocGNpX2VuYWJsZV9kZXZpY2UoZGV2X25ldGpldCkpCgkJcmV0dXJuKDApOwoJY3MtPmlycSA9IGRldl9uZXRqZXQtPmlycTsKCWlmICghY3MtPmlycSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImVudGVyOm5vdyBQQ0k6IE5vIElSUSBmb3IgUENJIGNhcmQgZm91bmRcbiIpOwoJCXJldHVybigwKTsKCX0KCWNzLT5ody5uamV0LmJhc2UgPSBwY2lfcmVzb3VyY2Vfc3RhcnQoZGV2X25ldGpldCwgMCk7CglpZiAoIWNzLT5ody5uamV0LmJhc2UpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJlbnRlcjpub3cgUENJOiBObyBJTy1BZHIgZm9yIFBDSSBjYXJkIGZvdW5kXG4iKTsKCQlyZXR1cm4oMCk7Cgl9CgkvKiBjaGVja3MgU3ViLVZlbmRvciBJRCBiZWNhdXNlIHN5c3RlbSBjcmFzaGVzIHdpdGggVHJhdmVyc2UtQ2FyZCAqLwoJaWYgKChkZXZfbmV0amV0LT5zdWJzeXN0ZW1fdmVuZG9yICE9IDB4NTUpIHx8CgkgICAgKGRldl9uZXRqZXQtPnN1YnN5c3RlbV9kZXZpY2UgIT0gMHgwMikpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJlbnRlcjpub3c6IFlvdSB0cmllZCB0byBsb2FkIHRoaXMgZHJpdmVyIHdpdGggYW4gaW5jb21wYXRpYmxlIFRpZ2VySmV0LWNhcmRcbiIpOwoJCXByaW50ayhLRVJOX1dBUk5JTkcgIlVzZSB0eXBlPTIwIGZvciBUcmF2ZXJzZSBOZXRKZXQgUENJIENhcmQuXG4iKTsKCQlyZXR1cm4oMCk7Cgl9CgoJcmV0dXJuKDEpOwp9CgpzdGF0aWMgdm9pZCBfX2RldmluaXQgZW5fY3NfaW5pdChzdHJ1Y3QgSXNkbkNhcmQgKmNhcmQsCgkJCQkgc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzKQp7Cgljcy0+aHcubmpldC5hdXhhID0gY3MtPmh3Lm5qZXQuYmFzZSArIE5FVEpFVF9BVVhEQVRBOwoJY3MtPmh3Lm5qZXQuaXNhYyA9IGNzLT5ody5uamV0LmJhc2UgKyAweEMwOyAvLyBGZW5zdGVyIHp1bSBBTUQKCgkvKiBSZXNldCBhbiAqLwoJY3MtPmh3Lm5qZXQuY3RybF9yZWcgPSAweDA3OyAgLy8gZ2XkbmRlcnQgdm9uIDB4ZmYKCW91dGIoY3MtPmh3Lm5qZXQuY3RybF9yZWcsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQ1RSTCk7CgkvKiAyMCBtcyBQYXVzZSAqLwoJbWRlbGF5KDIwKTsKCgljcy0+aHcubmpldC5jdHJsX3JlZyA9IDB4MzA7ICAvKiBSZXNldCBPZmYgYW5kIHN0YXR1cyByZWFkIGNsZWFyICovCglvdXRiKGNzLT5ody5uamV0LmN0cmxfcmVnLCBjcy0+aHcubmpldC5iYXNlICsgTkVUSkVUX0NUUkwpOwoJbWRlbGF5KDEwKTsKCgljcy0+aHcubmpldC5hdXhkID0gMHgwMDsgLy8gd2FyIDB4YzAKCWNzLT5ody5uamV0LmRtYWN0cmwgPSAwOwoKCW91dGIoflRKX0FNRF9JUlEsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfQVVYQ1RSTCk7CglvdXRiKFRKX0FNRF9JUlEsIGNzLT5ody5uamV0LmJhc2UgKyBORVRKRVRfSVJRTUFTSzEpOwoJb3V0Yihjcy0+aHcubmpldC5hdXhkLCBjcy0+aHcubmpldC5hdXhhKTsKfQoKc3RhdGljIGludCBfX2RldmluaXQgZW5fY3NfaW5pdF9yZXN0KHN0cnVjdCBJc2RuQ2FyZCAqY2FyZCwKCQkJCSAgICAgc3RydWN0IElzZG5DYXJkU3RhdGUgKmNzKQp7Cgljb25zdCBpbnQgYnl0ZWNudCA9IDI1NjsKCglwcmludGsoS0VSTl9JTkZPCgkJImVudGVyOm5vdyBQQ0k6IFBDSSBjYXJkIGNvbmZpZ3VyZWQgYXQgMHglbHggSVJRICVkXG4iLAoJCWNzLT5ody5uamV0LmJhc2UsIGNzLT5pcnEpOwoJaWYgKCFyZXF1ZXN0X3JlZ2lvbihjcy0+aHcubmpldC5iYXNlLCBieXRlY250LCAiRm5fSVNETiIpKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORwoJCSAgICAgICAiSGlTYXg6IGVudGVyOm5vdyBjb25maWcgcG9ydCAlbHgtJWx4IGFscmVhZHkgaW4gdXNlXG4iLAoJCSAgICAgICBjcy0+aHcubmpldC5iYXNlLAoJCSAgICAgICBjcy0+aHcubmpldC5iYXNlICsgYnl0ZWNudCk7CgkJcmV0dXJuICgwKTsKCX0KCglzZXR1cF9BbWQ3OTMwKGNzKTsKCWNzLT5ody5uamV0Lmxhc3RfaXMwID0gMDsKICAgICAgICAvKiBtYWNybyByQnl0ZUFNRCAqLwogICAgICAgIGNzLT5yZWFkaXNhYyA9ICZSZWFkQnl0ZUFtZDc5MzA7CiAgICAgICAgLyogbWFjcm8gd0J5dGVBTUQgKi8KICAgICAgICBjcy0+d3JpdGVpc2FjID0gJldyaXRlQnl0ZUFtZDc5MzA7CiAgICAgICAgY3MtPmRjLmFtZDc5MzAuc2V0SXJxTWFzayA9ICZlbnBjaV9zZXRJcnFNYXNrOwoKICAgICAgICBjcy0+QkNfUmVhZF9SZWcgID0gJmR1bW15cnI7Cgljcy0+QkNfV3JpdGVfUmVnID0gJmR1bW15d3I7Cgljcy0+QkNfU2VuZF9EYXRhID0gJm5ldGpldF9maWxsX2RtYTsKCWNzLT5jYXJkbXNnID0gJmVucGNpX2NhcmRfbXNnOwoJY3MtPmlycV9mdW5jID0gJmVucGNpX2ludGVycnVwdDsKCWNzLT5pcnFfZmxhZ3MgfD0gSVJRRl9TSEFSRUQ7CgoJcmV0dXJuICgxKTsKfQoKc3RhdGljIHN0cnVjdCBwY2lfZGV2ICpkZXZfbmV0amV0IF9fZGV2aW5pdGRhdGEgPSBOVUxMOwoKLyogY2FsbGVkIGJ5IGNvbmZpZy5jICovCmludCBfX2RldmluaXQKc2V0dXBfZW50ZXJub3dfcGNpKHN0cnVjdCBJc2RuQ2FyZCAqY2FyZCkKewoJaW50IHJldDsKCXN0cnVjdCBJc2RuQ2FyZFN0YXRlICpjcyA9IGNhcmQtPmNzOwoJY2hhciB0bXBbNjRdOwoKI2lmZGVmIF9fQklHX0VORElBTgojZXJyb3IgIm5vdCBydW5uaW5nIG9uIGJpZyBlbmRpYW4gbWFjaGluZXMgbm93IgojZW5kaWYKCiAgICAgICAgc3RyY3B5KHRtcCwgZW50ZXJub3dfcGNpX3Jldik7CglwcmludGsoS0VSTl9JTkZPICJIaVNheDogRm9ybXVsYS1uIEV1cm9wZSBBRyBlbnRlcjpub3cgSVNETiBQQ0kgZHJpdmVyIFJldi4gJXNcbiIsIEhpU2F4X2dldHJldih0bXApKTsKCWlmIChjcy0+dHlwICE9IElTRE5fQ1RZUEVfRU5URVJOT1cpCgkJcmV0dXJuKDApOwoJdGVzdF9hbmRfY2xlYXJfYml0KEZMR19MT0NLX0FUT01JQywgJmNzLT5IV19GbGFncyk7CgoJZm9yICggOzsgKQoJewoJCWlmICgoZGV2X25ldGpldCA9IGhpc2F4X2ZpbmRfcGNpX2RldmljZShQQ0lfVkVORE9SX0lEX1RJR0VSSkVULAoJCQlQQ0lfREVWSUNFX0lEX1RJR0VSSkVUXzMwMCwgIGRldl9uZXRqZXQpKSkgewoJCQlyZXQgPSBlbl9wY2lfcHJvYmUoZGV2X25ldGpldCwgY3MpOwoJCQlpZiAoIXJldCkKCQkJCXJldHVybigwKTsKCQl9IGVsc2UgewogICAgICAgICAgICAgICAgICAgICAgICBwcmludGsoS0VSTl9XQVJOSU5HICJlbnRlcjpub3cgUENJOiBObyBQQ0kgY2FyZCBmb3VuZFxuIik7CgkJCXJldHVybigwKTsKCQl9CgoJCWVuX2NzX2luaXQoY2FyZCwgY3MpOwoJCWJyZWFrOwoJfQoKICAgICAgICByZXR1cm4gZW5fY3NfaW5pdF9yZXN0KGNhcmQsIGNzKTsKfQo=