LyoKICoJUENJIGhhbmRsaW5nIG9mIEkyTyBjb250cm9sbGVyCiAqCiAqIAlDb3B5cmlnaHQgKEMpIDE5OTktMjAwMglSZWQgSGF0IFNvZnR3YXJlCiAqCiAqCVdyaXR0ZW4gYnkgQWxhbiBDb3gsIEJ1aWxkaW5nIE51bWJlciBUaHJlZSBMdGQKICoKICoJVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICoJdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlCiAqCUZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIKICoJb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICoJQSBsb3Qgb2YgdGhlIEkyTyBtZXNzYWdlIHNpZGUgY29kZSBmcm9tIHRoaXMgaXMgdGFrZW4gZnJvbSB0aGUgUmVkCiAqCUNyZWVrIFJDUENJNDUgYWRhcHRlciBkcml2ZXIgYnkgUmVkIENyZWVrIENvbW11bmljYXRpb25zCiAqCiAqCUZpeGVzL2FkZGl0aW9uczoKICoJCVBoaWxpcHAgUnVtcGYKICoJCUp1aGEgU2llduRuZW4gPEp1aGEuU2lldmFuZW5AY3MuSGVsc2lua2kuRkk+CiAqCQlBdXZvIEjka2tpbmVuIDxBdXZvLkhha2tpbmVuQGNzLkhlbHNpbmtpLkZJPgogKgkJRGVlcGFrIFNheGVuYSA8ZGVlcGFrQHBsZXhpdHkubmV0PgogKgkJQm9qaSBUIEthbm5hbnRoYW5hbSA8Ym9qaS50Lmthbm5hbnRoYW5hbUBpbnRlbC5jb20+CiAqCQlBbGFuIENveCA8YWxhbkByZWRoYXQuY29tPjoKICoJCQlQb3J0ZWQgdG8gTGludXggMi41LgogKgkJTWFya3VzIExpZGVsIDxNYXJrdXMuTGlkZWxAc2hhZG93Y29ubmVjdC5jb20+OgogKgkJCU1pbm9yIGZpeGVzIGZvciAyLjYuCiAqCQlNYXJrdXMgTGlkZWwgPE1hcmt1cy5MaWRlbEBzaGFkb3djb25uZWN0LmNvbT46CiAqCQkJU3VwcG9ydCBmb3Igc3lzZnMgaW5jbHVkZWQuCiAqLwoKI2luY2x1ZGUgPGxpbnV4L3BjaS5oPgojaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+CiNpbmNsdWRlIDxsaW51eC9pMm8uaD4KCiNpZmRlZiBDT05GSUdfTVRSUgojaW5jbHVkZSA8YXNtL210cnIuaD4KI2VuZGlmCQkJCS8vIENPTkZJR19NVFJSCgovKiBNb2R1bGUgaW50ZXJuYWwgZnVuY3Rpb25zIGZyb20gb3RoZXIgc291cmNlcyAqLwpleHRlcm4gc3RydWN0IGkyb19jb250cm9sbGVyICppMm9faW9wX2FsbG9jKHZvaWQpOwpleHRlcm4gdm9pZCBpMm9faW9wX2ZyZWUoc3RydWN0IGkyb19jb250cm9sbGVyICopOwoKZXh0ZXJuIGludCBpMm9faW9wX2FkZChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKik7CmV4dGVybiB2b2lkIGkyb19pb3BfcmVtb3ZlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqKTsKCmV4dGVybiBpbnQgaTJvX2RyaXZlcl9kaXNwYXRjaChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKiwgdTMyLAoJCQkgICAgICAgc3RydWN0IGkyb19tZXNzYWdlICopOwoKLyogUENJIGRldmljZSBpZCB0YWJsZSBmb3IgYWxsIEkyTyBjb250cm9sbGVycyAqLwpzdGF0aWMgc3RydWN0IHBjaV9kZXZpY2VfaWQgX19kZXZpbml0ZGF0YSBpMm9fcGNpX2lkc1tdID0gewoJe1BDSV9ERVZJQ0VfQ0xBU1MoUENJX0NMQVNTX0lOVEVMTElHRU5UX0kyTyA8PCA4LCAweGZmZmYwMCl9LAoJe1BDSV9ERVZJQ0UoUENJX1ZFTkRPUl9JRF9EUFQsIDB4YTUxMSl9LAoJezB9Cn07CgovKioKICoJaTJvX2RtYV9yZWFsbG9jIC0gUmVhbGxvYyBETUEgbWVtb3J5CiAqCUBkZXY6IHN0cnVjdCBkZXZpY2UgcG9pbnRlciB0byB0aGUgUENJIGRldmljZSBvZiB0aGUgSTJPIGNvbnRyb2xsZXIKICoJQGFkZHI6IHBvaW50ZXIgdG8gYSBpMm9fZG1hIHN0cnVjdCBETUEgYnVmZmVyCiAqCUBsZW46IG5ldyBsZW5ndGggb2YgbWVtb3J5CiAqCUBnZnBfbWFzazogR0ZQIG1hc2sKICoKICoJSWYgdGhlcmUgd2FzIHNvbWV0aGluZyBhbGxvY2F0ZWQgaW4gdGhlIGFkZHIsIGZyZWUgaXQgZmlyc3QuIElmIGxlbiA+IDAKICoJdGhhbiB0cnkgdG8gYWxsb2NhdGUgaXQgYW5kIHdyaXRlIHRoZSBhZGRyZXNzZXMgYmFjayB0byB0aGUgYWRkcgogKglzdHJ1Y3R1cmUuIElmIGxlbiA9PSAwIHNldCB0aGUgdmlydHVhbCBhZGRyZXNzIHRvIE5VTEwuCiAqCiAqCVJldHVybnMgdGhlIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwppbnQgaTJvX2RtYV9yZWFsbG9jKHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IGkyb19kbWEgKmFkZHIsIHNpemVfdCBsZW4sCgkJICAgIHVuc2lnbmVkIGludCBnZnBfbWFzaykKewoJaTJvX2RtYV9mcmVlKGRldiwgYWRkcik7CgoJaWYgKGxlbikKCQlyZXR1cm4gaTJvX2RtYV9hbGxvYyhkZXYsIGFkZHIsIGxlbiwgZ2ZwX21hc2spOwoKCXJldHVybiAwOwp9OwoKLyoqCiAqCWkyb19wY2lfZnJlZSAtIEZyZWVzIHRoZSBETUEgbWVtb3J5IGZvciB0aGUgSTJPIGNvbnRyb2xsZXIKICoJQGM6IEkyTyBjb250cm9sbGVyIHRvIGZyZWUKICoKICoJUmVtb3ZlIGFsbCBhbGxvY2F0ZWQgRE1BIG1lbW9yeSBhbmQgdW5tYXAgbWVtb3J5IElPIHJlZ2lvbnMuIElmIE1UUlIKICoJaXMgZW5hYmxlZCwgYWxzbyByZW1vdmUgaXQgYWdhaW4uCiAqLwpzdGF0aWMgdm9pZCBpMm9fcGNpX2ZyZWUoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglzdHJ1Y3QgZGV2aWNlICpkZXY7CgoJZGV2ID0gJmMtPnBkZXYtPmRldjsKCglpMm9fZG1hX2ZyZWUoZGV2LCAmYy0+b3V0X3F1ZXVlKTsKCWkyb19kbWFfZnJlZShkZXYsICZjLT5zdGF0dXNfYmxvY2spOwoJaWYgKGMtPmxjdCkKCQlrZnJlZShjLT5sY3QpOwoJaTJvX2RtYV9mcmVlKGRldiwgJmMtPmRsY3QpOwoJaTJvX2RtYV9mcmVlKGRldiwgJmMtPmhydCk7CglpMm9fZG1hX2ZyZWUoZGV2LCAmYy0+c3RhdHVzKTsKCiNpZmRlZiBDT05GSUdfTVRSUgoJaWYgKGMtPm10cnJfcmVnMCA+PSAwKQoJCW10cnJfZGVsKGMtPm10cnJfcmVnMCwgMCwgMCk7CglpZiAoYy0+bXRycl9yZWcxID49IDApCgkJbXRycl9kZWwoYy0+bXRycl9yZWcxLCAwLCAwKTsKI2VuZGlmCgoJaWYgKGMtPnJhcHRvciAmJiBjLT5pbl9xdWV1ZS52aXJ0KQoJCWlvdW5tYXAoYy0+aW5fcXVldWUudmlydCk7CgoJaWYgKGMtPmJhc2UudmlydCkKCQlpb3VubWFwKGMtPmJhc2UudmlydCk7Cn0KCi8qKgogKglpMm9fcGNpX2FsbG9jIC0gQWxsb2NhdGUgRE1BIG1lbW9yeSwgbWFwIElPIG1lbW9yeSBmb3IgSTJPIGNvbnRyb2xsZXIKICoJQGM6IEkyTyBjb250cm9sbGVyCiAqCiAqCUFsbG9jYXRlIERNQSBtZW1vcnkgZm9yIGEgUENJIChvciBpbiB0aGVvcnkgQUdQKSBJMk8gY29udHJvbGxlci4gQWxsCiAqCUlPIG1hcHBpbmdzIGFyZSBhbHNvIGRvbmUgaGVyZS4gSWYgTVRSUiBpcyBlbmFibGVkLCBhbHNvIGRvIGFkZCBtZW1vcnkKICoJcmVnaW9ucyBoZXJlLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwpzdGF0aWMgaW50IF9fZGV2aW5pdCBpMm9fcGNpX2FsbG9jKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IHBjaV9kZXYgKnBkZXYgPSBjLT5wZGV2OwoJc3RydWN0IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsKCWludCBpOwoKCWZvciAoaSA9IDA7IGkgPCA2OyBpKyspIHsKCQkvKiBTa2lwIEkvTyBzcGFjZXMgKi8KCQlpZiAoIShwY2lfcmVzb3VyY2VfZmxhZ3MocGRldiwgaSkgJiBJT1JFU09VUkNFX0lPKSkgewoJCQlpZiAoIWMtPmJhc2UucGh5cykgewoJCQkJYy0+YmFzZS5waHlzID0gcGNpX3Jlc291cmNlX3N0YXJ0KHBkZXYsIGkpOwoJCQkJYy0+YmFzZS5sZW4gPSBwY2lfcmVzb3VyY2VfbGVuKHBkZXYsIGkpOwoKCQkJCS8qCgkJCQkgKiBJZiB3ZSBrbm93IHdoYXQgY2FyZCBpdCBpcywgc2V0IHRoZSBzaXplCgkJCQkgKiBjb3JyZWN0bHkuIENvZGUgaXMgdGFrZW4gZnJvbSBkcHRfaTJvLmMKCQkJCSAqLwoJCQkJaWYgKHBkZXYtPmRldmljZSA9PSAweGE1MDEpIHsKCQkJCQlpZiAocGRldi0+c3Vic3lzdGVtX2RldmljZSA+PSAweGMwMzIgJiYKCQkJCQkgICAgcGRldi0+c3Vic3lzdGVtX2RldmljZSA8PSAweGMwM2IpIHsKCQkJCQkJaWYgKGMtPmJhc2UubGVuID4gMHg0MDAwMDApCgkJCQkJCQljLT5iYXNlLmxlbiA9IDB4NDAwMDAwOwoJCQkJCX0gZWxzZSB7CgkJCQkJCWlmIChjLT5iYXNlLmxlbiA+IDB4MTAwMDAwKQoJCQkJCQkJYy0+YmFzZS5sZW4gPSAweDEwMDAwMDsKCQkJCQl9CgkJCQl9CgkJCQlpZiAoIWMtPnJhcHRvcikKCQkJCQlicmVhazsKCQkJfSBlbHNlIHsKCQkJCWMtPmluX3F1ZXVlLnBoeXMgPSBwY2lfcmVzb3VyY2Vfc3RhcnQocGRldiwgaSk7CgkJCQljLT5pbl9xdWV1ZS5sZW4gPSBwY2lfcmVzb3VyY2VfbGVuKHBkZXYsIGkpOwoJCQkJYnJlYWs7CgkJCX0KCQl9Cgl9CgoJaWYgKGkgPT0gNikgewoJCXByaW50ayhLRVJOX0VSUiAiJXM6IEkyTyBjb250cm9sbGVyIGhhcyBubyBtZW1vcnkgcmVnaW9ucyIKCQkgICAgICAgIiBkZWZpbmVkLlxuIiwgYy0+bmFtZSk7CgkJaTJvX3BjaV9mcmVlKGMpOwoJCXJldHVybiAtRUlOVkFMOwoJfQoKCS8qIE1hcCB0aGUgSTJPIGNvbnRyb2xsZXIgKi8KCWlmIChjLT5yYXB0b3IpIHsKCQlwcmludGsoS0VSTl9JTkZPICIlczogUENJIEkyTyBjb250cm9sbGVyXG4iLCBjLT5uYW1lKTsKCQlwcmludGsoS0VSTl9JTkZPICIgICAgIEJBUjAgYXQgMHglMDhsWCBzaXplPSVsZFxuIiwKCQkgICAgICAgKHVuc2lnbmVkIGxvbmcpYy0+YmFzZS5waHlzLCAodW5zaWduZWQgbG9uZyljLT5iYXNlLmxlbik7CgkJcHJpbnRrKEtFUk5fSU5GTyAiICAgICBCQVIxIGF0IDB4JTA4bFggc2l6ZT0lbGRcbiIsCgkJICAgICAgICh1bnNpZ25lZCBsb25nKWMtPmluX3F1ZXVlLnBoeXMsCgkJICAgICAgICh1bnNpZ25lZCBsb25nKWMtPmluX3F1ZXVlLmxlbik7Cgl9IGVsc2UKCQlwcmludGsoS0VSTl9JTkZPICIlczogUENJIEkyTyBjb250cm9sbGVyIGF0ICUwOGxYIHNpemU9JWxkXG4iLAoJCSAgICAgICBjLT5uYW1lLCAodW5zaWduZWQgbG9uZyljLT5iYXNlLnBoeXMsCgkJICAgICAgICh1bnNpZ25lZCBsb25nKWMtPmJhc2UubGVuKTsKCgljLT5iYXNlLnZpcnQgPSBpb3JlbWFwKGMtPmJhc2UucGh5cywgYy0+YmFzZS5sZW4pOwoJaWYgKCFjLT5iYXNlLnZpcnQpIHsKCQlwcmludGsoS0VSTl9FUlIgIiVzOiBVbmFibGUgdG8gbWFwIGNvbnRyb2xsZXIuXG4iLCBjLT5uYW1lKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCglpZiAoYy0+cmFwdG9yKSB7CgkJYy0+aW5fcXVldWUudmlydCA9IGlvcmVtYXAoYy0+aW5fcXVldWUucGh5cywgYy0+aW5fcXVldWUubGVuKTsKCQlpZiAoIWMtPmluX3F1ZXVlLnZpcnQpIHsKCQkJcHJpbnRrKEtFUk5fRVJSICIlczogVW5hYmxlIHRvIG1hcCBjb250cm9sbGVyLlxuIiwKCQkJICAgICAgIGMtPm5hbWUpOwoJCQlpMm9fcGNpX2ZyZWUoYyk7CgkJCXJldHVybiAtRU5PTUVNOwoJCX0KCX0gZWxzZQoJCWMtPmluX3F1ZXVlID0gYy0+YmFzZTsKCgljLT5pcnFfbWFzayA9IGMtPmJhc2UudmlydCArIDB4MzQ7CgljLT5wb3N0X3BvcnQgPSBjLT5iYXNlLnZpcnQgKyAweDQwOwoJYy0+cmVwbHlfcG9ydCA9IGMtPmJhc2UudmlydCArIDB4NDQ7CgojaWZkZWYgQ09ORklHX01UUlIKCS8qIEVuYWJsZSBXcml0ZSBDb21iaW5pbmcgTVRSUiBmb3IgSU9QJ3MgbWVtb3J5IHJlZ2lvbiAqLwoJYy0+bXRycl9yZWcwID0gbXRycl9hZGQoYy0+aW5fcXVldWUucGh5cywgYy0+aW5fcXVldWUubGVuLAoJCQkJTVRSUl9UWVBFX1dSQ09NQiwgMSk7CgljLT5tdHJyX3JlZzEgPSAtMTsKCglpZiAoYy0+bXRycl9yZWcwIDwgMCkKCQlwcmludGsoS0VSTl9XQVJOSU5HICIlczogY291bGQgbm90IGVuYWJsZSB3cml0ZSBjb21iaW5pbmcgIgoJCSAgICAgICAiTVRSUlxuIiwgYy0+bmFtZSk7CgllbHNlCgkJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IHVzaW5nIHdyaXRlIGNvbWJpbmluZyBNVFJSXG4iLCBjLT5uYW1lKTsKCgkvKgoJICogSWYgaXQgaXMgYW4gSU5URUwgaTk2MCBJL08gcHJvY2Vzc29yIHRoZW4gc2V0IHRoZSBmaXJzdCA2NEsgdG8KCSAqIFVuY2FjaGVhYmxlIHNpbmNlIHRoZSByZWdpb24gY29udGFpbnMgdGhlIG1lc3NhZ2luZyB1bml0IHdoaWNoCgkgKiBzaG91bGRuJ3QgYmUgY2FjaGVkLgoJICovCglpZiAoKHBkZXYtPnZlbmRvciA9PSBQQ0lfVkVORE9SX0lEX0lOVEVMIHx8CgkgICAgIHBkZXYtPnZlbmRvciA9PSBQQ0lfVkVORE9SX0lEX0RQVCkgJiYgIWMtPnJhcHRvcikgewoJCXByaW50ayhLRVJOX0lORk8gIiVzOiBNVFJSIHdvcmthcm91bmQgZm9yIEludGVsIGk5NjAgcHJvY2Vzc29yIgoJCSAgICAgICAiXG4iLCBjLT5uYW1lKTsKCQljLT5tdHJyX3JlZzEgPSBtdHJyX2FkZChjLT5iYXNlLnBoeXMsIDB4MTAwMDAsCgkJCQkJTVRSUl9UWVBFX1VOQ0FDSEFCTEUsIDEpOwoKCQlpZiAoYy0+bXRycl9yZWcxIDwgMCkgewoJCQlwcmludGsoS0VSTl9XQVJOSU5HICIlczogRXJyb3IgaW4gc2V0dGluZyAiCgkJCSAgICAgICAiTVRSUl9UWVBFX1VOQ0FDSEFCTEVcbiIsIGMtPm5hbWUpOwoJCQltdHJyX2RlbChjLT5tdHJyX3JlZzAsIGMtPmluX3F1ZXVlLnBoeXMsCgkJCQkgYy0+aW5fcXVldWUubGVuKTsKCQkJYy0+bXRycl9yZWcwID0gLTE7CgkJfQoJfQojZW5kaWYKCglpZiAoaTJvX2RtYV9hbGxvYyhkZXYsICZjLT5zdGF0dXMsIDgsIEdGUF9LRVJORUwpKSB7CgkJaTJvX3BjaV9mcmVlKGMpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCWlmIChpMm9fZG1hX2FsbG9jKGRldiwgJmMtPmhydCwgc2l6ZW9mKGkyb19ocnQpLCBHRlBfS0VSTkVMKSkgewoJCWkyb19wY2lfZnJlZShjKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCglpZiAoaTJvX2RtYV9hbGxvYyhkZXYsICZjLT5kbGN0LCA4MTkyLCBHRlBfS0VSTkVMKSkgewoJCWkyb19wY2lfZnJlZShjKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCglpZiAoaTJvX2RtYV9hbGxvYyhkZXYsICZjLT5zdGF0dXNfYmxvY2ssIHNpemVvZihpMm9fc3RhdHVzX2Jsb2NrKSwKCQkJICBHRlBfS0VSTkVMKSkgewoJCWkyb19wY2lfZnJlZShjKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCglpZiAoaTJvX2RtYV9hbGxvYyhkZXYsICZjLT5vdXRfcXVldWUsIE1TR19QT09MX1NJWkUsIEdGUF9LRVJORUwpKSB7CgkJaTJvX3BjaV9mcmVlKGMpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCXBjaV9zZXRfZHJ2ZGF0YShwZGV2LCBjKTsKCglyZXR1cm4gMDsKfQoKLyoqCiAqCWkyb19wY2lfaW50ZXJydXB0IC0gSW50ZXJydXB0IGhhbmRsZXIgZm9yIEkyTyBjb250cm9sbGVyCiAqCUBpcnE6IGludGVycnVwdCBsaW5lCiAqCUBkZXZfaWQ6IHBvaW50ZXIgdG8gdGhlIEkyTyBjb250cm9sbGVyCiAqCUByOiBwb2ludGVyIHRvIHJlZ2lzdGVycwogKgogKglIYW5kbGUgYW4gaW50ZXJydXB0IGZyb20gYSBQQ0kgYmFzZWQgSTJPIGNvbnRyb2xsZXIuIFRoaXMgdHVybnMgb3V0CiAqCXRvIGJlIHJhdGhlciBzaW1wbGUuIFdlIGtlZXAgdGhlIGNvbnRyb2xsZXIgcG9pbnRlciBpbiB0aGUgY29va2llLgogKi8Kc3RhdGljIGlycXJldHVybl90IGkyb19wY2lfaW50ZXJydXB0KGludCBpcnEsIHZvaWQgKmRldl9pZCwgc3RydWN0IHB0X3JlZ3MgKnIpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYyA9IGRldl9pZDsKCXN0cnVjdCBkZXZpY2UgKmRldiA9ICZjLT5wZGV2LT5kZXY7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgKm07Cgl1MzIgbXY7CgoJLyoKCSAqIE9sZCA5NjAgc3RlcHBpbmdzIGhhZCBhIGJ1ZyBpbiB0aGUgSTJPIHVuaXQgdGhhdCBjYXVzZWQKCSAqIHRoZSBxdWV1ZSB0byBhcHBlYXIgZW1wdHkgd2hlbiBpdCB3YXNuJ3QuCgkgKi8KCW12ID0gSTJPX1JFUExZX1JFQUQzMihjKTsKCWlmIChtdiA9PSBJMk9fUVVFVUVfRU1QVFkpIHsKCQltdiA9IEkyT19SRVBMWV9SRUFEMzIoYyk7CgkJaWYgKHVubGlrZWx5KG12ID09IEkyT19RVUVVRV9FTVBUWSkpIHsKCQkJcmV0dXJuIElSUV9OT05FOwoJCX0gZWxzZQoJCQlwcl9kZWJ1ZygiJXM6IDk2MCBidWcgZGV0ZWN0ZWRcbiIsIGMtPm5hbWUpOwoJfQoKCXdoaWxlIChtdiAhPSBJMk9fUVVFVUVfRU1QVFkpIHsKCQkvKgoJCSAqIE1hcCB0aGUgbWVzc2FnZSBmcm9tIHRoZSBwYWdlIGZyYW1lIG1hcCB0byBrZXJuZWwgdmlydHVhbC4KCQkgKiBCZWNhdXNlIGJ1c190b192aXJ0IGlzIGRlcHJlY2F0ZWQsIHdlIGhhdmUgY2FsY3VsYXRlIHRoZQoJCSAqIGxvY2F0aW9uIGJ5IG91cnNlbGYhCgkJICovCgkJbSA9IGkyb19tc2dfb3V0X3RvX3ZpcnQoYywgbXYpOwoKCQkvKgoJCSAqICAgICAgRW5zdXJlIHRoaXMgbWVzc2FnZSBpcyBzZWVuIGNvaGVyZW50bHkgYnV0IGNhY2hhYmx5IGJ5CgkJICogICAgICB0aGUgcHJvY2Vzc29yCgkJICovCgkJZG1hX3N5bmNfc2luZ2xlX2Zvcl9jcHUoZGV2LCBtdiwgTVNHX0ZSQU1FX1NJWkUgKiA0LAoJCQkJCVBDSV9ETUFfRlJPTURFVklDRSk7CgoJCS8qIGRpc3BhdGNoIGl0ICovCgkJaWYgKGkyb19kcml2ZXJfZGlzcGF0Y2goYywgbXYsIG0pKQoJCQkvKiBmbHVzaCBpdCBpZiByZXN1bHQgIT0gMCAqLwoJCQlpMm9fZmx1c2hfcmVwbHkoYywgbXYpOwoKCQkvKgoJCSAqIFRoYXQgOTYwIGJ1ZyBhZ2Fpbi4uLgoJCSAqLwoJCW12ID0gSTJPX1JFUExZX1JFQUQzMihjKTsKCQlpZiAobXYgPT0gSTJPX1FVRVVFX0VNUFRZKQoJCQltdiA9IEkyT19SRVBMWV9SRUFEMzIoYyk7Cgl9CglyZXR1cm4gSVJRX0hBTkRMRUQ7Cn0KCi8qKgogKglpMm9fcGNpX2lycV9lbmFibGUgLSBBbGxvY2F0ZSBpbnRlcnJ1cHQgZm9yIEkyTyBjb250cm9sbGVyCiAqCiAqCUFsbG9jYXRlIGFuIGludGVycnVwdCBmb3IgdGhlIEkyTyBjb250cm9sbGVyLCBhbmQgYWN0aXZhdGUgaW50ZXJydXB0cwogKglvbiB0aGUgSTJPIGNvbnRyb2xsZXIuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCnN0YXRpYyBpbnQgaTJvX3BjaV9pcnFfZW5hYmxlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IHBjaV9kZXYgKnBkZXYgPSBjLT5wZGV2OwoJaW50IHJjOwoKCUkyT19JUlFfV1JJVEUzMihjLCAweGZmZmZmZmZmKTsKCglpZiAocGRldi0+aXJxKSB7CgkJcmMgPSByZXF1ZXN0X2lycShwZGV2LT5pcnEsIGkyb19wY2lfaW50ZXJydXB0LCBTQV9TSElSUSwKCQkJCSBjLT5uYW1lLCBjKTsKCQlpZiAocmMgPCAwKSB7CgkJCXByaW50ayhLRVJOX0VSUiAiJXM6IHVuYWJsZSB0byBhbGxvY2F0ZSBpbnRlcnJ1cHQgJWQuIgoJCQkgICAgICAgIlxuIiwgYy0+bmFtZSwgcGRldi0+aXJxKTsKCQkJcmV0dXJuIHJjOwoJCX0KCX0KCglJMk9fSVJRX1dSSVRFMzIoYywgMHgwMDAwMDAwMCk7CgoJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IEluc3RhbGxlZCBhdCBJUlEgJWRcbiIsIGMtPm5hbWUsIHBkZXYtPmlycSk7CgoJcmV0dXJuIDA7Cn0KCi8qKgogKglpMm9fcGNpX2lycV9kaXNhYmxlIC0gRnJlZSBpbnRlcnJ1cHQgZm9yIEkyTyBjb250cm9sbGVyCiAqCUBjOiBJMk8gY29udHJvbGxlcgogKgogKglEaXNhYmxlIGludGVycnVwdHMgaW4gSTJPIGNvbnRyb2xsZXIgYW5kIHRoZW4gZnJlZSBpbnRlcnJ1cHQuCiAqLwpzdGF0aWMgdm9pZCBpMm9fcGNpX2lycV9kaXNhYmxlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJSTJPX0lSUV9XUklURTMyKGMsIDB4ZmZmZmZmZmYpOwoKCWlmIChjLT5wZGV2LT5pcnEgPiAwKQoJCWZyZWVfaXJxKGMtPnBkZXYtPmlycSwgYyk7Cn0KCi8qKgogKglpMm9fcGNpX3Byb2JlIC0gUHJvYmUgdGhlIFBDSSBkZXZpY2UgZm9yIGFuIEkyTyBjb250cm9sbGVyCiAqCUBkZXY6IFBDSSBkZXZpY2UgdG8gdGVzdAogKglAaWQ6IGlkIHdoaWNoIG1hdGNoZWQgd2l0aCB0aGUgUENJIGRldmljZSBpZCB0YWJsZQogKgogKglQcm9iZSB0aGUgUENJIGRldmljZSBmb3IgYW55IGRldmljZSB3aGljaCBpcyBhIG1lbW9yeSBvZiB0aGUKICoJSW50ZWxsaWdlbnQsIEkyTyBjbGFzcyBvciBhbiBBZGFwdGVjIFplcm8gQ2hhbm5lbCBDb250cm9sbGVyLiBXZQogKglhdHRlbXB0IHRvIHNldCB1cCBlYWNoIHN1Y2ggZGV2aWNlIGFuZCByZWdpc3RlciBpdCB3aXRoIHRoZSBjb3JlLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwpzdGF0aWMgaW50IF9fZGV2aW5pdCBpMm9fcGNpX3Byb2JlKHN0cnVjdCBwY2lfZGV2ICpwZGV2LAoJCQkJICAgY29uc3Qgc3RydWN0IHBjaV9kZXZpY2VfaWQgKmlkKQp7CglzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmM7CglpbnQgcmM7CgoJcHJpbnRrKEtFUk5fSU5GTyAiaTJvOiBDaGVja2luZyBmb3IgUENJIEkyTyBjb250cm9sbGVycy4uLlxuIik7CgoJaWYgKChwZGV2LT5jbGFzcyAmIDB4ZmYpID4gMSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkybzogSTJPIGNvbnRyb2xsZXIgZm91bmQgYnV0IGRvZXMgbm90ICIKCQkgICAgICAgInN1cHBvcnQgSTJPIDEuNSAoc2tpcHBpbmcpLlxuIik7CgkJcmV0dXJuIC1FTk9ERVY7Cgl9CgoJaWYgKChyYyA9IHBjaV9lbmFibGVfZGV2aWNlKHBkZXYpKSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkybzogSTJPIGNvbnRyb2xsZXIgZm91bmQgYnV0IGNvdWxkIG5vdCBiZSIKCQkgICAgICAgIiBlbmFibGVkLlxuIik7CgkJcmV0dXJuIHJjOwoJfQoKCXByaW50ayhLRVJOX0lORk8gImkybzogSTJPIGNvbnRyb2xsZXIgZm91bmQgb24gYnVzICVkIGF0ICVkLlxuIiwKCSAgICAgICBwZGV2LT5idXMtPm51bWJlciwgcGRldi0+ZGV2Zm4pOwoKCWlmIChwY2lfc2V0X2RtYV9tYXNrKHBkZXYsIERNQV8zMkJJVF9NQVNLKSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkybzogSTJPIGNvbnRyb2xsZXIgb24gYnVzICVkIGF0ICVkOiBObyAiCgkJICAgICAgICJzdWl0YWJsZSBETUEgYXZhaWxhYmxlIVxuIiwgcGRldi0+YnVzLT5udW1iZXIsCgkJICAgICAgIHBkZXYtPmRldmZuKTsKCQlyYyA9IC1FTk9ERVY7CgkJZ290byBkaXNhYmxlOwoJfQoKCXBjaV9zZXRfbWFzdGVyKHBkZXYpOwoKCWMgPSBpMm9faW9wX2FsbG9jKCk7CglpZiAoSVNfRVJSKGMpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJpMm86IG1lbW9yeSBmb3IgSTJPIGNvbnRyb2xsZXIgY291bGQgbm90IGJlICIKCQkgICAgICAgImFsbG9jYXRlZFxuIik7CgkJcmMgPSBQVFJfRVJSKGMpOwoJCWdvdG8gZGlzYWJsZTsKCX0KCgljLT5wZGV2ID0gcGRldjsKCWMtPmRldmljZSA9IHBkZXYtPmRldjsKCgkvKiBDYXJkcyB0aGF0IGZhbGwgYXBhcnQgaWYgeW91IGhpdCB0aGVtIHdpdGggbGFyZ2UgSS9PIGxvYWRzLi4uICovCglpZiAocGRldi0+dmVuZG9yID09IFBDSV9WRU5ET1JfSURfTkNSICYmIHBkZXYtPmRldmljZSA9PSAweDA2MzApIHsKCQljLT5zaG9ydF9yZXEgPSAxOwoJCXByaW50ayhLRVJOX0lORk8gIiVzOiBTeW1iaW9zIEZDOTIwIHdvcmthcm91bmRzIGFjdGl2YXRlZC5cbiIsCgkJICAgICAgIGMtPm5hbWUpOwoJfQoKCWlmIChwZGV2LT5zdWJzeXN0ZW1fdmVuZG9yID09IFBDSV9WRU5ET1JfSURfUFJPTUlTRSkgewoJCWMtPnByb21pc2UgPSAxOwoJCXByaW50ayhLRVJOX0lORk8gIiVzOiBQcm9taXNlIHdvcmthcm91bmRzIGFjdGl2YXRlZC5cbiIsCgkJICAgICAgIGMtPm5hbWUpOwoJfQoKCS8qIENhcmRzIHRoYXQgZ28gYmFuYW5hcyBpZiB5b3UgcXVpZXNjZSB0aGVtIGJlZm9yZSB5b3UgcmVzZXQgdGhlbS4gKi8KCWlmIChwZGV2LT52ZW5kb3IgPT0gUENJX1ZFTkRPUl9JRF9EUFQpIHsKCQljLT5ub19xdWllc2NlID0gMTsKCQlpZiAocGRldi0+ZGV2aWNlID09IDB4YTUxMSkKCQkJYy0+cmFwdG9yID0gMTsKCX0KCglpZiAoKHJjID0gaTJvX3BjaV9hbGxvYyhjKSkpIHsKCQlwcmludGsoS0VSTl9FUlIgIiVzOiBETUEgLyBJTyBhbGxvY2F0aW9uIGZvciBJMk8gY29udHJvbGxlciAiCgkJICAgICAgICIgZmFpbGVkXG4iLCBjLT5uYW1lKTsKCQlnb3RvIGZyZWVfY29udHJvbGxlcjsKCX0KCglpZiAoaTJvX3BjaV9pcnFfZW5hYmxlKGMpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICIlczogdW5hYmxlIHRvIGVuYWJsZSBpbnRlcnJ1cHRzIGZvciBJMk8gIgoJCSAgICAgICAiY29udHJvbGxlclxuIiwgYy0+bmFtZSk7CgkJZ290byBmcmVlX3BjaTsKCX0KCglpZiAoKHJjID0gaTJvX2lvcF9hZGQoYykpKQoJCWdvdG8gdW5pbnN0YWxsOwoKCXJldHVybiAwOwoKICAgICAgdW5pbnN0YWxsOgoJaTJvX3BjaV9pcnFfZGlzYWJsZShjKTsKCiAgICAgIGZyZWVfcGNpOgoJaTJvX3BjaV9mcmVlKGMpOwoKICAgICAgZnJlZV9jb250cm9sbGVyOgoJaTJvX2lvcF9mcmVlKGMpOwoKICAgICAgZGlzYWJsZToKCXBjaV9kaXNhYmxlX2RldmljZShwZGV2KTsKCglyZXR1cm4gcmM7Cn0KCi8qKgogKglpMm9fcGNpX3JlbW92ZSAtIFJlbW92ZXMgYSBJMk8gY29udHJvbGxlciBmcm9tIHRoZSBzeXN0ZW0KICoJcGRldjogSTJPIGNvbnRyb2xsZXIgd2hpY2ggc2hvdWxkIGJlIHJlbW92ZWQKICoKICoJUmVzZXQgdGhlIEkyTyBjb250cm9sbGVyLCBkaXNhYmxlIGludGVycnVwdHMgYW5kIHJlbW92ZSBhbGwgYWxsb2NhdGVkCiAqCXJlc291cmNlcy4KICovCnN0YXRpYyB2b2lkIF9fZGV2ZXhpdCBpMm9fcGNpX3JlbW92ZShzdHJ1Y3QgcGNpX2RldiAqcGRldikKewoJc3RydWN0IGkyb19jb250cm9sbGVyICpjOwoJYyA9IHBjaV9nZXRfZHJ2ZGF0YShwZGV2KTsKCglpMm9faW9wX3JlbW92ZShjKTsKCWkyb19wY2lfaXJxX2Rpc2FibGUoYyk7CglpMm9fcGNpX2ZyZWUoYyk7CgoJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IENvbnRyb2xsZXIgcmVtb3ZlZC5cbiIsIGMtPm5hbWUpOwoKCWkyb19pb3BfZnJlZShjKTsKCXBjaV9kaXNhYmxlX2RldmljZShwZGV2KTsKfTsKCi8qIFBDSSBkcml2ZXIgZm9yIEkyTyBjb250cm9sbGVyICovCnN0YXRpYyBzdHJ1Y3QgcGNpX2RyaXZlciBpMm9fcGNpX2RyaXZlciA9IHsKCS5uYW1lID0gIkkyTyBjb250cm9sbGVyIiwKCS5pZF90YWJsZSA9IGkyb19wY2lfaWRzLAoJLnByb2JlID0gaTJvX3BjaV9wcm9iZSwKCS5yZW1vdmUgPSBfX2RldmV4aXRfcChpMm9fcGNpX3JlbW92ZSksCn07CgovKioKICoJaTJvX3BjaV9pbml0IC0gcmVnaXN0ZXJzIEkyTyBQQ0kgZHJpdmVyIGluIFBDSSBzdWJzeXN0ZW0KICoKICoJUmV0dXJucyA+IDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwppbnQgX19pbml0IGkyb19wY2lfaW5pdCh2b2lkKQp7CglyZXR1cm4gcGNpX3JlZ2lzdGVyX2RyaXZlcigmaTJvX3BjaV9kcml2ZXIpOwp9OwoKLyoqCiAqCWkyb19wY2lfZXhpdCAtIHVucmVnaXN0ZXJzIEkyTyBQQ0kgZHJpdmVyIGZyb20gUENJIHN1YnN5c3RlbQogKi8Kdm9pZCBfX2V4aXQgaTJvX3BjaV9leGl0KHZvaWQpCnsKCXBjaV91bnJlZ2lzdGVyX2RyaXZlcigmaTJvX3BjaV9kcml2ZXIpOwp9OwoKRVhQT1JUX1NZTUJPTChpMm9fZG1hX3JlYWxsb2MpOwpNT0RVTEVfREVWSUNFX1RBQkxFKHBjaSwgaTJvX3BjaV9pZHMpOwo=