LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICoKICogaTJjLXBhcnBvcnQuYyBJMkMgYnVzIG92ZXIgcGFyYWxsZWwgcG9ydCAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICoKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICoKICAgQ29weXJpZ2h0IChDKSAyMDAzLTIwMDQgSmVhbiBEZWx2YXJlIDxraGFsaUBsaW51eC1mci5vcmc+CiAgIAogICBCYXNlZCBvbiBvbGRlciBpMmMtcGhpbGlwcy1wYXIuYyBkcml2ZXIKICAgQ29weXJpZ2h0IChDKSAxOTk1LTIwMDAgU2ltb24gRy4gVm9nbAogICBXaXRoIHNvbWUgY2hhbmdlcyBmcm9tOgogICBGcm9kbyBMb29pamFhcmQgPGZyb2RvbEBkZHMubmw+CiAgIEt59nN0aSBN5Gxra2kgPGttYWxra2lAY2MuaHV0LmZpPgogICAKICAgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICAgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICAgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KCiAgIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogICBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAgIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCgogICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogICBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogICBGb3VuZGF0aW9uLCBJbmMuLCA2NzUgTWFzcyBBdmUsIENhbWJyaWRnZSwgTUEgMDIxMzksIFVTQS4KICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L3BhcnBvcnQuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvaTJjLWFsZ28tYml0Lmg+CiNpbmNsdWRlICJpMmMtcGFycG9ydC5oIgoKLyogLS0tLS0gRGV2aWNlIGxpc3QgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpzdHJ1Y3QgaTJjX3BhciB7CglzdHJ1Y3QgcGFyZGV2aWNlICpwZGV2OwoJc3RydWN0IGkyY19hZGFwdGVyIGFkYXB0ZXI7CglzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgYWxnb19kYXRhOwoJc3RydWN0IGkyY19wYXIgKm5leHQ7Cn07CgpzdGF0aWMgc3RydWN0IGkyY19wYXIgKmFkYXB0ZXJfbGlzdDsKCi8qIC0tLS0tIExvdy1sZXZlbCBwYXJhbGxlbCBwb3J0IGFjY2VzcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwoKc3RhdGljIHZvaWQgcG9ydF93cml0ZV9kYXRhKHN0cnVjdCBwYXJwb3J0ICpwLCB1bnNpZ25lZCBjaGFyIGQpCnsKCXBhcnBvcnRfd3JpdGVfZGF0YShwLCBkKTsKfQoKc3RhdGljIHZvaWQgcG9ydF93cml0ZV9jb250cm9sKHN0cnVjdCBwYXJwb3J0ICpwLCB1bnNpZ25lZCBjaGFyIGQpCnsKCXBhcnBvcnRfd3JpdGVfY29udHJvbChwLCBkKTsKfQoKc3RhdGljIHVuc2lnbmVkIGNoYXIgcG9ydF9yZWFkX2RhdGEoc3RydWN0IHBhcnBvcnQgKnApCnsKCXJldHVybiBwYXJwb3J0X3JlYWRfZGF0YShwKTsKfQoKc3RhdGljIHVuc2lnbmVkIGNoYXIgcG9ydF9yZWFkX3N0YXR1cyhzdHJ1Y3QgcGFycG9ydCAqcCkKewoJcmV0dXJuIHBhcnBvcnRfcmVhZF9zdGF0dXMocCk7Cn0KCnN0YXRpYyB1bnNpZ25lZCBjaGFyIHBvcnRfcmVhZF9jb250cm9sKHN0cnVjdCBwYXJwb3J0ICpwKQp7CglyZXR1cm4gcGFycG9ydF9yZWFkX2NvbnRyb2wocCk7Cn0KCnN0YXRpYyB2b2lkICgqcG9ydF93cml0ZVtdKShzdHJ1Y3QgcGFycG9ydCAqLCB1bnNpZ25lZCBjaGFyKSA9IHsKCXBvcnRfd3JpdGVfZGF0YSwKCU5VTEwsCglwb3J0X3dyaXRlX2NvbnRyb2wsCn07CgpzdGF0aWMgdW5zaWduZWQgY2hhciAoKnBvcnRfcmVhZFtdKShzdHJ1Y3QgcGFycG9ydCAqKSA9IHsKCXBvcnRfcmVhZF9kYXRhLAoJcG9ydF9yZWFkX3N0YXR1cywKCXBvcnRfcmVhZF9jb250cm9sLAp9OwoKLyogLS0tLS0gVW5pZmllZCBsaW5lIG9wZXJhdGlvbiBmdW5jdGlvbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpzdGF0aWMgaW5saW5lIHZvaWQgbGluZV9zZXQoc3RydWN0IHBhcnBvcnQgKmRhdGEsIGludCBzdGF0ZSwKCWNvbnN0IHN0cnVjdCBsaW5lb3AgKm9wKQp7Cgl1OCBvbGR2YWwgPSBwb3J0X3JlYWRbb3AtPnBvcnRdKGRhdGEpOwoKCS8qIFRvdWNoIG9ubHkgdGhlIGJpdChzKSBuZWVkZWQgKi8KCWlmICgob3AtPmludmVydGVkICYmICFzdGF0ZSkgfHwgKCFvcC0+aW52ZXJ0ZWQgJiYgc3RhdGUpKQoJCXBvcnRfd3JpdGVbb3AtPnBvcnRdKGRhdGEsIG9sZHZhbCB8IG9wLT52YWwpOwoJZWxzZQoJCXBvcnRfd3JpdGVbb3AtPnBvcnRdKGRhdGEsIG9sZHZhbCAmIH5vcC0+dmFsKTsKfQoKc3RhdGljIGlubGluZSBpbnQgbGluZV9nZXQoc3RydWN0IHBhcnBvcnQgKmRhdGEsCgljb25zdCBzdHJ1Y3QgbGluZW9wICpvcCkKewoJdTggb2xkdmFsID0gcG9ydF9yZWFkW29wLT5wb3J0XShkYXRhKTsKCglyZXR1cm4gKChvcC0+aW52ZXJ0ZWQgJiYgKG9sZHZhbCAmIG9wLT52YWwpICE9IG9wLT52YWwpCgkgICAgfHwgKCFvcC0+aW52ZXJ0ZWQgJiYgKG9sZHZhbCAmIG9wLT52YWwpID09IG9wLT52YWwpKTsKfQoKLyogLS0tLS0gSTJDIGFsZ29yaXRobSBjYWxsLWJhY2sgZnVuY3Rpb25zIGFuZCBzdHJ1Y3R1cmVzIC0tLS0tLS0tLS0tLS0tLS0tICovCgpzdGF0aWMgdm9pZCBwYXJwb3J0X3NldHNjbCh2b2lkICpkYXRhLCBpbnQgc3RhdGUpCnsKCWxpbmVfc2V0KChzdHJ1Y3QgcGFycG9ydCAqKSBkYXRhLCBzdGF0ZSwgJmFkYXB0ZXJfcGFybVt0eXBlXS5zZXRzY2wpOwp9CgpzdGF0aWMgdm9pZCBwYXJwb3J0X3NldHNkYSh2b2lkICpkYXRhLCBpbnQgc3RhdGUpCnsKCWxpbmVfc2V0KChzdHJ1Y3QgcGFycG9ydCAqKSBkYXRhLCBzdGF0ZSwgJmFkYXB0ZXJfcGFybVt0eXBlXS5zZXRzZGEpOwp9CgpzdGF0aWMgaW50IHBhcnBvcnRfZ2V0c2NsKHZvaWQgKmRhdGEpCnsKCXJldHVybiBsaW5lX2dldCgoc3RydWN0IHBhcnBvcnQgKikgZGF0YSwgJmFkYXB0ZXJfcGFybVt0eXBlXS5nZXRzY2wpOwp9CgpzdGF0aWMgaW50IHBhcnBvcnRfZ2V0c2RhKHZvaWQgKmRhdGEpCnsKCXJldHVybiBsaW5lX2dldCgoc3RydWN0IHBhcnBvcnQgKikgZGF0YSwgJmFkYXB0ZXJfcGFybVt0eXBlXS5nZXRzZGEpOwp9CgovKiBFbmNhcHN1bGF0ZSB0aGUgZnVuY3Rpb25zIGFib3ZlIGluIHRoZSBjb3JyZWN0IHN0cnVjdHVyZS4KICAgTm90ZSB0aGF0IHRoaXMgaXMgb25seSBhIHRlbXBsYXRlLCBmcm9tIHdoaWNoIHRoZSByZWFsIHN0cnVjdHVyZXMgYXJlCiAgIGNvcGllZC4gVGhlIGF0dGFjaGluZyBjb2RlIHdpbGwgc2V0IGdldHNjbCB0byBOVUxMIGZvciBhZGFwdGVycyB0aGF0CiAgIGNhbm5vdCByZWFkIFNDTCBiYWNrLCBhbmQgd2lsbCBhbHNvIG1ha2UgdGhlIGRhdGEgZmllbGQgcG9pbnQgdG8KICAgdGhlIHBhcmFsbGVsIHBvcnQgc3RydWN0dXJlLiAqLwpzdGF0aWMgc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhIHBhcnBvcnRfYWxnb19kYXRhID0gewoJLnNldHNkYQkJPSBwYXJwb3J0X3NldHNkYSwKCS5zZXRzY2wJCT0gcGFycG9ydF9zZXRzY2wsCgkuZ2V0c2RhCQk9IHBhcnBvcnRfZ2V0c2RhLAoJLmdldHNjbAkJPSBwYXJwb3J0X2dldHNjbCwKCS51ZGVsYXkJCT0gNjAsCgkudGltZW91dAk9IEhaLAp9OyAKCi8qIC0tLS0tIEkyYyBhbmQgcGFyYWxsZWwgcG9ydCBjYWxsLWJhY2sgZnVuY3Rpb25zIGFuZCBzdHJ1Y3R1cmVzIC0tLS0tLS0tLSAqLwoKc3RhdGljIHN0cnVjdCBpMmNfYWRhcHRlciBwYXJwb3J0X2FkYXB0ZXIgPSB7Cgkub3duZXIJCT0gVEhJU19NT0RVTEUsCgkuY2xhc3MJCT0gSTJDX0NMQVNTX0hXTU9OLAoJLmlkCQk9IEkyQ19IV19CX0xQLAoJLm5hbWUJCT0gIlBhcmFsbGVsIHBvcnQgYWRhcHRlciIsCn07CgpzdGF0aWMgdm9pZCBpMmNfcGFycG9ydF9hdHRhY2ggKHN0cnVjdCBwYXJwb3J0ICpwb3J0KQp7CglzdHJ1Y3QgaTJjX3BhciAqYWRhcHRlcjsKCQoJYWRhcHRlciA9IGt6YWxsb2Moc2l6ZW9mKHN0cnVjdCBpMmNfcGFyKSwgR0ZQX0tFUk5FTCk7CglpZiAoYWRhcHRlciA9PSBOVUxMKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJpMmMtcGFycG9ydDogRmFpbGVkIHRvIGt6YWxsb2NcbiIpOwoJCXJldHVybjsKCX0KCglwcl9kZWJ1ZygiaTJjLXBhcnBvcnQ6IGF0dGFjaGluZyB0byAlc1xuIiwgcG9ydC0+bmFtZSk7CglhZGFwdGVyLT5wZGV2ID0gcGFycG9ydF9yZWdpc3Rlcl9kZXZpY2UocG9ydCwgImkyYy1wYXJwb3J0IiwKCQlOVUxMLCBOVUxMLCBOVUxMLCBQQVJQT1JUX0ZMQUdfRVhDTCwgTlVMTCk7CglpZiAoIWFkYXB0ZXItPnBkZXYpIHsKCQlwcmludGsoS0VSTl9FUlIgImkyYy1wYXJwb3J0OiBVbmFibGUgdG8gcmVnaXN0ZXIgd2l0aCBwYXJwb3J0XG4iKTsKCQlnb3RvIEVSUk9SMDsKCX0KCgkvKiBGaWxsIHRoZSByZXN0IG9mIHRoZSBzdHJ1Y3R1cmUgKi8KCWFkYXB0ZXItPmFkYXB0ZXIgPSBwYXJwb3J0X2FkYXB0ZXI7CglhZGFwdGVyLT5hbGdvX2RhdGEgPSBwYXJwb3J0X2FsZ29fZGF0YTsKCWlmICghYWRhcHRlcl9wYXJtW3R5cGVdLmdldHNjbC52YWwpCgkJYWRhcHRlci0+YWxnb19kYXRhLmdldHNjbCA9IE5VTEw7CglhZGFwdGVyLT5hbGdvX2RhdGEuZGF0YSA9IHBvcnQ7CglhZGFwdGVyLT5hZGFwdGVyLmFsZ29fZGF0YSA9ICZhZGFwdGVyLT5hbGdvX2RhdGE7CgoJaWYgKHBhcnBvcnRfY2xhaW1fb3JfYmxvY2soYWRhcHRlci0+cGRldikgPCAwKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJpMmMtcGFycG9ydDogQ291bGQgbm90IGNsYWltIHBhcmFsbGVsIHBvcnRcbiIpOwoJCWdvdG8gRVJST1IxOwoJfQoKCS8qIFJlc2V0IGhhcmR3YXJlIHRvIGEgc2FuZSBzdGF0ZSAoU0NMIGFuZCBTREEgaGlnaCkgKi8KCXBhcnBvcnRfc2V0c2RhKHBvcnQsIDEpOwoJcGFycG9ydF9zZXRzY2wocG9ydCwgMSk7CgkvKiBPdGhlciBpbml0IGlmIG5lZWRlZCAocG93ZXIgb24uLi4pICovCglpZiAoYWRhcHRlcl9wYXJtW3R5cGVdLmluaXQudmFsKQoJCWxpbmVfc2V0KHBvcnQsIDEsICZhZGFwdGVyX3Bhcm1bdHlwZV0uaW5pdCk7CgoJcGFycG9ydF9yZWxlYXNlKGFkYXB0ZXItPnBkZXYpOwoKCWlmIChpMmNfYml0X2FkZF9idXMoJmFkYXB0ZXItPmFkYXB0ZXIpIDwgMCkgewoJCXByaW50ayhLRVJOX0VSUiAiaTJjLXBhcnBvcnQ6IFVuYWJsZSB0byByZWdpc3RlciB3aXRoIEkyQ1xuIik7CgkJZ290byBFUlJPUjE7Cgl9CgoJLyogQWRkIHRoZSBuZXcgYWRhcHRlciB0byB0aGUgbGlzdCAqLwoJYWRhcHRlci0+bmV4dCA9IGFkYXB0ZXJfbGlzdDsKCWFkYXB0ZXJfbGlzdCA9IGFkYXB0ZXI7CiAgICAgICAgcmV0dXJuOwoKRVJST1IxOgoJcGFycG9ydF91bnJlZ2lzdGVyX2RldmljZShhZGFwdGVyLT5wZGV2KTsKRVJST1IwOgoJa2ZyZWUoYWRhcHRlcik7Cn0KCnN0YXRpYyB2b2lkIGkyY19wYXJwb3J0X2RldGFjaCAoc3RydWN0IHBhcnBvcnQgKnBvcnQpCnsKCXN0cnVjdCBpMmNfcGFyICphZGFwdGVyLCAqcHJldjsKCgkvKiBXYWxrIHRoZSBsaXN0ICovCglmb3IgKHByZXYgPSBOVUxMLCBhZGFwdGVyID0gYWRhcHRlcl9saXN0OyBhZGFwdGVyOwoJICAgICBwcmV2ID0gYWRhcHRlciwgYWRhcHRlciA9IGFkYXB0ZXItPm5leHQpIHsKCQlpZiAoYWRhcHRlci0+cGRldi0+cG9ydCA9PSBwb3J0KSB7CgkJCS8qIFVuLWluaXQgaWYgbmVlZGVkIChwb3dlciBvZmYuLi4pICovCgkJCWlmIChhZGFwdGVyX3Bhcm1bdHlwZV0uaW5pdC52YWwpCgkJCQlsaW5lX3NldChwb3J0LCAwLCAmYWRhcHRlcl9wYXJtW3R5cGVdLmluaXQpOwoJCQkJCgkJCWkyY19iaXRfZGVsX2J1cygmYWRhcHRlci0+YWRhcHRlcik7CgkJCXBhcnBvcnRfdW5yZWdpc3Rlcl9kZXZpY2UoYWRhcHRlci0+cGRldik7CgkJCWlmIChwcmV2KQoJCQkJcHJldi0+bmV4dCA9IGFkYXB0ZXItPm5leHQ7CgkJCWVsc2UKCQkJCWFkYXB0ZXJfbGlzdCA9IGFkYXB0ZXItPm5leHQ7CgkJCWtmcmVlKGFkYXB0ZXIpOwoJCQlyZXR1cm47CgkJfQoJfQp9CgpzdGF0aWMgc3RydWN0IHBhcnBvcnRfZHJpdmVyIGkyY19wYXJwb3J0X2RyaXZlciA9IHsKCS5uYW1lCT0gImkyYy1wYXJwb3J0IiwKCS5hdHRhY2gJPSBpMmNfcGFycG9ydF9hdHRhY2gsCgkuZGV0YWNoCT0gaTJjX3BhcnBvcnRfZGV0YWNoLAp9OwoKLyogLS0tLS0gTW9kdWxlIGxvYWRpbmcsIHVubG9hZGluZyBhbmQgaW5mb3JtYXRpb24gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgpzdGF0aWMgaW50IF9faW5pdCBpMmNfcGFycG9ydF9pbml0KHZvaWQpCnsKCWlmICh0eXBlIDwgMCkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkyYy1wYXJwb3J0OiBhZGFwdGVyIHR5cGUgdW5zcGVjaWZpZWRcbiIpOwoJCXJldHVybiAtRU5PREVWOwoJfQoKCWlmICh0eXBlID49IEFSUkFZX1NJWkUoYWRhcHRlcl9wYXJtKSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkyYy1wYXJwb3J0OiBpbnZhbGlkIHR5cGUgKCVkKVxuIiwgdHlwZSk7CgkJcmV0dXJuIC1FTk9ERVY7Cgl9CgoJcmV0dXJuIHBhcnBvcnRfcmVnaXN0ZXJfZHJpdmVyKCZpMmNfcGFycG9ydF9kcml2ZXIpOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgaTJjX3BhcnBvcnRfZXhpdCh2b2lkKQp7CglwYXJwb3J0X3VucmVnaXN0ZXJfZHJpdmVyKCZpMmNfcGFycG9ydF9kcml2ZXIpOwp9CgpNT0RVTEVfQVVUSE9SKCJKZWFuIERlbHZhcmUgPGtoYWxpQGxpbnV4LWZyLm9yZz4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJJMkMgYnVzIG92ZXIgcGFyYWxsZWwgcG9ydCIpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Cgptb2R1bGVfaW5pdChpMmNfcGFycG9ydF9pbml0KTsKbW9kdWxlX2V4aXQoaTJjX3BhcnBvcnRfZXhpdCk7Cg==