LyoKICoJUENJIGhhbmRsaW5nIG9mIEkyTyBjb250cm9sbGVyCiAqCiAqIAlDb3B5cmlnaHQgKEMpIDE5OTktMjAwMglSZWQgSGF0IFNvZnR3YXJlCiAqCiAqCVdyaXR0ZW4gYnkgQWxhbiBDb3gsIEJ1aWxkaW5nIE51bWJlciBUaHJlZSBMdGQKICoKICoJVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICoJdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlCiAqCUZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIKICoJb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICoJQSBsb3Qgb2YgdGhlIEkyTyBtZXNzYWdlIHNpZGUgY29kZSBmcm9tIHRoaXMgaXMgdGFrZW4gZnJvbSB0aGUgUmVkCiAqCUNyZWVrIFJDUENJNDUgYWRhcHRlciBkcml2ZXIgYnkgUmVkIENyZWVrIENvbW11bmljYXRpb25zCiAqCiAqCUZpeGVzL2FkZGl0aW9uczoKICoJCVBoaWxpcHAgUnVtcGYKICoJCUp1aGEgU2llduRuZW4gPEp1aGEuU2lldmFuZW5AY3MuSGVsc2lua2kuRkk+CiAqCQlBdXZvIEjka2tpbmVuIDxBdXZvLkhha2tpbmVuQGNzLkhlbHNpbmtpLkZJPgogKgkJRGVlcGFrIFNheGVuYSA8ZGVlcGFrQHBsZXhpdHkubmV0PgogKgkJQm9qaSBUIEthbm5hbnRoYW5hbSA8Ym9qaS50Lmthbm5hbnRoYW5hbUBpbnRlbC5jb20+CiAqCQlBbGFuIENveCA8YWxhbkByZWRoYXQuY29tPjoKICoJCQlQb3J0ZWQgdG8gTGludXggMi41LgogKgkJTWFya3VzIExpZGVsIDxNYXJrdXMuTGlkZWxAc2hhZG93Y29ubmVjdC5jb20+OgogKgkJCU1pbm9yIGZpeGVzIGZvciAyLjYuCiAqCQlNYXJrdXMgTGlkZWwgPE1hcmt1cy5MaWRlbEBzaGFkb3djb25uZWN0LmNvbT46CiAqCQkJU3VwcG9ydCBmb3Igc3lzZnMgaW5jbHVkZWQuCiAqLwoKI2luY2x1ZGUgPGxpbnV4L3BjaS5oPgojaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+CiNpbmNsdWRlIDxsaW51eC9pMm8uaD4KI2luY2x1ZGUgImNvcmUuaCIKCiNkZWZpbmUgT1NNX0RFU0NSSVBUSU9OCSJJMk8tc3Vic3lzdGVtIgoKLyogUENJIGRldmljZSBpZCB0YWJsZSBmb3IgYWxsIEkyTyBjb250cm9sbGVycyAqLwpzdGF0aWMgc3RydWN0IHBjaV9kZXZpY2VfaWQgX19kZXZpbml0ZGF0YSBpMm9fcGNpX2lkc1tdID0gewoJe1BDSV9ERVZJQ0VfQ0xBU1MoUENJX0NMQVNTX0lOVEVMTElHRU5UX0kyTyA8PCA4LCAweGZmZmYwMCl9LAoJe1BDSV9ERVZJQ0UoUENJX1ZFTkRPUl9JRF9EUFQsIDB4YTUxMSl9LAoJey52ZW5kb3IgPSBQQ0lfVkVORE9SX0lEX0lOVEVMLC5kZXZpY2UgPSAweDE5NjIsCgkgLnN1YnZlbmRvciA9IFBDSV9WRU5ET1JfSURfUFJPTUlTRSwuc3ViZGV2aWNlID0gUENJX0FOWV9JRH0sCgl7MH0KfTsKCi8qKgogKglpMm9fcGNpX2ZyZWUgLSBGcmVlcyB0aGUgRE1BIG1lbW9yeSBmb3IgdGhlIEkyTyBjb250cm9sbGVyCiAqCUBjOiBJMk8gY29udHJvbGxlciB0byBmcmVlCiAqCiAqCVJlbW92ZSBhbGwgYWxsb2NhdGVkIERNQSBtZW1vcnkgYW5kIHVubWFwIG1lbW9yeSBJTyByZWdpb25zLiBJZiBNVFJSCiAqCWlzIGVuYWJsZWQsIGFsc28gcmVtb3ZlIGl0IGFnYWluLgogKi8Kc3RhdGljIHZvaWQgaTJvX3BjaV9mcmVlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IGRldmljZSAqZGV2OwoKCWRldiA9ICZjLT5wZGV2LT5kZXY7CgoJaTJvX2RtYV9mcmVlKGRldiwgJmMtPm91dF9xdWV1ZSk7CglpMm9fZG1hX2ZyZWUoZGV2LCAmYy0+c3RhdHVzX2Jsb2NrKTsKCWtmcmVlKGMtPmxjdCk7CglpMm9fZG1hX2ZyZWUoZGV2LCAmYy0+ZGxjdCk7CglpMm9fZG1hX2ZyZWUoZGV2LCAmYy0+aHJ0KTsKCWkyb19kbWFfZnJlZShkZXYsICZjLT5zdGF0dXMpOwoKCWlmIChjLT5yYXB0b3IgJiYgYy0+aW5fcXVldWUudmlydCkKCQlpb3VubWFwKGMtPmluX3F1ZXVlLnZpcnQpOwoKCWlmIChjLT5iYXNlLnZpcnQpCgkJaW91bm1hcChjLT5iYXNlLnZpcnQpOwoKCXBjaV9yZWxlYXNlX3JlZ2lvbnMoYy0+cGRldik7Cn0KCi8qKgogKglpMm9fcGNpX2FsbG9jIC0gQWxsb2NhdGUgRE1BIG1lbW9yeSwgbWFwIElPIG1lbW9yeSBmb3IgSTJPIGNvbnRyb2xsZXIKICoJQGM6IEkyTyBjb250cm9sbGVyCiAqCiAqCUFsbG9jYXRlIERNQSBtZW1vcnkgZm9yIGEgUENJIChvciBpbiB0aGVvcnkgQUdQKSBJMk8gY29udHJvbGxlci4gQWxsCiAqCUlPIG1hcHBpbmdzIGFyZSBhbHNvIGRvbmUgaGVyZS4gSWYgTVRSUiBpcyBlbmFibGVkLCBhbHNvIGRvIGFkZCBtZW1vcnkKICoJcmVnaW9ucyBoZXJlLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwpzdGF0aWMgaW50IF9fZGV2aW5pdCBpMm9fcGNpX2FsbG9jKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IHBjaV9kZXYgKnBkZXYgPSBjLT5wZGV2OwoJc3RydWN0IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsKCWludCBpOwoKCWZvciAoaSA9IDA7IGkgPCA2OyBpKyspIHsKCQkvKiBTa2lwIEkvTyBzcGFjZXMgKi8KCQlpZiAoIShwY2lfcmVzb3VyY2VfZmxhZ3MocGRldiwgaSkgJiBJT1JFU09VUkNFX0lPKSkgewoJCQlpZiAoIWMtPmJhc2UucGh5cykgewoJCQkJYy0+YmFzZS5waHlzID0gcGNpX3Jlc291cmNlX3N0YXJ0KHBkZXYsIGkpOwoJCQkJYy0+YmFzZS5sZW4gPSBwY2lfcmVzb3VyY2VfbGVuKHBkZXYsIGkpOwoKCQkJCS8qCgkJCQkgKiBJZiB3ZSBrbm93IHdoYXQgY2FyZCBpdCBpcywgc2V0IHRoZSBzaXplCgkJCQkgKiBjb3JyZWN0bHkuIENvZGUgaXMgdGFrZW4gZnJvbSBkcHRfaTJvLmMKCQkJCSAqLwoJCQkJaWYgKHBkZXYtPmRldmljZSA9PSAweGE1MDEpIHsKCQkJCQlpZiAocGRldi0+c3Vic3lzdGVtX2RldmljZSA+PSAweGMwMzIgJiYKCQkJCQkgICAgcGRldi0+c3Vic3lzdGVtX2RldmljZSA8PSAweGMwM2IpIHsKCQkJCQkJaWYgKGMtPmJhc2UubGVuID4gMHg0MDAwMDApCgkJCQkJCQljLT5iYXNlLmxlbiA9IDB4NDAwMDAwOwoJCQkJCX0gZWxzZSB7CgkJCQkJCWlmIChjLT5iYXNlLmxlbiA+IDB4MTAwMDAwKQoJCQkJCQkJYy0+YmFzZS5sZW4gPSAweDEwMDAwMDsKCQkJCQl9CgkJCQl9CgkJCQlpZiAoIWMtPnJhcHRvcikKCQkJCQlicmVhazsKCQkJfSBlbHNlIHsKCQkJCWMtPmluX3F1ZXVlLnBoeXMgPSBwY2lfcmVzb3VyY2Vfc3RhcnQocGRldiwgaSk7CgkJCQljLT5pbl9xdWV1ZS5sZW4gPSBwY2lfcmVzb3VyY2VfbGVuKHBkZXYsIGkpOwoJCQkJYnJlYWs7CgkJCX0KCQl9Cgl9CgoJaWYgKGkgPT0gNikgewoJCXByaW50ayhLRVJOX0VSUiAiJXM6IEkyTyBjb250cm9sbGVyIGhhcyBubyBtZW1vcnkgcmVnaW9ucyIKCQkgICAgICAgIiBkZWZpbmVkLlxuIiwgYy0+bmFtZSk7CgkJaTJvX3BjaV9mcmVlKGMpOwoJCXJldHVybiAtRUlOVkFMOwoJfQoKCS8qIE1hcCB0aGUgSTJPIGNvbnRyb2xsZXIgKi8KCWlmIChjLT5yYXB0b3IpIHsKCQlwcmludGsoS0VSTl9JTkZPICIlczogUENJIEkyTyBjb250cm9sbGVyXG4iLCBjLT5uYW1lKTsKCQlwcmludGsoS0VSTl9JTkZPICIgICAgIEJBUjAgYXQgMHglMDhsWCBzaXplPSVsZFxuIiwKCQkgICAgICAgKHVuc2lnbmVkIGxvbmcpYy0+YmFzZS5waHlzLCAodW5zaWduZWQgbG9uZyljLT5iYXNlLmxlbik7CgkJcHJpbnRrKEtFUk5fSU5GTyAiICAgICBCQVIxIGF0IDB4JTA4bFggc2l6ZT0lbGRcbiIsCgkJICAgICAgICh1bnNpZ25lZCBsb25nKWMtPmluX3F1ZXVlLnBoeXMsCgkJICAgICAgICh1bnNpZ25lZCBsb25nKWMtPmluX3F1ZXVlLmxlbik7Cgl9IGVsc2UKCQlwcmludGsoS0VSTl9JTkZPICIlczogUENJIEkyTyBjb250cm9sbGVyIGF0ICUwOGxYIHNpemU9JWxkXG4iLAoJCSAgICAgICBjLT5uYW1lLCAodW5zaWduZWQgbG9uZyljLT5iYXNlLnBoeXMsCgkJICAgICAgICh1bnNpZ25lZCBsb25nKWMtPmJhc2UubGVuKTsKCgljLT5iYXNlLnZpcnQgPSBpb3JlbWFwX25vY2FjaGUoYy0+YmFzZS5waHlzLCBjLT5iYXNlLmxlbik7CglpZiAoIWMtPmJhc2UudmlydCkgewoJCXByaW50ayhLRVJOX0VSUiAiJXM6IFVuYWJsZSB0byBtYXAgY29udHJvbGxlci5cbiIsIGMtPm5hbWUpOwoJCWkyb19wY2lfZnJlZShjKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCglpZiAoYy0+cmFwdG9yKSB7CgkJYy0+aW5fcXVldWUudmlydCA9CgkJICAgIGlvcmVtYXBfbm9jYWNoZShjLT5pbl9xdWV1ZS5waHlzLCBjLT5pbl9xdWV1ZS5sZW4pOwoJCWlmICghYy0+aW5fcXVldWUudmlydCkgewoJCQlwcmludGsoS0VSTl9FUlIgIiVzOiBVbmFibGUgdG8gbWFwIGNvbnRyb2xsZXIuXG4iLAoJCQkgICAgICAgYy0+bmFtZSk7CgkJCWkyb19wY2lfZnJlZShjKTsKCQkJcmV0dXJuIC1FTk9NRU07CgkJfQoJfSBlbHNlCgkJYy0+aW5fcXVldWUgPSBjLT5iYXNlOwoKCWMtPmlycV9zdGF0dXMgPSBjLT5iYXNlLnZpcnQgKyBJMk9fSVJRX1NUQVRVUzsKCWMtPmlycV9tYXNrID0gYy0+YmFzZS52aXJ0ICsgSTJPX0lSUV9NQVNLOwoJYy0+aW5fcG9ydCA9IGMtPmJhc2UudmlydCArIEkyT19JTl9QT1JUOwoJYy0+b3V0X3BvcnQgPSBjLT5iYXNlLnZpcnQgKyBJMk9fT1VUX1BPUlQ7CgoJaWYgKGkyb19kbWFfYWxsb2MoZGV2LCAmYy0+c3RhdHVzLCA4LCBHRlBfS0VSTkVMKSkgewoJCWkyb19wY2lfZnJlZShjKTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCglpZiAoaTJvX2RtYV9hbGxvYyhkZXYsICZjLT5ocnQsIHNpemVvZihpMm9faHJ0KSwgR0ZQX0tFUk5FTCkpIHsKCQlpMm9fcGNpX2ZyZWUoYyk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgoJaWYgKGkyb19kbWFfYWxsb2MoZGV2LCAmYy0+ZGxjdCwgODE5MiwgR0ZQX0tFUk5FTCkpIHsKCQlpMm9fcGNpX2ZyZWUoYyk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgoJaWYgKGkyb19kbWFfYWxsb2MoZGV2LCAmYy0+c3RhdHVzX2Jsb2NrLCBzaXplb2YoaTJvX3N0YXR1c19ibG9jayksCgkJCSAgR0ZQX0tFUk5FTCkpIHsKCQlpMm9fcGNpX2ZyZWUoYyk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgoJaWYgKGkyb19kbWFfYWxsb2MKCSAgICAoZGV2LCAmYy0+b3V0X3F1ZXVlLAoJICAgICBJMk9fTUFYX09VVEJPVU5EX01TR19GUkFNRVMgKiBJMk9fT1VUQk9VTkRfTVNHX0ZSQU1FX1NJWkUgKgoJICAgICBzaXplb2YodTMyKSwgR0ZQX0tFUk5FTCkpIHsKCQlpMm9fcGNpX2ZyZWUoYyk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgoJcGNpX3NldF9kcnZkYXRhKHBkZXYsIGMpOwoKCXJldHVybiAwOwp9CgovKioKICoJaTJvX3BjaV9pbnRlcnJ1cHQgLSBJbnRlcnJ1cHQgaGFuZGxlciBmb3IgSTJPIGNvbnRyb2xsZXIKICoJQGlycTogaW50ZXJydXB0IGxpbmUKICoJQGRldl9pZDogcG9pbnRlciB0byB0aGUgSTJPIGNvbnRyb2xsZXIKICoJQHI6IHBvaW50ZXIgdG8gcmVnaXN0ZXJzCiAqCiAqCUhhbmRsZSBhbiBpbnRlcnJ1cHQgZnJvbSBhIFBDSSBiYXNlZCBJMk8gY29udHJvbGxlci4gVGhpcyB0dXJucyBvdXQKICoJdG8gYmUgcmF0aGVyIHNpbXBsZS4gV2Uga2VlcCB0aGUgY29udHJvbGxlciBwb2ludGVyIGluIHRoZSBjb29raWUuCiAqLwpzdGF0aWMgaXJxcmV0dXJuX3QgaTJvX3BjaV9pbnRlcnJ1cHQoaW50IGlycSwgdm9pZCAqZGV2X2lkLCBzdHJ1Y3QgcHRfcmVncyAqcikKewoJc3RydWN0IGkyb19jb250cm9sbGVyICpjID0gZGV2X2lkOwoJdTMyIG07CglpcnFyZXR1cm5fdCByYyA9IElSUV9OT05FOwoKCXdoaWxlIChyZWFkbChjLT5pcnFfc3RhdHVzKSAmIEkyT19JUlFfT1VUQk9VTkRfUE9TVCkgewoJCW0gPSByZWFkbChjLT5vdXRfcG9ydCk7CgkJaWYgKG0gPT0gSTJPX1FVRVVFX0VNUFRZKSB7CgkJCS8qCgkJCSAqIE9sZCA5NjAgc3RlcHBpbmdzIGhhZCBhIGJ1ZyBpbiB0aGUgSTJPIHVuaXQgdGhhdAoJCQkgKiBjYXVzZWQgdGhlIHF1ZXVlIHRvIGFwcGVhciBlbXB0eSB3aGVuIGl0IHdhc24ndC4KCQkJICovCgkJCW0gPSByZWFkbChjLT5vdXRfcG9ydCk7CgkJCWlmICh1bmxpa2VseShtID09IEkyT19RVUVVRV9FTVBUWSkpCgkJCQlicmVhazsKCQl9CgoJCS8qIGRpc3BhdGNoIGl0ICovCgkJaWYgKGkyb19kcml2ZXJfZGlzcGF0Y2goYywgbSkpCgkJCS8qIGZsdXNoIGl0IGlmIHJlc3VsdCAhPSAwICovCgkJCWkyb19mbHVzaF9yZXBseShjLCBtKTsKCgkJcmMgPSBJUlFfSEFORExFRDsKCX0KCglyZXR1cm4gcmM7Cn0KCi8qKgogKglpMm9fcGNpX2lycV9lbmFibGUgLSBBbGxvY2F0ZSBpbnRlcnJ1cHQgZm9yIEkyTyBjb250cm9sbGVyCiAqCiAqCUFsbG9jYXRlIGFuIGludGVycnVwdCBmb3IgdGhlIEkyTyBjb250cm9sbGVyLCBhbmQgYWN0aXZhdGUgaW50ZXJydXB0cwogKglvbiB0aGUgSTJPIGNvbnRyb2xsZXIuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIG9yIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4KICovCnN0YXRpYyBpbnQgaTJvX3BjaV9pcnFfZW5hYmxlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IHBjaV9kZXYgKnBkZXYgPSBjLT5wZGV2OwoJaW50IHJjOwoKCXdyaXRlbCgweGZmZmZmZmZmLCBjLT5pcnFfbWFzayk7CgoJaWYgKHBkZXYtPmlycSkgewoJCXJjID0gcmVxdWVzdF9pcnEocGRldi0+aXJxLCBpMm9fcGNpX2ludGVycnVwdCwgU0FfU0hJUlEsCgkJCQkgYy0+bmFtZSwgYyk7CgkJaWYgKHJjIDwgMCkgewoJCQlwcmludGsoS0VSTl9FUlIgIiVzOiB1bmFibGUgdG8gYWxsb2NhdGUgaW50ZXJydXB0ICVkLiIKCQkJICAgICAgICJcbiIsIGMtPm5hbWUsIHBkZXYtPmlycSk7CgkJCXJldHVybiByYzsKCQl9Cgl9CgoJd3JpdGVsKDB4MDAwMDAwMDAsIGMtPmlycV9tYXNrKTsKCglwcmludGsoS0VSTl9JTkZPICIlczogSW5zdGFsbGVkIGF0IElSUSAlZFxuIiwgYy0+bmFtZSwgcGRldi0+aXJxKTsKCglyZXR1cm4gMDsKfQoKLyoqCiAqCWkyb19wY2lfaXJxX2Rpc2FibGUgLSBGcmVlIGludGVycnVwdCBmb3IgSTJPIGNvbnRyb2xsZXIKICoJQGM6IEkyTyBjb250cm9sbGVyCiAqCiAqCURpc2FibGUgaW50ZXJydXB0cyBpbiBJMk8gY29udHJvbGxlciBhbmQgdGhlbiBmcmVlIGludGVycnVwdC4KICovCnN0YXRpYyB2b2lkIGkyb19wY2lfaXJxX2Rpc2FibGUoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7Cgl3cml0ZWwoMHhmZmZmZmZmZiwgYy0+aXJxX21hc2spOwoKCWlmIChjLT5wZGV2LT5pcnEgPiAwKQoJCWZyZWVfaXJxKGMtPnBkZXYtPmlycSwgYyk7Cn0KCi8qKgogKglpMm9fcGNpX3Byb2JlIC0gUHJvYmUgdGhlIFBDSSBkZXZpY2UgZm9yIGFuIEkyTyBjb250cm9sbGVyCiAqCUBkZXY6IFBDSSBkZXZpY2UgdG8gdGVzdAogKglAaWQ6IGlkIHdoaWNoIG1hdGNoZWQgd2l0aCB0aGUgUENJIGRldmljZSBpZCB0YWJsZQogKgogKglQcm9iZSB0aGUgUENJIGRldmljZSBmb3IgYW55IGRldmljZSB3aGljaCBpcyBhIG1lbW9yeSBvZiB0aGUKICoJSW50ZWxsaWdlbnQsIEkyTyBjbGFzcyBvciBhbiBBZGFwdGVjIFplcm8gQ2hhbm5lbCBDb250cm9sbGVyLiBXZQogKglhdHRlbXB0IHRvIHNldCB1cCBlYWNoIHN1Y2ggZGV2aWNlIGFuZCByZWdpc3RlciBpdCB3aXRoIHRoZSBjb3JlLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwpzdGF0aWMgaW50IF9fZGV2aW5pdCBpMm9fcGNpX3Byb2JlKHN0cnVjdCBwY2lfZGV2ICpwZGV2LAoJCQkJICAgY29uc3Qgc3RydWN0IHBjaV9kZXZpY2VfaWQgKmlkKQp7CglzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmM7CglpbnQgcmM7CglzdHJ1Y3QgcGNpX2RldiAqaTk2MCA9IE5VTEw7CglpbnQgcGNpX2Rldl9idXN5ID0gMDsKCglwcmludGsoS0VSTl9JTkZPICJpMm86IENoZWNraW5nIGZvciBQQ0kgSTJPIGNvbnRyb2xsZXJzLi4uXG4iKTsKCglpZiAoKHBkZXYtPmNsYXNzICYgMHhmZikgPiAxKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiaTJvOiAlcyBkb2VzIG5vdCBzdXBwb3J0IEkyTyAxLjUgIgoJCSAgICAgICAiKHNraXBwaW5nKS5cbiIsIHBjaV9uYW1lKHBkZXYpKTsKCQlyZXR1cm4gLUVOT0RFVjsKCX0KCglpZiAoKHJjID0gcGNpX2VuYWJsZV9kZXZpY2UocGRldikpKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiaTJvOiBjb3VsZG4ndCBlbmFibGUgZGV2aWNlICVzXG4iLAoJCSAgICAgICBwY2lfbmFtZShwZGV2KSk7CgkJcmV0dXJuIHJjOwoJfQoKCWlmIChwY2lfcmVxdWVzdF9yZWdpb25zKHBkZXYsIE9TTV9ERVNDUklQVElPTikpIHsKCQlwcmludGsoS0VSTl9FUlIgImkybzogZGV2aWNlIGFscmVhZHkgY2xhaW1lZFxuIik7CgkJcmV0dXJuIC1FTk9ERVY7Cgl9CgoJaWYgKHBjaV9zZXRfZG1hX21hc2socGRldiwgRE1BXzMyQklUX01BU0spKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiaTJvOiBubyBzdWl0YWJsZSBETUEgZm91bmQgZm9yICVzXG4iLAoJCSAgICAgICBwY2lfbmFtZShwZGV2KSk7CgkJcmMgPSAtRU5PREVWOwoJCWdvdG8gZGlzYWJsZTsKCX0KCglwY2lfc2V0X21hc3RlcihwZGV2KTsKCgljID0gaTJvX2lvcF9hbGxvYygpOwoJaWYgKElTX0VSUihjKSkgewoJCXByaW50ayhLRVJOX0VSUiAiaTJvOiBjb3VsZG4ndCBhbGxvY2F0ZSBtZW1vcnkgZm9yICVzXG4iLAoJCSAgICAgICBwY2lfbmFtZShwZGV2KSk7CgkJcmMgPSBQVFJfRVJSKGMpOwoJCWdvdG8gZGlzYWJsZTsKCX0gZWxzZQoJCXByaW50ayhLRVJOX0lORk8gIiVzOiBjb250cm9sbGVyIGZvdW5kICglcylcbiIsIGMtPm5hbWUsCgkJICAgICAgIHBjaV9uYW1lKHBkZXYpKTsKCgljLT5wZGV2ID0gcGRldjsKCWMtPmRldmljZS5wYXJlbnQgPSAmcGRldi0+ZGV2OwoKCS8qIENhcmRzIHRoYXQgZmFsbCBhcGFydCBpZiB5b3UgaGl0IHRoZW0gd2l0aCBsYXJnZSBJL08gbG9hZHMuLi4gKi8KCWlmIChwZGV2LT52ZW5kb3IgPT0gUENJX1ZFTkRPUl9JRF9OQ1IgJiYgcGRldi0+ZGV2aWNlID09IDB4MDYzMCkgewoJCWMtPnNob3J0X3JlcSA9IDE7CgkJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IFN5bWJpb3MgRkM5MjAgd29ya2Fyb3VuZHMgYWN0aXZhdGVkLlxuIiwKCQkgICAgICAgYy0+bmFtZSk7Cgl9CgoJaWYgKHBkZXYtPnN1YnN5c3RlbV92ZW5kb3IgPT0gUENJX1ZFTkRPUl9JRF9QUk9NSVNFKSB7CgkJLyoKCQkgKiBFeHBvc2UgdGhlIHNoaXAgYmVoaW5kIGk5NjAgZm9yIGluaXRpYWxpemF0aW9uLCBvciBpdCB3aWxsCgkJICogZmFpbGVkCgkJICovCgkJaTk2MCA9CgkJICAgIHBjaV9maW5kX3Nsb3QoYy0+cGRldi0+YnVzLT5udW1iZXIsCgkJCQkgIFBDSV9ERVZGTihQQ0lfU0xPVChjLT5wZGV2LT5kZXZmbiksIDApKTsKCgkJaWYgKGk5NjApCgkJCXBjaV93cml0ZV9jb25maWdfd29yZChpOTYwLCAweDQyLCAwKTsKCgkJYy0+cHJvbWlzZSA9IDE7CgkJYy0+bGltaXRfc2VjdG9ycyA9IDE7Cgl9CgoJaWYgKHBkZXYtPnN1YnN5c3RlbV92ZW5kb3IgPT0gUENJX1ZFTkRPUl9JRF9EUFQpCgkJYy0+YWRhcHRlYyA9IDE7CgoJLyogQ2FyZHMgdGhhdCBnbyBiYW5hbmFzIGlmIHlvdSBxdWllc2NlIHRoZW0gYmVmb3JlIHlvdSByZXNldCB0aGVtLiAqLwoJaWYgKHBkZXYtPnZlbmRvciA9PSBQQ0lfVkVORE9SX0lEX0RQVCkgewoJCWMtPm5vX3F1aWVzY2UgPSAxOwoJCWlmIChwZGV2LT5kZXZpY2UgPT0gMHhhNTExKQoJCQljLT5yYXB0b3IgPSAxOwoKCQlpZiAocGRldi0+c3Vic3lzdGVtX2RldmljZSA9PSAweGMwNWEpIHsKCQkJYy0+bGltaXRfc2VjdG9ycyA9IDE7CgkJCXByaW50ayhLRVJOX0lORk8KCQkJICAgICAgICIlczogbGltaXQgc2VjdG9ycyBwZXIgcmVxdWVzdCB0byAlZFxuIiwgYy0+bmFtZSwKCQkJICAgICAgIEkyT19NQVhfU0VDVE9SU19MSU1JVEVEKTsKCQl9CiNpZmRlZiBDT05GSUdfSTJPX0VYVF9BREFQVEVDX0RNQTY0CgkJaWYgKHNpemVvZihkbWFfYWRkcl90KSA+IDQpIHsKCQkJaWYgKHBjaV9zZXRfZG1hX21hc2socGRldiwgRE1BXzY0QklUX01BU0spKQoJCQkJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IDY0LWJpdCBETUEgdW5hdmFpbGFibGVcbiIsCgkJCQkgICAgICAgYy0+bmFtZSk7CgkJCWVsc2UgewoJCQkJYy0+cGFlX3N1cHBvcnQgPSAxOwoJCQkJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IHVzaW5nIDY0LWJpdCBETUFcbiIsCgkJCQkgICAgICAgYy0+bmFtZSk7CgkJCX0KCQl9CiNlbmRpZgoJfQoKCWlmICgocmMgPSBpMm9fcGNpX2FsbG9jKGMpKSkgewoJCXByaW50ayhLRVJOX0VSUiAiJXM6IERNQSAvIElPIGFsbG9jYXRpb24gZm9yIEkyTyBjb250cm9sbGVyICIKCQkgICAgICAgIiBmYWlsZWRcbiIsIGMtPm5hbWUpOwoJCWlmIChyYyA9PSAtRU5PREVWKQoJCQlwY2lfZGV2X2J1c3kgPSAxOwoJCWdvdG8gZnJlZV9jb250cm9sbGVyOwoJfQoKCWlmIChpMm9fcGNpX2lycV9lbmFibGUoYykpIHsKCQlwcmludGsoS0VSTl9FUlIgIiVzOiB1bmFibGUgdG8gZW5hYmxlIGludGVycnVwdHMgZm9yIEkyTyAiCgkJICAgICAgICJjb250cm9sbGVyXG4iLCBjLT5uYW1lKTsKCQlnb3RvIGZyZWVfcGNpOwoJfQoKCWlmICgocmMgPSBpMm9faW9wX2FkZChjKSkpCgkJZ290byB1bmluc3RhbGw7CgoJaWYgKGk5NjApCgkJcGNpX3dyaXRlX2NvbmZpZ193b3JkKGk5NjAsIDB4NDIsIDB4MDNmZik7CgoJcmV0dXJuIDA7CgogICAgICB1bmluc3RhbGw6CglpMm9fcGNpX2lycV9kaXNhYmxlKGMpOwoKICAgICAgZnJlZV9wY2k6CglpMm9fcGNpX2ZyZWUoYyk7CgogICAgICBmcmVlX2NvbnRyb2xsZXI6CglpMm9faW9wX2ZyZWUoYyk7CgogICAgICBkaXNhYmxlOgoJaWYgKCFwY2lfZGV2X2J1c3kpCgkJcGNpX2Rpc2FibGVfZGV2aWNlKHBkZXYpOwoKCXJldHVybiByYzsKfQoKLyoqCiAqCWkyb19wY2lfcmVtb3ZlIC0gUmVtb3ZlcyBhIEkyTyBjb250cm9sbGVyIGZyb20gdGhlIHN5c3RlbQogKglwZGV2OiBJMk8gY29udHJvbGxlciB3aGljaCBzaG91bGQgYmUgcmVtb3ZlZAogKgogKglSZXNldCB0aGUgSTJPIGNvbnRyb2xsZXIsIGRpc2FibGUgaW50ZXJydXB0cyBhbmQgcmVtb3ZlIGFsbCBhbGxvY2F0ZWQKICoJcmVzb3VyY2VzLgogKi8Kc3RhdGljIHZvaWQgX19kZXZleGl0IGkyb19wY2lfcmVtb3ZlKHN0cnVjdCBwY2lfZGV2ICpwZGV2KQp7CglzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmM7CgljID0gcGNpX2dldF9kcnZkYXRhKHBkZXYpOwoKCWkyb19pb3BfcmVtb3ZlKGMpOwoJaTJvX3BjaV9pcnFfZGlzYWJsZShjKTsKCWkyb19wY2lfZnJlZShjKTsKCglwY2lfZGlzYWJsZV9kZXZpY2UocGRldik7CgoJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IENvbnRyb2xsZXIgcmVtb3ZlZC5cbiIsIGMtPm5hbWUpOwoKCXB1dF9kZXZpY2UoJmMtPmRldmljZSk7Cn07CgovKiBQQ0kgZHJpdmVyIGZvciBJMk8gY29udHJvbGxlciAqLwpzdGF0aWMgc3RydWN0IHBjaV9kcml2ZXIgaTJvX3BjaV9kcml2ZXIgPSB7CgkubmFtZSA9ICJQQ0lfSTJPIiwKCS5pZF90YWJsZSA9IGkyb19wY2lfaWRzLAoJLnByb2JlID0gaTJvX3BjaV9wcm9iZSwKCS5yZW1vdmUgPSBfX2RldmV4aXRfcChpMm9fcGNpX3JlbW92ZSksCn07CgovKioKICoJaTJvX3BjaV9pbml0IC0gcmVnaXN0ZXJzIEkyTyBQQ0kgZHJpdmVyIGluIFBDSSBzdWJzeXN0ZW0KICoKICoJUmV0dXJucyA+IDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwppbnQgX19pbml0IGkyb19wY2lfaW5pdCh2b2lkKQp7CglyZXR1cm4gcGNpX3JlZ2lzdGVyX2RyaXZlcigmaTJvX3BjaV9kcml2ZXIpOwp9OwoKLyoqCiAqCWkyb19wY2lfZXhpdCAtIHVucmVnaXN0ZXJzIEkyTyBQQ0kgZHJpdmVyIGZyb20gUENJIHN1YnN5c3RlbQogKi8Kdm9pZCBfX2V4aXQgaTJvX3BjaV9leGl0KHZvaWQpCnsKCXBjaV91bnJlZ2lzdGVyX2RyaXZlcigmaTJvX3BjaV9kcml2ZXIpOwp9OwoKTU9EVUxFX0RFVklDRV9UQUJMRShwY2ksIGkyb19wY2lfaWRzKTsK