LyoKICoJUENJIGhhbmRsaW5nIG9mIEkyTyBjb250cm9sbGVyCiAqCiAqIAlDb3B5cmlnaHQgKEMpIDE5OTktMjAwMglSZWQgSGF0IFNvZnR3YXJlCiAqCiAqCVdyaXR0ZW4gYnkgQWxhbiBDb3gsIEJ1aWxkaW5nIE51bWJlciBUaHJlZSBMdGQKICoKICoJVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkgaXQKICoJdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkgdGhlCiAqCUZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIKICoJb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICoJQSBsb3Qgb2YgdGhlIEkyTyBtZXNzYWdlIHNpZGUgY29kZSBmcm9tIHRoaXMgaXMgdGFrZW4gZnJvbSB0aGUgUmVkCiAqCUNyZWVrIFJDUENJNDUgYWRhcHRlciBkcml2ZXIgYnkgUmVkIENyZWVrIENvbW11bmljYXRpb25zCiAqCiAqCUZpeGVzL2FkZGl0aW9uczoKICoJCVBoaWxpcHAgUnVtcGYKICoJCUp1aGEgU2llduRuZW4gPEp1aGEuU2lldmFuZW5AY3MuSGVsc2lua2kuRkk+CiAqCQlBdXZvIEjka2tpbmVuIDxBdXZvLkhha2tpbmVuQGNzLkhlbHNpbmtpLkZJPgogKgkJRGVlcGFrIFNheGVuYSA8ZGVlcGFrQHBsZXhpdHkubmV0PgogKgkJQm9qaSBUIEthbm5hbnRoYW5hbSA8Ym9qaS50Lmthbm5hbnRoYW5hbUBpbnRlbC5jb20+CiAqCQlBbGFuIENveCA8YWxhbkByZWRoYXQuY29tPjoKICoJCQlQb3J0ZWQgdG8gTGludXggMi41LgogKgkJTWFya3VzIExpZGVsIDxNYXJrdXMuTGlkZWxAc2hhZG93Y29ubmVjdC5jb20+OgogKgkJCU1pbm9yIGZpeGVzIGZvciAyLjYuCiAqCQlNYXJrdXMgTGlkZWwgPE1hcmt1cy5MaWRlbEBzaGFkb3djb25uZWN0LmNvbT46CiAqCQkJU3VwcG9ydCBmb3Igc3lzZnMgaW5jbHVkZWQuCiAqLwoKI2luY2x1ZGUgPGxpbnV4L3BjaS5oPgojaW5jbHVkZSA8bGludXgvaW50ZXJydXB0Lmg+CiNpbmNsdWRlIDxsaW51eC9pMm8uaD4KI2luY2x1ZGUgImNvcmUuaCIKCiNkZWZpbmUgT1NNX0RFU0NSSVBUSU9OCSJJMk8tc3Vic3lzdGVtIgoKLyogUENJIGRldmljZSBpZCB0YWJsZSBmb3IgYWxsIEkyTyBjb250cm9sbGVycyAqLwpzdGF0aWMgc3RydWN0IHBjaV9kZXZpY2VfaWQgX19kZXZpbml0ZGF0YSBpMm9fcGNpX2lkc1tdID0gewoJe1BDSV9ERVZJQ0VfQ0xBU1MoUENJX0NMQVNTX0lOVEVMTElHRU5UX0kyTyA8PCA4LCAweGZmZmYwMCl9LAoJe1BDSV9ERVZJQ0UoUENJX1ZFTkRPUl9JRF9EUFQsIDB4YTUxMSl9LAoJey52ZW5kb3IgPSBQQ0lfVkVORE9SX0lEX0lOVEVMLC5kZXZpY2UgPSAweDE5NjIsCgkgLnN1YnZlbmRvciA9IFBDSV9WRU5ET1JfSURfUFJPTUlTRSwuc3ViZGV2aWNlID0gUENJX0FOWV9JRH0sCgl7MH0KfTsKCi8qKgogKglpMm9fcGNpX2ZyZWUgLSBGcmVlcyB0aGUgRE1BIG1lbW9yeSBmb3IgdGhlIEkyTyBjb250cm9sbGVyCiAqCUBjOiBJMk8gY29udHJvbGxlciB0byBmcmVlCiAqCiAqCVJlbW92ZSBhbGwgYWxsb2NhdGVkIERNQSBtZW1vcnkgYW5kIHVubWFwIG1lbW9yeSBJTyByZWdpb25zLiBJZiBNVFJSCiAqCWlzIGVuYWJsZWQsIGFsc28gcmVtb3ZlIGl0IGFnYWluLgogKi8Kc3RhdGljIHZvaWQgaTJvX3BjaV9mcmVlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IGRldmljZSAqZGV2OwoKCWRldiA9ICZjLT5wZGV2LT5kZXY7CgoJaTJvX2RtYV9mcmVlKGRldiwgJmMtPm91dF9xdWV1ZSk7CglpMm9fZG1hX2ZyZWUoZGV2LCAmYy0+c3RhdHVzX2Jsb2NrKTsKCWtmcmVlKGMtPmxjdCk7CglpMm9fZG1hX2ZyZWUoZGV2LCAmYy0+ZGxjdCk7CglpMm9fZG1hX2ZyZWUoZGV2LCAmYy0+aHJ0KTsKCWkyb19kbWFfZnJlZShkZXYsICZjLT5zdGF0dXMpOwoKCWlmIChjLT5yYXB0b3IgJiYgYy0+aW5fcXVldWUudmlydCkKCQlpb3VubWFwKGMtPmluX3F1ZXVlLnZpcnQpOwoKCWlmIChjLT5iYXNlLnZpcnQpCgkJaW91bm1hcChjLT5iYXNlLnZpcnQpOwoKCXBjaV9yZWxlYXNlX3JlZ2lvbnMoYy0+cGRldik7Cn0KCi8qKgogKglpMm9fcGNpX2FsbG9jIC0gQWxsb2NhdGUgRE1BIG1lbW9yeSwgbWFwIElPIG1lbW9yeSBmb3IgSTJPIGNvbnRyb2xsZXIKICoJQGM6IEkyTyBjb250cm9sbGVyCiAqCiAqCUFsbG9jYXRlIERNQSBtZW1vcnkgZm9yIGEgUENJIChvciBpbiB0aGVvcnkgQUdQKSBJMk8gY29udHJvbGxlci4gQWxsCiAqCUlPIG1hcHBpbmdzIGFyZSBhbHNvIGRvbmUgaGVyZS4gSWYgTVRSUiBpcyBlbmFibGVkLCBhbHNvIGRvIGFkZCBtZW1vcnkKICoJcmVnaW9ucyBoZXJlLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwpzdGF0aWMgaW50IF9fZGV2aW5pdCBpMm9fcGNpX2FsbG9jKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJc3RydWN0IHBjaV9kZXYgKnBkZXYgPSBjLT5wZGV2OwoJc3RydWN0IGRldmljZSAqZGV2ID0gJnBkZXYtPmRldjsKCWludCBpOwoKCWlmIChwY2lfcmVxdWVzdF9yZWdpb25zKHBkZXYsIE9TTV9ERVNDUklQVElPTikpIHsKCQlwcmludGsoS0VSTl9FUlIgIiVzOiBkZXZpY2UgYWxyZWFkeSBjbGFpbWVkXG4iLCBjLT5uYW1lKTsKCQlyZXR1cm4gLUVOT0RFVjsKCX0KCglmb3IgKGkgPSAwOyBpIDwgNjsgaSsrKSB7CgkJLyogU2tpcCBJL08gc3BhY2VzICovCgkJaWYgKCEocGNpX3Jlc291cmNlX2ZsYWdzKHBkZXYsIGkpICYgSU9SRVNPVVJDRV9JTykpIHsKCQkJaWYgKCFjLT5iYXNlLnBoeXMpIHsKCQkJCWMtPmJhc2UucGh5cyA9IHBjaV9yZXNvdXJjZV9zdGFydChwZGV2LCBpKTsKCQkJCWMtPmJhc2UubGVuID0gcGNpX3Jlc291cmNlX2xlbihwZGV2LCBpKTsKCgkJCQkvKgoJCQkJICogSWYgd2Uga25vdyB3aGF0IGNhcmQgaXQgaXMsIHNldCB0aGUgc2l6ZQoJCQkJICogY29ycmVjdGx5LiBDb2RlIGlzIHRha2VuIGZyb20gZHB0X2kyby5jCgkJCQkgKi8KCQkJCWlmIChwZGV2LT5kZXZpY2UgPT0gMHhhNTAxKSB7CgkJCQkJaWYgKHBkZXYtPnN1YnN5c3RlbV9kZXZpY2UgPj0gMHhjMDMyICYmCgkJCQkJICAgIHBkZXYtPnN1YnN5c3RlbV9kZXZpY2UgPD0gMHhjMDNiKSB7CgkJCQkJCWlmIChjLT5iYXNlLmxlbiA+IDB4NDAwMDAwKQoJCQkJCQkJYy0+YmFzZS5sZW4gPSAweDQwMDAwMDsKCQkJCQl9IGVsc2UgewoJCQkJCQlpZiAoYy0+YmFzZS5sZW4gPiAweDEwMDAwMCkKCQkJCQkJCWMtPmJhc2UubGVuID0gMHgxMDAwMDA7CgkJCQkJfQoJCQkJfQoJCQkJaWYgKCFjLT5yYXB0b3IpCgkJCQkJYnJlYWs7CgkJCX0gZWxzZSB7CgkJCQljLT5pbl9xdWV1ZS5waHlzID0gcGNpX3Jlc291cmNlX3N0YXJ0KHBkZXYsIGkpOwoJCQkJYy0+aW5fcXVldWUubGVuID0gcGNpX3Jlc291cmNlX2xlbihwZGV2LCBpKTsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJfQoKCWlmIChpID09IDYpIHsKCQlwcmludGsoS0VSTl9FUlIgIiVzOiBJMk8gY29udHJvbGxlciBoYXMgbm8gbWVtb3J5IHJlZ2lvbnMiCgkJICAgICAgICIgZGVmaW5lZC5cbiIsIGMtPm5hbWUpOwoJCWkyb19wY2lfZnJlZShjKTsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCgkvKiBNYXAgdGhlIEkyTyBjb250cm9sbGVyICovCglpZiAoYy0+cmFwdG9yKSB7CgkJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IFBDSSBJMk8gY29udHJvbGxlclxuIiwgYy0+bmFtZSk7CgkJcHJpbnRrKEtFUk5fSU5GTyAiICAgICBCQVIwIGF0IDB4JTA4bFggc2l6ZT0lbGRcbiIsCgkJICAgICAgICh1bnNpZ25lZCBsb25nKWMtPmJhc2UucGh5cywgKHVuc2lnbmVkIGxvbmcpYy0+YmFzZS5sZW4pOwoJCXByaW50ayhLRVJOX0lORk8gIiAgICAgQkFSMSBhdCAweCUwOGxYIHNpemU9JWxkXG4iLAoJCSAgICAgICAodW5zaWduZWQgbG9uZyljLT5pbl9xdWV1ZS5waHlzLAoJCSAgICAgICAodW5zaWduZWQgbG9uZyljLT5pbl9xdWV1ZS5sZW4pOwoJfSBlbHNlCgkJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IFBDSSBJMk8gY29udHJvbGxlciBhdCAlMDhsWCBzaXplPSVsZFxuIiwKCQkgICAgICAgYy0+bmFtZSwgKHVuc2lnbmVkIGxvbmcpYy0+YmFzZS5waHlzLAoJCSAgICAgICAodW5zaWduZWQgbG9uZyljLT5iYXNlLmxlbik7CgoJYy0+YmFzZS52aXJ0ID0gaW9yZW1hcF9ub2NhY2hlKGMtPmJhc2UucGh5cywgYy0+YmFzZS5sZW4pOwoJaWYgKCFjLT5iYXNlLnZpcnQpIHsKCQlwcmludGsoS0VSTl9FUlIgIiVzOiBVbmFibGUgdG8gbWFwIGNvbnRyb2xsZXIuXG4iLCBjLT5uYW1lKTsKCQlpMm9fcGNpX2ZyZWUoYyk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgoJaWYgKGMtPnJhcHRvcikgewoJCWMtPmluX3F1ZXVlLnZpcnQgPQoJCSAgICBpb3JlbWFwX25vY2FjaGUoYy0+aW5fcXVldWUucGh5cywgYy0+aW5fcXVldWUubGVuKTsKCQlpZiAoIWMtPmluX3F1ZXVlLnZpcnQpIHsKCQkJcHJpbnRrKEtFUk5fRVJSICIlczogVW5hYmxlIHRvIG1hcCBjb250cm9sbGVyLlxuIiwKCQkJICAgICAgIGMtPm5hbWUpOwoJCQlpMm9fcGNpX2ZyZWUoYyk7CgkJCXJldHVybiAtRU5PTUVNOwoJCX0KCX0gZWxzZQoJCWMtPmluX3F1ZXVlID0gYy0+YmFzZTsKCgljLT5pcnFfc3RhdHVzID0gYy0+YmFzZS52aXJ0ICsgSTJPX0lSUV9TVEFUVVM7CgljLT5pcnFfbWFzayA9IGMtPmJhc2UudmlydCArIEkyT19JUlFfTUFTSzsKCWMtPmluX3BvcnQgPSBjLT5iYXNlLnZpcnQgKyBJMk9fSU5fUE9SVDsKCWMtPm91dF9wb3J0ID0gYy0+YmFzZS52aXJ0ICsgSTJPX09VVF9QT1JUOwoKCWlmIChpMm9fZG1hX2FsbG9jKGRldiwgJmMtPnN0YXR1cywgOCwgR0ZQX0tFUk5FTCkpIHsKCQlpMm9fcGNpX2ZyZWUoYyk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CgoJaWYgKGkyb19kbWFfYWxsb2MoZGV2LCAmYy0+aHJ0LCBzaXplb2YoaTJvX2hydCksIEdGUF9LRVJORUwpKSB7CgkJaTJvX3BjaV9mcmVlKGMpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCWlmIChpMm9fZG1hX2FsbG9jKGRldiwgJmMtPmRsY3QsIDgxOTIsIEdGUF9LRVJORUwpKSB7CgkJaTJvX3BjaV9mcmVlKGMpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCWlmIChpMm9fZG1hX2FsbG9jKGRldiwgJmMtPnN0YXR1c19ibG9jaywgc2l6ZW9mKGkyb19zdGF0dXNfYmxvY2spLAoJCQkgIEdGUF9LRVJORUwpKSB7CgkJaTJvX3BjaV9mcmVlKGMpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCWlmIChpMm9fZG1hX2FsbG9jCgkgICAgKGRldiwgJmMtPm91dF9xdWV1ZSwKCSAgICAgSTJPX01BWF9PVVRCT1VORF9NU0dfRlJBTUVTICogSTJPX09VVEJPVU5EX01TR19GUkFNRV9TSVpFICoKCSAgICAgc2l6ZW9mKHUzMiksIEdGUF9LRVJORUwpKSB7CgkJaTJvX3BjaV9mcmVlKGMpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoKCXBjaV9zZXRfZHJ2ZGF0YShwZGV2LCBjKTsKCglyZXR1cm4gMDsKfQoKLyoqCiAqCWkyb19wY2lfaW50ZXJydXB0IC0gSW50ZXJydXB0IGhhbmRsZXIgZm9yIEkyTyBjb250cm9sbGVyCiAqCUBpcnE6IGludGVycnVwdCBsaW5lCiAqCUBkZXZfaWQ6IHBvaW50ZXIgdG8gdGhlIEkyTyBjb250cm9sbGVyCiAqCUByOiBwb2ludGVyIHRvIHJlZ2lzdGVycwogKgogKglIYW5kbGUgYW4gaW50ZXJydXB0IGZyb20gYSBQQ0kgYmFzZWQgSTJPIGNvbnRyb2xsZXIuIFRoaXMgdHVybnMgb3V0CiAqCXRvIGJlIHJhdGhlciBzaW1wbGUuIFdlIGtlZXAgdGhlIGNvbnRyb2xsZXIgcG9pbnRlciBpbiB0aGUgY29va2llLgogKi8Kc3RhdGljIGlycXJldHVybl90IGkyb19wY2lfaW50ZXJydXB0KGludCBpcnEsIHZvaWQgKmRldl9pZCwgc3RydWN0IHB0X3JlZ3MgKnIpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYyA9IGRldl9pZDsKCXUzMiBtOwoJaXJxcmV0dXJuX3QgcmMgPSBJUlFfTk9ORTsKCgl3aGlsZSAocmVhZGwoYy0+aXJxX3N0YXR1cykgJiBJMk9fSVJRX09VVEJPVU5EX1BPU1QpIHsKCQltID0gcmVhZGwoYy0+b3V0X3BvcnQpOwoJCWlmIChtID09IEkyT19RVUVVRV9FTVBUWSkgewoJCQkvKgoJCQkgKiBPbGQgOTYwIHN0ZXBwaW5ncyBoYWQgYSBidWcgaW4gdGhlIEkyTyB1bml0IHRoYXQKCQkJICogY2F1c2VkIHRoZSBxdWV1ZSB0byBhcHBlYXIgZW1wdHkgd2hlbiBpdCB3YXNuJ3QuCgkJCSAqLwoJCQltID0gcmVhZGwoYy0+b3V0X3BvcnQpOwoJCQlpZiAodW5saWtlbHkobSA9PSBJMk9fUVVFVUVfRU1QVFkpKQoJCQkJYnJlYWs7CgkJfQoKCQkvKiBkaXNwYXRjaCBpdCAqLwoJCWlmIChpMm9fZHJpdmVyX2Rpc3BhdGNoKGMsIG0pKQoJCQkvKiBmbHVzaCBpdCBpZiByZXN1bHQgIT0gMCAqLwoJCQlpMm9fZmx1c2hfcmVwbHkoYywgbSk7CgoJCXJjID0gSVJRX0hBTkRMRUQ7Cgl9CgoJcmV0dXJuIHJjOwp9CgovKioKICoJaTJvX3BjaV9pcnFfZW5hYmxlIC0gQWxsb2NhdGUgaW50ZXJydXB0IGZvciBJMk8gY29udHJvbGxlcgogKgogKglBbGxvY2F0ZSBhbiBpbnRlcnJ1cHQgZm9yIHRoZSBJMk8gY29udHJvbGxlciwgYW5kIGFjdGl2YXRlIGludGVycnVwdHMKICoJb24gdGhlIEkyTyBjb250cm9sbGVyLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwpzdGF0aWMgaW50IGkyb19wY2lfaXJxX2VuYWJsZShzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCXN0cnVjdCBwY2lfZGV2ICpwZGV2ID0gYy0+cGRldjsKCWludCByYzsKCgl3cml0ZWwoMHhmZmZmZmZmZiwgYy0+aXJxX21hc2spOwoKCWlmIChwZGV2LT5pcnEpIHsKCQlyYyA9IHJlcXVlc3RfaXJxKHBkZXYtPmlycSwgaTJvX3BjaV9pbnRlcnJ1cHQsIFNBX1NISVJRLAoJCQkJIGMtPm5hbWUsIGMpOwoJCWlmIChyYyA8IDApIHsKCQkJcHJpbnRrKEtFUk5fRVJSICIlczogdW5hYmxlIHRvIGFsbG9jYXRlIGludGVycnVwdCAlZC4iCgkJCSAgICAgICAiXG4iLCBjLT5uYW1lLCBwZGV2LT5pcnEpOwoJCQlyZXR1cm4gcmM7CgkJfQoJfQoKCXdyaXRlbCgweDAwMDAwMDAwLCBjLT5pcnFfbWFzayk7CgoJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IEluc3RhbGxlZCBhdCBJUlEgJWRcbiIsIGMtPm5hbWUsIHBkZXYtPmlycSk7CgoJcmV0dXJuIDA7Cn0KCi8qKgogKglpMm9fcGNpX2lycV9kaXNhYmxlIC0gRnJlZSBpbnRlcnJ1cHQgZm9yIEkyTyBjb250cm9sbGVyCiAqCUBjOiBJMk8gY29udHJvbGxlcgogKgogKglEaXNhYmxlIGludGVycnVwdHMgaW4gSTJPIGNvbnRyb2xsZXIgYW5kIHRoZW4gZnJlZSBpbnRlcnJ1cHQuCiAqLwpzdGF0aWMgdm9pZCBpMm9fcGNpX2lycV9kaXNhYmxlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYykKewoJd3JpdGVsKDB4ZmZmZmZmZmYsIGMtPmlycV9tYXNrKTsKCglpZiAoYy0+cGRldi0+aXJxID4gMCkKCQlmcmVlX2lycShjLT5wZGV2LT5pcnEsIGMpOwp9CgovKioKICoJaTJvX3BjaV9wcm9iZSAtIFByb2JlIHRoZSBQQ0kgZGV2aWNlIGZvciBhbiBJMk8gY29udHJvbGxlcgogKglAZGV2OiBQQ0kgZGV2aWNlIHRvIHRlc3QKICoJQGlkOiBpZCB3aGljaCBtYXRjaGVkIHdpdGggdGhlIFBDSSBkZXZpY2UgaWQgdGFibGUKICoKICoJUHJvYmUgdGhlIFBDSSBkZXZpY2UgZm9yIGFueSBkZXZpY2Ugd2hpY2ggaXMgYSBtZW1vcnkgb2YgdGhlCiAqCUludGVsbGlnZW50LCBJMk8gY2xhc3Mgb3IgYW4gQWRhcHRlYyBaZXJvIENoYW5uZWwgQ29udHJvbGxlci4gV2UKICoJYXR0ZW1wdCB0byBzZXQgdXAgZWFjaCBzdWNoIGRldmljZSBhbmQgcmVnaXN0ZXIgaXQgd2l0aCB0aGUgY29yZS4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8Kc3RhdGljIGludCBfX2RldmluaXQgaTJvX3BjaV9wcm9iZShzdHJ1Y3QgcGNpX2RldiAqcGRldiwKCQkJCSAgIGNvbnN0IHN0cnVjdCBwY2lfZGV2aWNlX2lkICppZCkKewoJc3RydWN0IGkyb19jb250cm9sbGVyICpjOwoJaW50IHJjOwoJc3RydWN0IHBjaV9kZXYgKmk5NjAgPSBOVUxMOwoJaW50IHBjaV9kZXZfYnVzeSA9IDA7CgoJcHJpbnRrKEtFUk5fSU5GTyAiaTJvOiBDaGVja2luZyBmb3IgUENJIEkyTyBjb250cm9sbGVycy4uLlxuIik7CgoJaWYgKChwZGV2LT5jbGFzcyAmIDB4ZmYpID4gMSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkybzogJXMgZG9lcyBub3Qgc3VwcG9ydCBJMk8gMS41ICIKCQkgICAgICAgIihza2lwcGluZykuXG4iLCBwY2lfbmFtZShwZGV2KSk7CgkJcmV0dXJuIC1FTk9ERVY7Cgl9CgoJaWYgKChyYyA9IHBjaV9lbmFibGVfZGV2aWNlKHBkZXYpKSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkybzogY291bGRuJ3QgZW5hYmxlIGRldmljZSAlc1xuIiwKCQkgICAgICAgcGNpX25hbWUocGRldikpOwoJCXJldHVybiByYzsKCX0KCglpZiAocGNpX3NldF9kbWFfbWFzayhwZGV2LCBETUFfMzJCSVRfTUFTSykpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJpMm86IG5vIHN1aXRhYmxlIERNQSBmb3VuZCBmb3IgJXNcbiIsCgkJICAgICAgIHBjaV9uYW1lKHBkZXYpKTsKCQlyYyA9IC1FTk9ERVY7CgkJZ290byBkaXNhYmxlOwoJfQoKCXBjaV9zZXRfbWFzdGVyKHBkZXYpOwoKCWMgPSBpMm9faW9wX2FsbG9jKCk7CglpZiAoSVNfRVJSKGMpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICJpMm86IGNvdWxkbid0IGFsbG9jYXRlIG1lbW9yeSBmb3IgJXNcbiIsCgkJICAgICAgIHBjaV9uYW1lKHBkZXYpKTsKCQlyYyA9IFBUUl9FUlIoYyk7CgkJZ290byBkaXNhYmxlOwoJfSBlbHNlCgkJcHJpbnRrKEtFUk5fSU5GTyAiJXM6IGNvbnRyb2xsZXIgZm91bmQgKCVzKVxuIiwgYy0+bmFtZSwKCQkgICAgICAgcGNpX25hbWUocGRldikpOwoKCWMtPnBkZXYgPSBwZGV2OwoJYy0+ZGV2aWNlLnBhcmVudCA9IGdldF9kZXZpY2UoJnBkZXYtPmRldik7CgoJLyogQ2FyZHMgdGhhdCBmYWxsIGFwYXJ0IGlmIHlvdSBoaXQgdGhlbSB3aXRoIGxhcmdlIEkvTyBsb2Fkcy4uLiAqLwoJaWYgKHBkZXYtPnZlbmRvciA9PSBQQ0lfVkVORE9SX0lEX05DUiAmJiBwZGV2LT5kZXZpY2UgPT0gMHgwNjMwKSB7CgkJYy0+c2hvcnRfcmVxID0gMTsKCQlwcmludGsoS0VSTl9JTkZPICIlczogU3ltYmlvcyBGQzkyMCB3b3JrYXJvdW5kcyBhY3RpdmF0ZWQuXG4iLAoJCSAgICAgICBjLT5uYW1lKTsKCX0KCglpZiAocGRldi0+c3Vic3lzdGVtX3ZlbmRvciA9PSBQQ0lfVkVORE9SX0lEX1BST01JU0UpIHsKCQkvKgoJCSAqIEV4cG9zZSB0aGUgc2hpcCBiZWhpbmQgaTk2MCBmb3IgaW5pdGlhbGl6YXRpb24sIG9yIGl0IHdpbGwKCQkgKiBmYWlsZWQKCQkgKi8KCQlpOTYwID0KCQkgICAgcGNpX2ZpbmRfc2xvdChjLT5wZGV2LT5idXMtPm51bWJlciwKCQkJCSAgUENJX0RFVkZOKFBDSV9TTE9UKGMtPnBkZXYtPmRldmZuKSwgMCkpOwoKCQlpZiAoaTk2MCkKCQkJcGNpX3dyaXRlX2NvbmZpZ193b3JkKGk5NjAsIDB4NDIsIDApOwoKCQljLT5wcm9taXNlID0gMTsKCQljLT5saW1pdF9zZWN0b3JzID0gMTsKCX0KCglpZiAocGRldi0+c3Vic3lzdGVtX3ZlbmRvciA9PSBQQ0lfVkVORE9SX0lEX0RQVCkKCQljLT5hZGFwdGVjID0gMTsKCgkvKiBDYXJkcyB0aGF0IGdvIGJhbmFuYXMgaWYgeW91IHF1aWVzY2UgdGhlbSBiZWZvcmUgeW91IHJlc2V0IHRoZW0uICovCglpZiAocGRldi0+dmVuZG9yID09IFBDSV9WRU5ET1JfSURfRFBUKSB7CgkJYy0+bm9fcXVpZXNjZSA9IDE7CgkJaWYgKHBkZXYtPmRldmljZSA9PSAweGE1MTEpCgkJCWMtPnJhcHRvciA9IDE7CgoJCWlmIChwZGV2LT5zdWJzeXN0ZW1fZGV2aWNlID09IDB4YzA1YSkgewoJCQljLT5saW1pdF9zZWN0b3JzID0gMTsKCQkJcHJpbnRrKEtFUk5fSU5GTwoJCQkgICAgICAgIiVzOiBsaW1pdCBzZWN0b3JzIHBlciByZXF1ZXN0IHRvICVkXG4iLCBjLT5uYW1lLAoJCQkgICAgICAgSTJPX01BWF9TRUNUT1JTX0xJTUlURUQpOwoJCX0KI2lmZGVmIENPTkZJR19JMk9fRVhUX0FEQVBURUNfRE1BNjQKCQlpZiAoc2l6ZW9mKGRtYV9hZGRyX3QpID4gNCkgewoJCQlpZiAocGNpX3NldF9kbWFfbWFzayhwZGV2LCBETUFfNjRCSVRfTUFTSykpCgkJCQlwcmludGsoS0VSTl9JTkZPICIlczogNjQtYml0IERNQSB1bmF2YWlsYWJsZVxuIiwKCQkJCSAgICAgICBjLT5uYW1lKTsKCQkJZWxzZSB7CgkJCQljLT5wYWVfc3VwcG9ydCA9IDE7CgkJCQlwcmludGsoS0VSTl9JTkZPICIlczogdXNpbmcgNjQtYml0IERNQVxuIiwKCQkJCSAgICAgICBjLT5uYW1lKTsKCQkJfQoJCX0KI2VuZGlmCgl9CgoJaWYgKChyYyA9IGkyb19wY2lfYWxsb2MoYykpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICIlczogRE1BIC8gSU8gYWxsb2NhdGlvbiBmb3IgSTJPIGNvbnRyb2xsZXIgIgoJCSAgICAgICAiIGZhaWxlZFxuIiwgYy0+bmFtZSk7CgkJaWYgKHJjID09IC1FTk9ERVYpCgkJCXBjaV9kZXZfYnVzeSA9IDE7CgkJZ290byBmcmVlX2NvbnRyb2xsZXI7Cgl9CgoJaWYgKGkyb19wY2lfaXJxX2VuYWJsZShjKSkgewoJCXByaW50ayhLRVJOX0VSUiAiJXM6IHVuYWJsZSB0byBlbmFibGUgaW50ZXJydXB0cyBmb3IgSTJPICIKCQkgICAgICAgImNvbnRyb2xsZXJcbiIsIGMtPm5hbWUpOwoJCWdvdG8gZnJlZV9wY2k7Cgl9CgoJaWYgKChyYyA9IGkyb19pb3BfYWRkKGMpKSkKCQlnb3RvIHVuaW5zdGFsbDsKCglnZXRfZGV2aWNlKCZjLT5kZXZpY2UpOwoKCWlmIChpOTYwKQoJCXBjaV93cml0ZV9jb25maWdfd29yZChpOTYwLCAweDQyLCAweDAzZmYpOwoKCXJldHVybiAwOwoKICAgICAgdW5pbnN0YWxsOgoJaTJvX3BjaV9pcnFfZGlzYWJsZShjKTsKCiAgICAgIGZyZWVfcGNpOgoJaTJvX3BjaV9mcmVlKGMpOwoKICAgICAgZnJlZV9jb250cm9sbGVyOgoJcHV0X2RldmljZShjLT5kZXZpY2UucGFyZW50KTsKCWkyb19pb3BfZnJlZShjKTsKCiAgICAgIGRpc2FibGU6CglpZiAoIXBjaV9kZXZfYnVzeSkKCQlwY2lfZGlzYWJsZV9kZXZpY2UocGRldik7CgoJcmV0dXJuIHJjOwp9CgovKioKICoJaTJvX3BjaV9yZW1vdmUgLSBSZW1vdmVzIGEgSTJPIGNvbnRyb2xsZXIgZnJvbSB0aGUgc3lzdGVtCiAqCXBkZXY6IEkyTyBjb250cm9sbGVyIHdoaWNoIHNob3VsZCBiZSByZW1vdmVkCiAqCiAqCVJlc2V0IHRoZSBJMk8gY29udHJvbGxlciwgZGlzYWJsZSBpbnRlcnJ1cHRzIGFuZCByZW1vdmUgYWxsIGFsbG9jYXRlZAogKglyZXNvdXJjZXMuCiAqLwpzdGF0aWMgdm9pZCBfX2RldmV4aXQgaTJvX3BjaV9yZW1vdmUoc3RydWN0IHBjaV9kZXYgKnBkZXYpCnsKCXN0cnVjdCBpMm9fY29udHJvbGxlciAqYzsKCWMgPSBwY2lfZ2V0X2RydmRhdGEocGRldik7CgoJaTJvX2lvcF9yZW1vdmUoYyk7CglpMm9fcGNpX2lycV9kaXNhYmxlKGMpOwoJaTJvX3BjaV9mcmVlKGMpOwoKCXBjaV9kaXNhYmxlX2RldmljZShwZGV2KTsKCglwcmludGsoS0VSTl9JTkZPICIlczogQ29udHJvbGxlciByZW1vdmVkLlxuIiwgYy0+bmFtZSk7CgoJcHV0X2RldmljZShjLT5kZXZpY2UucGFyZW50KTsKCXB1dF9kZXZpY2UoJmMtPmRldmljZSk7Cn07CgovKiBQQ0kgZHJpdmVyIGZvciBJMk8gY29udHJvbGxlciAqLwpzdGF0aWMgc3RydWN0IHBjaV9kcml2ZXIgaTJvX3BjaV9kcml2ZXIgPSB7CgkubmFtZSA9ICJQQ0lfSTJPIiwKCS5pZF90YWJsZSA9IGkyb19wY2lfaWRzLAoJLnByb2JlID0gaTJvX3BjaV9wcm9iZSwKCS5yZW1vdmUgPSBfX2RldmV4aXRfcChpMm9fcGNpX3JlbW92ZSksCn07CgovKioKICoJaTJvX3BjaV9pbml0IC0gcmVnaXN0ZXJzIEkyTyBQQ0kgZHJpdmVyIGluIFBDSSBzdWJzeXN0ZW0KICoKICoJUmV0dXJucyA+IDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwppbnQgX19pbml0IGkyb19wY2lfaW5pdCh2b2lkKQp7CglyZXR1cm4gcGNpX3JlZ2lzdGVyX2RyaXZlcigmaTJvX3BjaV9kcml2ZXIpOwp9OwoKLyoqCiAqCWkyb19wY2lfZXhpdCAtIHVucmVnaXN0ZXJzIEkyTyBQQ0kgZHJpdmVyIGZyb20gUENJIHN1YnN5c3RlbQogKi8Kdm9pZCBfX2V4aXQgaTJvX3BjaV9leGl0KHZvaWQpCnsKCXBjaV91bnJlZ2lzdGVyX2RyaXZlcigmaTJvX3BjaV9kcml2ZXIpOwp9OwpNT0RVTEVfREVWSUNFX1RBQkxFKHBjaSwgaTJvX3BjaV9pZHMpOwo=