LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiAgICAgICAgICAgICAgICAKICogRmlsZW5hbWU6ICAgICAgaXJ0dHktc2lyLmMKICogVmVyc2lvbjogICAgICAgMi4wCiAqIERlc2NyaXB0aW9uOiAgIElyREEgbGluZSBkaXNjaXBsaW5lIGltcGxlbWVudGF0aW9uCiAqIFN0YXR1czogICAgICAgIEV4cGVyaW1lbnRhbC4KICogQXV0aG9yOiAgICAgICAgRGFnIEJyYXR0bGkgPGRhZ2JAY3MudWl0Lm5vPgogKiBDcmVhdGVkIGF0OiAgICBUdWUgRGVjICA5IDIxOjE4OjM4IDE5OTcKICogTW9kaWZpZWQgYXQ6ICAgU3VuIE9jdCAyNyAyMjoxMzozMCAyMDAyCiAqIE1vZGlmaWVkIGJ5OiAgIE1hcnRpbiBEaWVobCA8bWFkQG1kaWVobC5kZT4KICogU291cmNlczogICAgICAgc2xpcC5jIGJ5IExhdXJlbmNlIEN1bGhhbmUsICAgPGxvekBob2xtZXMuZGVtb24uY28udWs+CiAqICAgICAgICAgICAgICAgICAgICAgICAgICBGcmVkIE4uIHZhbiBLZW1wZW4sIDx3YWx0amVAdXdhbHQubmwubXVnbmV0Lm9yZz4KICogCiAqICAgICBDb3B5cmlnaHQgKGMpIDE5OTgtMjAwMCBEYWcgQnJhdHRsaSwKICogICAgIENvcHlyaWdodCAoYykgMjAwMiBNYXJ0aW4gRGllaGwsCiAqICAgICBBbGwgUmlnaHRzIFJlc2VydmVkLgogKiAgICAgIAogKiAgICAgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciAKICogICAgIG1vZGlmeSBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIAogKiAgICAgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgCiAqICAgICB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICogIAogKiAgICAgTmVpdGhlciBEYWcgQnJhdHRsaSBub3IgVW5pdmVyc2l0eSBvZiBUcm9tc/ggYWRtaXQgbGlhYmlsaXR5IG5vcgogKiAgICAgcHJvdmlkZSB3YXJyYW50eSBmb3IgYW55IG9mIHRoaXMgc29mdHdhcmUuIFRoaXMgbWF0ZXJpYWwgaXMgCiAqICAgICBwcm92aWRlZCAiQVMtSVMiIGFuZCBhdCBubyBjaGFyZ2UuCiAqICAgICAKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLyAgICAKCiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgojaW5jbHVkZSA8bGludXgvdHR5Lmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgojaW5jbHVkZSA8bGludXgvc21wX2xvY2suaD4KI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CgojaW5jbHVkZSA8bmV0L2lyZGEvaXJkYS5oPgojaW5jbHVkZSA8bmV0L2lyZGEvaXJkYV9kZXZpY2UuaD4KCiNpbmNsdWRlICJzaXItZGV2LmgiCiNpbmNsdWRlICJpcnR0eS1zaXIuaCIKCnN0YXRpYyBpbnQgcW9zX210dF9iaXRzID0gMHgwMzsgICAgICAvKiA1IG1zIG9yIG1vcmUgKi8KCm1vZHVsZV9wYXJhbShxb3NfbXR0X2JpdHMsIGludCwgMCk7Ck1PRFVMRV9QQVJNX0RFU0MocW9zX210dF9iaXRzLCAiTWluaW11bSBUdXJuIFRpbWUiKTsKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCi8qIGRldmljZSBjb25maWd1cmF0aW9uIGNhbGxiYWNrcyBhbHdheXMgaW52b2tlZCB3aXRoIGlyZGEtdGhyZWFkIGNvbnRleHQgKi8KCi8qIGZpbmQgb3V0LCBob3cgbWFueSBjaGFycyB3ZSBoYXZlIGluIGJ1ZmZlcnMgYmVsb3cgdXMKICogdGhpcyBpcyBhbGxvd2VkIHRvIGxpZSwgaS5lLiByZXR1cm4gbGVzcyBjaGFycyB0aGFuIHdlCiAqIGFjdHVhbGx5IGhhdmUuIFRoZSByZXR1cm5lZCB2YWx1ZSBpcyB1c2VkIHRvIGRldGVybWluZQogKiBob3cgbG9uZyB0aGUgaXJkYXRocmVhZCBzaG91bGQgd2FpdCBiZWZvcmUgZG9pbmcgdGhlCiAqIHJlYWwgYmxvY2tpbmcgd2FpdF91bnRpbF9zZW50KCkKICovCgpzdGF0aWMgaW50IGlydHR5X2NoYXJzX2luX2J1ZmZlcihzdHJ1Y3Qgc2lyX2RldiAqZGV2KQp7CglzdHJ1Y3Qgc2lydHR5X2NiICpwcml2ID0gZGV2LT5wcml2OwoKCUlSREFfQVNTRVJUKHByaXYgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChwcml2LT5tYWdpYyA9PSBJUlRUWV9NQUdJQywgcmV0dXJuIC0xOyk7CgoJcmV0dXJuIHByaXYtPnR0eS0+ZHJpdmVyLT5jaGFyc19pbl9idWZmZXIocHJpdi0+dHR5KTsKfQoKLyogV2FpdCAoc2xlZXApIHVudGlsIHVuZGVybGF5aW5nIGhhcmR3YXJlIGZpbmlzaGVkIHRyYW5zbWlzc2lvbgogKiBpLmUuIGhhcmR3YXJlIGJ1ZmZlcnMgYXJlIGRyYWluZWQKICogdGhpcyBtdXN0IGJsb2NrIGFuZCBub3QgcmV0dXJuIGJlZm9yZSBhbGwgY2hhcmFjdGVycyBhcmUgcmVhbGx5IHNlbnQKICoKICogSWYgdGhlIHR0eSBzaXRzIG9uIHRvcCBvZiBhIDE2NTUwQS1saWtlIHVhcnQsIHRoZXJlIGFyZSB0eXBpY2FsbHkKICogdXAgdG8gMTYgYnl0ZXMgaW4gdGhlIGZpZm8gLSBmLmUuIDk2MDAgYnBzIDhOMSBuZWVkcyAxNi43IG1zZWMKICoKICogV2l0aCB1c2JzZXJpYWwgdGhlIHVhcnQtZmlmbyBpcyBiYXNpY2FsbHkgcmVwbGFjZWQgYnkgdGhlIGNvbnZlcnRlcidzCiAqIG91dGdvaW5nIGVuZHBvaW50IGJ1ZmZlciwgd2hpY2ggY2FuIHVzdWFsbHkgaG9sZCA2NCBieXRlcyAoYXQgbGVhc3QpLgogKiBXaXRoIHBsMjMwMyBpdCBhcHBlYXJzIHdlIGFyZSBzYWZlIHdpdGggNjBtc2VjIGhlcmUuCiAqCiAqIEkgcmVhbGx5IHdpc2ggYWxsIHNlcmlhbCBkcml2ZXJzIHdvdWxkIHByb3ZpZGUKICogY29ycmVjdCBpbXBsZW1lbnRhdGlvbiBvZiB3YWl0X3VudGlsX3NlbnQoKQogKi8KCiNkZWZpbmUgVVNCU0VSSUFMX1RYX0RPTkVfREVMQVkJNjAKCnN0YXRpYyB2b2lkIGlydHR5X3dhaXRfdW50aWxfc2VudChzdHJ1Y3Qgc2lyX2RldiAqZGV2KQp7CglzdHJ1Y3Qgc2lydHR5X2NiICpwcml2ID0gZGV2LT5wcml2OwoJc3RydWN0IHR0eV9zdHJ1Y3QgKnR0eTsKCglJUkRBX0FTU0VSVChwcml2ICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQocHJpdi0+bWFnaWMgPT0gSVJUVFlfTUFHSUMsIHJldHVybjspOwoKCXR0eSA9IHByaXYtPnR0eTsKCWlmICh0dHktPmRyaXZlci0+d2FpdF91bnRpbF9zZW50KSB7CgkJbG9ja19rZXJuZWwoKTsKCQl0dHktPmRyaXZlci0+d2FpdF91bnRpbF9zZW50KHR0eSwgbXNlY3NfdG9famlmZmllcygxMDApKTsKCQl1bmxvY2tfa2VybmVsKCk7Cgl9CgllbHNlIHsKCQltc2xlZXAoVVNCU0VSSUFMX1RYX0RPTkVfREVMQVkpOwoJfQp9CgovKiAKICogIEZ1bmN0aW9uIGlydHR5X2NoYW5nZV9zcGVlZCAoZGV2LCBzcGVlZCkKICoKICogICAgQ2hhbmdlIHRoZSBzcGVlZCBvZiB0aGUgc2VyaWFsIHBvcnQuCiAqCiAqIFRoaXMgbWF5IHNsZWVwIGluIHNldF90ZXJtaW9zICh1c2JzZXJpYWwgZHJpdmVyIGYuZS4pIGFuZCBtdXN0CiAqIG5vdCBiZSBjYWxsZWQgZnJvbSBpbnRlcnJ1cHQvdGltZXIvdGFza2xldCB0aGVyZWZvcmUuCiAqIEFsbCBzdWNoIGludm9jYXRpb25zIGFyZSBkZWZlcnJlZCB0byBrSXJEQWQgbm93IHNvIHdlIGNhbiBzbGVlcCB0aGVyZS4KICovCgpzdGF0aWMgaW50IGlydHR5X2NoYW5nZV9zcGVlZChzdHJ1Y3Qgc2lyX2RldiAqZGV2LCB1bnNpZ25lZCBzcGVlZCkKewoJc3RydWN0IHNpcnR0eV9jYiAqcHJpdiA9IGRldi0+cHJpdjsKCXN0cnVjdCB0dHlfc3RydWN0ICp0dHk7CiAgICAgICAgc3RydWN0IHRlcm1pb3Mgb2xkX3Rlcm1pb3M7CglpbnQgY2ZsYWc7CgoJSVJEQV9BU1NFUlQocHJpdiAhPSBOVUxMLCByZXR1cm4gLTE7KTsKCUlSREFfQVNTRVJUKHByaXYtPm1hZ2ljID09IElSVFRZX01BR0lDLCByZXR1cm4gLTE7KTsKCgl0dHkgPSBwcml2LT50dHk7CgoJbG9ja19rZXJuZWwoKTsKCW9sZF90ZXJtaW9zID0gKih0dHktPnRlcm1pb3MpOwoJY2ZsYWcgPSB0dHktPnRlcm1pb3MtPmNfY2ZsYWc7CgoJY2ZsYWcgJj0gfkNCQVVEOwoKCUlSREFfREVCVUcoMiwgIiVzKCksIFNldHRpbmcgc3BlZWQgdG8gJWRcbiIsIF9fRlVOQ1RJT05fXywgc3BlZWQpOwoKCXN3aXRjaCAoc3BlZWQpIHsKCWNhc2UgMTIwMDoKCQljZmxhZyB8PSBCMTIwMDsKCQlicmVhazsKCWNhc2UgMjQwMDoKCQljZmxhZyB8PSBCMjQwMDsKCQlicmVhazsKCWNhc2UgNDgwMDoKCQljZmxhZyB8PSBCNDgwMDsKCQlicmVhazsKCWNhc2UgMTkyMDA6CgkJY2ZsYWcgfD0gQjE5MjAwOwoJCWJyZWFrOwoJY2FzZSAzODQwMDoKCQljZmxhZyB8PSBCMzg0MDA7CgkJYnJlYWs7CgljYXNlIDU3NjAwOgoJCWNmbGFnIHw9IEI1NzYwMDsKCQlicmVhazsKCWNhc2UgMTE1MjAwOgoJCWNmbGFnIHw9IEIxMTUyMDA7CgkJYnJlYWs7CgljYXNlIDk2MDA6CglkZWZhdWx0OgoJCWNmbGFnIHw9IEI5NjAwOwoJCWJyZWFrOwoJfQkKCgl0dHktPnRlcm1pb3MtPmNfY2ZsYWcgPSBjZmxhZzsKCWlmICh0dHktPmRyaXZlci0+c2V0X3Rlcm1pb3MpCgkJdHR5LT5kcml2ZXItPnNldF90ZXJtaW9zKHR0eSwgJm9sZF90ZXJtaW9zKTsKCXVubG9ja19rZXJuZWwoKTsKCglwcml2LT5pby5zcGVlZCA9IHNwZWVkOwoKCXJldHVybiAwOwp9CgovKgogKiBGdW5jdGlvbiBpcnR0eV9zZXRfZHRyX3J0cyAoZGV2LCBkdHIsIHJ0cykKICoKICogICAgVGhpcyBmdW5jdGlvbiBjYW4gYmUgdXNlZCBieSBkb25nbGVzIGV0Yy4gdG8gc2V0IG9yIHJlc2V0IHRoZSBzdGF0dXMKICogICAgb2YgdGhlIGR0ciBhbmQgcnRzIGxpbmVzCiAqLwoKc3RhdGljIGludCBpcnR0eV9zZXRfZHRyX3J0cyhzdHJ1Y3Qgc2lyX2RldiAqZGV2LCBpbnQgZHRyLCBpbnQgcnRzKQp7CglzdHJ1Y3Qgc2lydHR5X2NiICpwcml2ID0gZGV2LT5wcml2OwoJaW50IHNldCA9IDA7CglpbnQgY2xlYXIgPSAwOwoKCUlSREFfQVNTRVJUKHByaXYgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CglJUkRBX0FTU0VSVChwcml2LT5tYWdpYyA9PSBJUlRUWV9NQUdJQywgcmV0dXJuIC0xOyk7CgoJaWYgKHJ0cykKCQlzZXQgfD0gVElPQ01fUlRTOwoJZWxzZQoJCWNsZWFyIHw9IFRJT0NNX1JUUzsKCWlmIChkdHIpCgkJc2V0IHw9IFRJT0NNX0RUUjsKCWVsc2UKCQljbGVhciB8PSBUSU9DTV9EVFI7CgoJLyoKCSAqIFdlIGNhbid0IHVzZSBpb2N0bCgpIGJlY2F1c2UgaXQgZXhwZWN0cyBhIG5vbi1udWxsIGZpbGUgc3RydWN0dXJlLAoJICogYW5kIHdlIGRvbid0IGhhdmUgdGhhdCBoZXJlLgoJICogVGhpcyBmdW5jdGlvbiBpcyBub3QgeWV0IGRlZmluZWQgZm9yIGFsbCB0dHkgZHJpdmVyLCBzbwoJICogbGV0J3MgYmUgY2FyZWZ1bC4uLiBKZWFuIElJCgkgKi8KCUlSREFfQVNTRVJUKHByaXYtPnR0eS0+ZHJpdmVyLT50aW9jbXNldCAhPSBOVUxMLCByZXR1cm4gLTE7KTsKCXByaXYtPnR0eS0+ZHJpdmVyLT50aW9jbXNldChwcml2LT50dHksIE5VTEwsIHNldCwgY2xlYXIpOwoKCXJldHVybiAwOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiBjYWxsZWQgZnJvbSBzaXJfZGV2IHdoZW4gdGhlcmUgaXMgbW9yZSBkYXRhIHRvIHNlbmQKICogY29udGV4dCBpcyBlaXRoZXIgbmV0ZGV2LT5oYXJkX3htaXQgb3Igc29tZSB0cmFuc21pdC1jb21wbGV0aW9uIGJoCiAqIGkuZS4gd2UgYXJlIHVuZGVyIHNwaW5sb2NrIGhlcmUgYW5kIG11c3Qgbm90IHNsZWVwLgogKi8KCnN0YXRpYyBpbnQgaXJ0dHlfZG9fd3JpdGUoc3RydWN0IHNpcl9kZXYgKmRldiwgY29uc3QgdW5zaWduZWQgY2hhciAqcHRyLCBzaXplX3QgbGVuKQp7CglzdHJ1Y3Qgc2lydHR5X2NiICpwcml2ID0gZGV2LT5wcml2OwoJc3RydWN0IHR0eV9zdHJ1Y3QgKnR0eTsKCWludCB3cml0ZWxlbjsKCglJUkRBX0FTU0VSVChwcml2ICE9IE5VTEwsIHJldHVybiAtMTspOwoJSVJEQV9BU1NFUlQocHJpdi0+bWFnaWMgPT0gSVJUVFlfTUFHSUMsIHJldHVybiAtMTspOwoKCXR0eSA9IHByaXYtPnR0eTsKCWlmICghdHR5LT5kcml2ZXItPndyaXRlKQoJCXJldHVybiAwOwoJdHR5LT5mbGFncyB8PSAoMSA8PCBUVFlfRE9fV1JJVEVfV0FLRVVQKTsKCWlmICh0dHktPmRyaXZlci0+d3JpdGVfcm9vbSkgewoJCXdyaXRlbGVuID0gdHR5LT5kcml2ZXItPndyaXRlX3Jvb20odHR5KTsKCQlpZiAod3JpdGVsZW4gPiBsZW4pCgkJCXdyaXRlbGVuID0gbGVuOwoJfQoJZWxzZQoJCXdyaXRlbGVuID0gbGVuOwoJcmV0dXJuIHR0eS0+ZHJpdmVyLT53cml0ZSh0dHksIHB0ciwgd3JpdGVsZW4pOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiBpcmRhIGxpbmUgZGlzY2lwbGluZSBjYWxsYmFja3MgKi8KCi8qIAogKiAgRnVuY3Rpb24gaXJ0dHlfcmVjZWl2ZV9idWYoIHR0eSwgY3AsIGNvdW50KQogKgogKiAgICBIYW5kbGUgdGhlICdyZWNlaXZlciBkYXRhIHJlYWR5JyBpbnRlcnJ1cHQuICBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZAogKiAgICBieSB0aGUgJ3R0eV9pbycgbW9kdWxlIGluIHRoZSBrZXJuZWwgd2hlbiBhIGJsb2NrIG9mIElyREEgZGF0YSBoYXMKICogICAgYmVlbiByZWNlaXZlZCwgd2hpY2ggY2FuIG5vdyBiZSBkZWNhcHN1bGF0ZWQgYW5kIGRlbGl2ZXJlZCBmb3IKICogICAgZnVydGhlciBwcm9jZXNzaW5nIAogKgogKiBjYWxsaW5nIGNvbnRleHQgZGVwZW5kcyBvbiB1bmRlcmx5aW5nIGRyaXZlciBhbmQgdHR5LT5sb3dfbGF0ZW5jeSEKICogZm9yIGV4YW1wbGUgKGxvd19sYXRlbmN5OiAxIC8gMCk6CiAqIHNlcmlhbC5jOgl1YXJ0LWludGVycnVwdCAvIHNvZnRpbnQKICogdXNic2VyaWFsOgl1cmItY29tcGxldGUtaW50ZXJydXB0IC8gc29mdGludAogKi8KCnN0YXRpYyB2b2lkIGlydHR5X3JlY2VpdmVfYnVmKHN0cnVjdCB0dHlfc3RydWN0ICp0dHksIGNvbnN0IHVuc2lnbmVkIGNoYXIgKmNwLAoJCQkgICAgICBjaGFyICpmcCwgaW50IGNvdW50KSAKewoJc3RydWN0IHNpcl9kZXYgKmRldjsKCXN0cnVjdCBzaXJ0dHlfY2IgKnByaXYgPSB0dHktPmRpc2NfZGF0YTsKCWludAlpOwoKCUlSREFfQVNTRVJUKHByaXYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChwcml2LT5tYWdpYyA9PSBJUlRUWV9NQUdJQywgcmV0dXJuOyk7CgoJaWYgKHVubGlrZWx5KGNvdW50PT0wKSkJCS8qIHllcywgdGhpcyBoYXBwZW5zICovCgkJcmV0dXJuOwoKCWRldiA9IHByaXYtPmRldjsKCWlmICghZGV2KSB7CgkJSVJEQV9XQVJOSU5HKCIlcygpLCBub3QgcmVhZHkgeWV0IVxuIiwgX19GVU5DVElPTl9fKTsKCQlyZXR1cm47Cgl9CgoJZm9yIChpID0gMDsgaSA8IGNvdW50OyBpKyspIHsKCQkvKiAKCQkgKiAgQ2hhcmFjdGVycyByZWNlaXZlZCB3aXRoIGEgcGFyaXR5IGVycm9yLCBldGM/CgkJICovCiAJCWlmIChmcCAmJiAqZnArKykgeyAKCQkJSVJEQV9ERUJVRygwLCAiRnJhbWluZyBvciBwYXJpdHkgZXJyb3IhXG4iKTsKCQkJc2lyZGV2X3JlY2VpdmUoZGV2LCBOVUxMLCAwKTsJLyogbm90aWZ5IHNpcl9kZXYgKHVwZGF0aW5nIHN0YXRzKSAqLwoJCQlyZXR1cm47CiAJCX0KCX0KCglzaXJkZXZfcmVjZWl2ZShkZXYsIGNwLCBjb3VudCk7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlydHR5X3JlY2VpdmVfcm9vbSAodHR5KQogKgogKiAgICBVc2VkIGJ5IHRoZSBUVFkgdG8gZmluZCBvdXQgaG93IG11Y2ggZGF0YSB3ZSBjYW4gcmVjZWl2ZSBhdCBhIHRpbWUKICogCiovCnN0YXRpYyBpbnQgaXJ0dHlfcmVjZWl2ZV9yb29tKHN0cnVjdCB0dHlfc3RydWN0ICp0dHkpIAp7CglzdHJ1Y3Qgc2lydHR5X2NiICpwcml2ID0gdHR5LT5kaXNjX2RhdGE7CgoJSVJEQV9BU1NFUlQocHJpdiAhPSBOVUxMLCByZXR1cm4gMDspOwoJSVJEQV9BU1NFUlQocHJpdi0+bWFnaWMgPT0gSVJUVFlfTUFHSUMsIHJldHVybiAwOyk7CgoJcmV0dXJuIDY1NTM2OyAgLyogV2UgY2FuIGhhbmRsZSBhbiBpbmZpbml0ZSBhbW91bnQgb2YgZGF0YS4gOi0pICovCn0KCi8qCiAqIEZ1bmN0aW9uIGlydHR5X3dyaXRlX3dha2V1cCAodHR5KQogKgogKiAgICBDYWxsZWQgYnkgdGhlIGRyaXZlciB3aGVuIHRoZXJlJ3Mgcm9vbSBmb3IgbW9yZSBkYXRhLiAgSWYgd2UgaGF2ZQogKiAgICBtb3JlIHBhY2tldHMgdG8gc2VuZCwgd2Ugc2VuZCB0aGVtIGhlcmUuCiAqCiAqLwpzdGF0aWMgdm9pZCBpcnR0eV93cml0ZV93YWtldXAoc3RydWN0IHR0eV9zdHJ1Y3QgKnR0eSkgCnsKCXN0cnVjdCBzaXJ0dHlfY2IgKnByaXYgPSB0dHktPmRpc2NfZGF0YTsKCglJUkRBX0FTU0VSVChwcml2ICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQocHJpdi0+bWFnaWMgPT0gSVJUVFlfTUFHSUMsIHJldHVybjspOwoKCXR0eS0+ZmxhZ3MgJj0gfigxIDw8IFRUWV9ET19XUklURV9XQUtFVVApOwoKCWlmIChwcml2LT5kZXYpCgkJc2lyZGV2X3dyaXRlX2NvbXBsZXRlKHByaXYtPmRldik7Cn0KCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KCi8qCiAqIEZ1bmN0aW9uIGlydHR5X3N0b3BfcmVjZWl2ZXIgKHR0eSwgc3RvcCkKICoKICovCgpzdGF0aWMgaW5saW5lIHZvaWQgaXJ0dHlfc3RvcF9yZWNlaXZlcihzdHJ1Y3QgdHR5X3N0cnVjdCAqdHR5LCBpbnQgc3RvcCkKewoJc3RydWN0IHRlcm1pb3Mgb2xkX3Rlcm1pb3M7CglpbnQgY2ZsYWc7CgoJbG9ja19rZXJuZWwoKTsKCW9sZF90ZXJtaW9zID0gKih0dHktPnRlcm1pb3MpOwoJY2ZsYWcgPSB0dHktPnRlcm1pb3MtPmNfY2ZsYWc7CgkKCWlmIChzdG9wKQoJCWNmbGFnICY9IH5DUkVBRDsKCWVsc2UKCQljZmxhZyB8PSBDUkVBRDsKCgl0dHktPnRlcm1pb3MtPmNfY2ZsYWcgPSBjZmxhZzsKCWlmICh0dHktPmRyaXZlci0+c2V0X3Rlcm1pb3MpCgkJdHR5LT5kcml2ZXItPnNldF90ZXJtaW9zKHR0eSwgJm9sZF90ZXJtaW9zKTsKCXVubG9ja19rZXJuZWwoKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKLyogc2VyaWFsaXplIGxkaXNjIG9wZW4vY2xvc2Ugd2l0aCBzaXJfZGV2ICovCnN0YXRpYyBERUNMQVJFX01VVEVYKGlydHR5X3NlbSk7CgovKiBub3RpZmllciBmcm9tIHNpcl9kZXYgd2hlbiBpcmRhJSBkZXZpY2UgZ2V0cyBvcGVuZWQgKGlmdXApICovCgpzdGF0aWMgaW50IGlydHR5X3N0YXJ0X2RldihzdHJ1Y3Qgc2lyX2RldiAqZGV2KQp7CglzdHJ1Y3Qgc2lydHR5X2NiICpwcml2OwoJc3RydWN0IHR0eV9zdHJ1Y3QgKnR0eTsKCgkvKiBzZXJpYWxpemUgd2l0aCBsZGlzYyBvcGVuL2Nsb3NlICovCglkb3duKCZpcnR0eV9zZW0pOwoKCXByaXYgPSBkZXYtPnByaXY7CglpZiAodW5saWtlbHkoIXByaXYgfHwgcHJpdi0+bWFnaWMhPUlSVFRZX01BR0lDKSkgewoJCXVwKCZpcnR0eV9zZW0pOwoJCXJldHVybiAtRVNUQUxFOwoJfQoKCXR0eSA9IHByaXYtPnR0eTsKCglpZiAodHR5LT5kcml2ZXItPnN0YXJ0KQoJCXR0eS0+ZHJpdmVyLT5zdGFydCh0dHkpOwoJLyogTWFrZSBzdXJlIHdlIGNhbiByZWNlaXZlIG1vcmUgZGF0YSAqLwoJaXJ0dHlfc3RvcF9yZWNlaXZlcih0dHksIEZBTFNFKTsKCgl1cCgmaXJ0dHlfc2VtKTsKCXJldHVybiAwOwp9CgovKiBub3RpZmllciBmcm9tIHNpcl9kZXYgd2hlbiBpcmRhJSBkZXZpY2UgZ2V0cyBjbG9zZWQgKGlmZG93bikgKi8KCnN0YXRpYyBpbnQgaXJ0dHlfc3RvcF9kZXYoc3RydWN0IHNpcl9kZXYgKmRldikKewoJc3RydWN0IHNpcnR0eV9jYiAqcHJpdjsKCXN0cnVjdCB0dHlfc3RydWN0ICp0dHk7CgoJLyogc2VyaWFsaXplIHdpdGggbGRpc2Mgb3Blbi9jbG9zZSAqLwoJZG93bigmaXJ0dHlfc2VtKTsKCglwcml2ID0gZGV2LT5wcml2OwoJaWYgKHVubGlrZWx5KCFwcml2IHx8IHByaXYtPm1hZ2ljIT1JUlRUWV9NQUdJQykpIHsKCQl1cCgmaXJ0dHlfc2VtKTsKCQlyZXR1cm4gLUVTVEFMRTsKCX0KCgl0dHkgPSBwcml2LT50dHk7CgoJLyogTWFrZSBzdXJlIHdlIGRvbid0IHJlY2VpdmUgbW9yZSBkYXRhICovCglpcnR0eV9zdG9wX3JlY2VpdmVyKHR0eSwgVFJVRSk7CglpZiAodHR5LT5kcml2ZXItPnN0b3ApCgkJdHR5LT5kcml2ZXItPnN0b3AodHR5KTsKCgl1cCgmaXJ0dHlfc2VtKTsKCglyZXR1cm4gMDsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKc3RhdGljIHN0cnVjdCBzaXJfZHJpdmVyIHNpcl90dHlfZHJ2ID0gewoJLm93bmVyCQkJPSBUSElTX01PRFVMRSwKCS5kcml2ZXJfbmFtZQkJPSAic2lyX3R0eSIsCgkuc3RhcnRfZGV2CQk9IGlydHR5X3N0YXJ0X2RldiwKCS5zdG9wX2RldgkJPSBpcnR0eV9zdG9wX2RldiwKCS5kb193cml0ZQkJPSBpcnR0eV9kb193cml0ZSwKCS5jaGFyc19pbl9idWZmZXIJPSBpcnR0eV9jaGFyc19pbl9idWZmZXIsCgkud2FpdF91bnRpbF9zZW50CT0gaXJ0dHlfd2FpdF91bnRpbF9zZW50LAoJLnNldF9zcGVlZAkJPSBpcnR0eV9jaGFuZ2Vfc3BlZWQsCgkuc2V0X2R0cl9ydHMJCT0gaXJ0dHlfc2V0X2R0cl9ydHMsCn07CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKgogKiBGdW5jdGlvbiBpcnR0eV9pb2N0bCAodHR5LCBmaWxlLCBjbWQsIGFyZykKICoKICogICAgIFRoZSBTd2lzcyBhcm15IGtuaWZlIG9mIHN5c3RlbSBjYWxscyA6LSkKICoKICovCnN0YXRpYyBpbnQgaXJ0dHlfaW9jdGwoc3RydWN0IHR0eV9zdHJ1Y3QgKnR0eSwgc3RydWN0IGZpbGUgKmZpbGUsIHVuc2lnbmVkIGludCBjbWQsIHVuc2lnbmVkIGxvbmcgYXJnKQp7CglzdHJ1Y3QgaXJ0dHlfaW5mbyB7IGNoYXIgbmFtZVs2XTsgfSBpbmZvOwoJc3RydWN0IHNpcl9kZXYgKmRldjsKCXN0cnVjdCBzaXJ0dHlfY2IgKnByaXYgPSB0dHktPmRpc2NfZGF0YTsKCWludCBlcnIgPSAwOwoKCUlSREFfQVNTRVJUKHByaXYgIT0gTlVMTCwgcmV0dXJuIC1FTk9ERVY7KTsKCUlSREFfQVNTRVJUKHByaXYtPm1hZ2ljID09IElSVFRZX01BR0lDLCByZXR1cm4gLUVCQURSOyk7CgoJSVJEQV9ERUJVRygzLCAiJXMoY21kPTB4JVgpXG4iLCBfX0ZVTkNUSU9OX18sIGNtZCk7CgoJZGV2ID0gcHJpdi0+ZGV2OwoJSVJEQV9BU1NFUlQoZGV2ICE9IE5VTEwsIHJldHVybiAtMTspOwoKCXN3aXRjaCAoY21kKSB7CgljYXNlIFRDR0VUUzoKCWNhc2UgVENHRVRBOgoJCWVyciA9IG5fdHR5X2lvY3RsKHR0eSwgZmlsZSwgY21kLCBhcmcpOwoJCWJyZWFrOwoKCWNhc2UgSVJUVFlfSU9DVERPTkdMRToKCQkvKiB0aGlzIGNhbGwgYmxvY2tzIGZvciBjb21wbGV0aW9uICovCgkJZXJyID0gc2lyZGV2X3NldF9kb25nbGUoZGV2LCAoSVJEQV9ET05HTEUpIGFyZyk7CgkJYnJlYWs7CgoJY2FzZSBJUlRUWV9JT0NHRVQ6CgkJSVJEQV9BU1NFUlQoZGV2LT5uZXRkZXYgIT0gTlVMTCwgcmV0dXJuIC0xOyk7CgoJCW1lbXNldCgmaW5mbywgMCwgc2l6ZW9mKGluZm8pKTsgCgkJc3RybmNweShpbmZvLm5hbWUsIGRldi0+bmV0ZGV2LT5uYW1lLCBzaXplb2YoaW5mby5uYW1lKS0xKTsKCgkJaWYgKGNvcHlfdG9fdXNlcigodm9pZCBfX3VzZXIgKilhcmcsICZpbmZvLCBzaXplb2YoaW5mbykpKQoJCQllcnIgPSAtRUZBVUxUOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQllcnIgPSAtRU5PSU9DVExDTUQ7CgkJYnJlYWs7Cgl9CglyZXR1cm4gZXJyOwp9CgoKLyogCiAqICBGdW5jdGlvbiBpcnR0eV9vcGVuKHR0eSkKICoKICogICAgVGhpcyBmdW5jdGlvbiBpcyBjYWxsZWQgYnkgdGhlIFRUWSBtb2R1bGUgd2hlbiB0aGUgSXJEQSBsaW5lCiAqICAgIGRpc2NpcGxpbmUgaXMgY2FsbGVkIGZvci4gIEJlY2F1c2Ugd2UgYXJlIHN1cmUgdGhlIHR0eSBsaW5lIGV4aXN0cywKICogICAgd2Ugb25seSBoYXZlIHRvIGxpbmsgaXQgdG8gYSBmcmVlIElyREEgY2hhbm5lbC4gIAogKi8Kc3RhdGljIGludCBpcnR0eV9vcGVuKHN0cnVjdCB0dHlfc3RydWN0ICp0dHkpIAp7CglzdHJ1Y3Qgc2lyX2RldiAqZGV2OwoJc3RydWN0IHNpcnR0eV9jYiAqcHJpdjsKCWludCByZXQgPSAwOwoKCS8qIE1vZHVsZSBzdHVmZiBoYW5kbGVkIHZpYSBpcmRhX2xkaXNjLm93bmVyIC0gSmVhbiBJSSAqLwoKCS8qIEZpcnN0IG1ha2Ugc3VyZSB3ZSdyZSBub3QgYWxyZWFkeSBjb25uZWN0ZWQuICovCglpZiAodHR5LT5kaXNjX2RhdGEgIT0gTlVMTCkgewoJCXByaXYgPSB0dHktPmRpc2NfZGF0YTsKCQlpZiAocHJpdiAmJiBwcml2LT5tYWdpYyA9PSBJUlRUWV9NQUdJQykgewoJCQlyZXQgPSAtRUVYSVNUOwoJCQlnb3RvIG91dDsKCQl9CgkJdHR5LT5kaXNjX2RhdGEgPSBOVUxMOwkJLyogIyMjICovCgl9CgoJLyogc3RvcCB0aGUgdW5kZXJseWluZyAgZHJpdmVyICovCglpcnR0eV9zdG9wX3JlY2VpdmVyKHR0eSwgVFJVRSk7CglpZiAodHR5LT5kcml2ZXItPnN0b3ApCgkJdHR5LT5kcml2ZXItPnN0b3AodHR5KTsKCglpZiAodHR5LT5kcml2ZXItPmZsdXNoX2J1ZmZlcikKCQl0dHktPmRyaXZlci0+Zmx1c2hfYnVmZmVyKHR0eSk7CgkKCS8qIGFwcGx5IG10dCBvdmVycmlkZSAqLwoJc2lyX3R0eV9kcnYucW9zX210dF9iaXRzID0gcW9zX210dF9iaXRzOwoKCS8qIGdldCBhIHNpciBkZXZpY2UgaW5zdGFuY2UgZm9yIHRoaXMgZHJpdmVyICovCglkZXYgPSBzaXJkZXZfZ2V0X2luc3RhbmNlKCZzaXJfdHR5X2RydiwgdHR5LT5uYW1lKTsKCWlmICghZGV2KSB7CgkJcmV0ID0gLUVOT0RFVjsKCQlnb3RvIG91dDsKCX0KCgkvKiBhbGxvY2F0ZSBwcml2YXRlIGRldmljZSBpbmZvIGJsb2NrICovCglwcml2ID0ga21hbGxvYyhzaXplb2YoKnByaXYpLCBHRlBfS0VSTkVMKTsKCWlmICghcHJpdikKCQlnb3RvIG91dF9wdXQ7CgltZW1zZXQocHJpdiwgMCwgc2l6ZW9mKCpwcml2KSk7CgoJcHJpdi0+bWFnaWMgPSBJUlRUWV9NQUdJQzsKCXByaXYtPnR0eSA9IHR0eTsKCXByaXYtPmRldiA9IGRldjsKCgkvKiBzZXJpYWxpemUgd2l0aCBzdGFydF9kZXYgLSBpbiBjYXNlIHdlIHdlcmUgcmFjaW5nIHdpdGggaWZ1cCAqLwoJZG93bigmaXJ0dHlfc2VtKTsKCglkZXYtPnByaXYgPSBwcml2OwoJdHR5LT5kaXNjX2RhdGEgPSBwcml2OwoKCXVwKCZpcnR0eV9zZW0pOwoKCUlSREFfREVCVUcoMCwgIiVzIC0gJXM6IGlyZGEgbGluZSBkaXNjaXBsaW5lIG9wZW5lZFxuIiwgX19GVU5DVElPTl9fLCB0dHktPm5hbWUpOwoKCXJldHVybiAwOwoKb3V0X3B1dDoKCXNpcmRldl9wdXRfaW5zdGFuY2UoZGV2KTsKb3V0OgoJcmV0dXJuIHJldDsKfQoKLyogCiAqICBGdW5jdGlvbiBpcnR0eV9jbG9zZSAodHR5KQogKgogKiAgICBDbG9zZSBkb3duIGEgSXJEQSBjaGFubmVsLiBUaGlzIG1lYW5zIGZsdXNoaW5nIG91dCBhbnkgcGVuZGluZyBxdWV1ZXMsCiAqICAgIGFuZCB0aGVuIHJlc3RvcmluZyB0aGUgVFRZIGxpbmUgZGlzY2lwbGluZSB0byB3aGF0IGl0IHdhcyBiZWZvcmUgaXQgZ290CiAqICAgIGhvb2tlZCB0byBJckRBICh3aGljaCB1c3VhbGx5IGlzIFRUWSBhZ2FpbikuICAKICovCnN0YXRpYyB2b2lkIGlydHR5X2Nsb3NlKHN0cnVjdCB0dHlfc3RydWN0ICp0dHkpIAp7CglzdHJ1Y3Qgc2lydHR5X2NiICpwcml2ID0gdHR5LT5kaXNjX2RhdGE7CgoJSVJEQV9BU1NFUlQocHJpdiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHByaXYtPm1hZ2ljID09IElSVFRZX01BR0lDLCByZXR1cm47KTsKCgkvKiBIbSwgd2l0aCBhIGRvbmdsZSBhdHRhY2hlZCB0aGUgZG9uZ2xlIGRyaXZlciB3YW50cwoJICogdG8gY2xvc2UgdGhlIGRvbmdsZSAtIHdoaWNoIHJlcXVpcmVzIHRoZSB1c2Ugb2YKCSAqIHNvbWUgdHR5IHdyaXRlIGFuZC9vciB0ZXJtaW9zIG9yIGlvY3RsIG9wZXJhdGlvbnMuCgkgKiBBcmUgd2UgYWxsb3dlZCB0byBjYWxsIHRob3NlIHdoZW4gYWxyZWFkeSByZXF1ZXN0ZWQKCSAqIHRvIHNodXRkb3duIHRoZSBsZGlzYz8KCSAqIElmIG5vdCwgd2Ugc2hvdWxkIHNvbWVob3cgbWFyayB0aGUgZGV2IGJlaW5nIHN0YWxlZC4KCSAqIFF1ZXN0aW9uIHJlbWFpbnMsIGhvdyB0byBjbG9zZSB0aGUgZG9uZ2xlIGluIHRoaXMgY2FzZS4uLgoJICogRm9yIG5vdyBsZXQncyBhc3N1bWUgd2UgYXJlIGdyYW50ZWQgdG8gaXNzdWUgdHR5IGRyaXZlciBjYWxscwoJICogdW50aWwgd2UgcmV0dXJuIGhlcmUgZnJvbSB0aGUgbGRpc2MgY2xvc2UuIEknbSBqdXN0IHdvbmRlcmluZwoJICogaG93IHRoaXMgYmVoYXZlcyB3aXRoIGhvdHBsdWdnYWJsZSBzZXJpYWwgaGFyZHdhcmUgbGlrZQoJICogcnMyMzItcGNtY2lhIGNhcmQgb3IgdXNiLXNlcmlhbC4uLgoJICoKCSAqIHByaXYtPnR0eSA9IE5VTEw/OwoJICovCgoJLyogd2UgYXJlIGRlYWQgbm93ICovCgl0dHktPmRpc2NfZGF0YSA9IE5VTEw7CgoJc2lyZGV2X3B1dF9pbnN0YW5jZShwcml2LT5kZXYpOwoKCS8qIFN0b3AgdHR5ICovCglpcnR0eV9zdG9wX3JlY2VpdmVyKHR0eSwgVFJVRSk7Cgl0dHktPmZsYWdzICY9IH4oMSA8PCBUVFlfRE9fV1JJVEVfV0FLRVVQKTsKCWlmICh0dHktPmRyaXZlci0+c3RvcCkKCQl0dHktPmRyaXZlci0+c3RvcCh0dHkpOwoKCWtmcmVlKHByaXYpOwoKCUlSREFfREVCVUcoMCwgIiVzIC0gJXM6IGlyZGEgbGluZSBkaXNjaXBsaW5lIGNsb3NlZFxuIiwgX19GVU5DVElPTl9fLCB0dHktPm5hbWUpOwp9CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpzdGF0aWMgc3RydWN0IHR0eV9sZGlzYyBpcmRhX2xkaXNjID0gewoJLm1hZ2ljCQk9IFRUWV9MRElTQ19NQUdJQywKIAkubmFtZQkJPSAiaXJkYSIsCgkuZmxhZ3MJCT0gMCwKCS5vcGVuCQk9IGlydHR5X29wZW4sCgkuY2xvc2UJCT0gaXJ0dHlfY2xvc2UsCgkucmVhZAkJPSBOVUxMLAoJLndyaXRlCQk9IE5VTEwsCgkuaW9jdGwJCT0gaXJ0dHlfaW9jdGwsCiAJLnBvbGwJCT0gTlVMTCwKCS5yZWNlaXZlX2J1Zgk9IGlydHR5X3JlY2VpdmVfYnVmLAoJLnJlY2VpdmVfcm9vbQk9IGlydHR5X3JlY2VpdmVfcm9vbSwKCS53cml0ZV93YWtldXAJPSBpcnR0eV93cml0ZV93YWtldXAsCgkub3duZXIJCT0gVEhJU19NT0RVTEUsCn07CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpzdGF0aWMgaW50IF9faW5pdCBpcnR0eV9zaXJfaW5pdCh2b2lkKQp7CglpbnQgZXJyOwoKCWlmICgoZXJyID0gdHR5X3JlZ2lzdGVyX2xkaXNjKE5fSVJEQSwgJmlyZGFfbGRpc2MpKSAhPSAwKQoJCUlSREFfRVJST1IoIklyREE6IGNhbid0IHJlZ2lzdGVyIGxpbmUgZGlzY2lwbGluZSAoZXJyID0gJWQpXG4iLAoJCQkgICBlcnIpOwoJcmV0dXJuIGVycjsKfQoKc3RhdGljIHZvaWQgX19leGl0IGlydHR5X3Npcl9jbGVhbnVwKHZvaWQpIAp7CglpbnQgZXJyOwoKCWlmICgoZXJyID0gdHR5X3JlZ2lzdGVyX2xkaXNjKE5fSVJEQSwgTlVMTCkpKSB7CgkJSVJEQV9FUlJPUigiJXMoKSwgY2FuJ3QgdW5yZWdpc3RlciBsaW5lIGRpc2NpcGxpbmUgKGVyciA9ICVkKVxuIiwKCQkJICAgX19GVU5DVElPTl9fLCBlcnIpOwoJfQp9Cgptb2R1bGVfaW5pdChpcnR0eV9zaXJfaW5pdCk7Cm1vZHVsZV9leGl0KGlydHR5X3Npcl9jbGVhbnVwKTsKCk1PRFVMRV9BVVRIT1IoIkRhZyBCcmF0dGxpIDxkYWdiQGNzLnVpdC5ubz4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJJckRBIFRUWSBkZXZpY2UgZHJpdmVyIik7Ck1PRFVMRV9BTElBU19MRElTQyhOX0lSREEpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Cgo=