LyoKICoJRXhlY3V0aXZlIE9TTQogKgogKiAJQ29weXJpZ2h0IChDKSAxOTk5LTIwMDIJUmVkIEhhdCBTb2Z0d2FyZQogKgogKglXcml0dGVuIGJ5IEFsYW4gQ294LCBCdWlsZGluZyBOdW1iZXIgVGhyZWUgTHRkCiAqCiAqCVRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqCXVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZQogKglGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyCiAqCW9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqCUEgbG90IG9mIHRoZSBJMk8gbWVzc2FnZSBzaWRlIGNvZGUgZnJvbSB0aGlzIGlzIHRha2VuIGZyb20gdGhlIFJlZAogKglDcmVlayBSQ1BDSTQ1IGFkYXB0ZXIgZHJpdmVyIGJ5IFJlZCBDcmVlayBDb21tdW5pY2F0aW9ucwogKgogKglGaXhlcy9hZGRpdGlvbnM6CiAqCQlQaGlsaXBwIFJ1bXBmCiAqCQlKdWhhIFNpZXbkbmVuIDxKdWhhLlNpZXZhbmVuQGNzLkhlbHNpbmtpLkZJPgogKgkJQXV2byBI5GtraW5lbiA8QXV2by5IYWtraW5lbkBjcy5IZWxzaW5raS5GST4KICoJCURlZXBhayBTYXhlbmEgPGRlZXBha0BwbGV4aXR5Lm5ldD4KICoJCUJvamkgVCBLYW5uYW50aGFuYW0gPGJvamkudC5rYW5uYW50aGFuYW1AaW50ZWwuY29tPgogKgkJQWxhbiBDb3ggPGFsYW5AcmVkaGF0LmNvbT46CiAqCQkJUG9ydGVkIHRvIExpbnV4IDIuNS4KICoJCU1hcmt1cyBMaWRlbCA8TWFya3VzLkxpZGVsQHNoYWRvd2Nvbm5lY3QuY29tPjoKICoJCQlNaW5vciBmaXhlcyBmb3IgMi42LgogKgkJTWFya3VzIExpZGVsIDxNYXJrdXMuTGlkZWxAc2hhZG93Y29ubmVjdC5jb20+OgogKgkJCVN1cHBvcnQgZm9yIHN5c2ZzIGluY2x1ZGVkLgogKi8KCiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2kyby5oPgojaW5jbHVkZSA8bGludXgvZGVsYXkuaD4KI2luY2x1ZGUgImNvcmUuaCIKCiNkZWZpbmUgT1NNX05BTUUgImV4ZWMtb3NtIgoKc3RydWN0IGkyb19kcml2ZXIgaTJvX2V4ZWNfZHJpdmVyOwoKc3RhdGljIGludCBpMm9fZXhlY19sY3Rfbm90aWZ5KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgdTMyIGNoYW5nZV9pbmQpOwoKLyogZ2xvYmFsIHdhaXQgbGlzdCBmb3IgUE9TVCBXQUlUICovCnN0YXRpYyBMSVNUX0hFQUQoaTJvX2V4ZWNfd2FpdF9saXN0KTsKCi8qIFdhaXQgc3RydWN0IG5lZWRlZCBmb3IgUE9TVCBXQUlUICovCnN0cnVjdCBpMm9fZXhlY193YWl0IHsKCXdhaXRfcXVldWVfaGVhZF90ICp3cTsJLyogUG9pbnRlciB0byBXYWl0IHF1ZXVlICovCglzdHJ1Y3QgaTJvX2RtYSBkbWE7CS8qIERNQSBidWZmZXJzIHRvIGZyZWUgb24gZmFpbHVyZSAqLwoJdTMyIHRjbnR4dDsJCS8qIHRyYW5zYWN0aW9uIGNvbnRleHQgZnJvbSByZXBseSAqLwoJaW50IGNvbXBsZXRlOwkJLyogMSBpZiByZXBseSByZWNlaXZlZCBvdGhlcndpc2UgMCAqLwoJdTMyIG07CQkJLyogbWVzc2FnZSBpZCAqLwoJc3RydWN0IGkyb19tZXNzYWdlICptc2c7CS8qIHBvaW50ZXIgdG8gdGhlIHJlcGx5IG1lc3NhZ2UgKi8KCXN0cnVjdCBsaXN0X2hlYWQgbGlzdDsJLyogbm9kZSBpbiBnbG9iYWwgd2FpdCBsaXN0ICovCn07CgovKiBFeGVjIE9TTSBjbGFzcyBoYW5kbGluZyBkZWZpbml0aW9uICovCnN0YXRpYyBzdHJ1Y3QgaTJvX2NsYXNzX2lkIGkyb19leGVjX2NsYXNzX2lkW10gPSB7Cgl7STJPX0NMQVNTX0VYRUNVVElWRX0sCgl7STJPX0NMQVNTX0VORH0KfTsKCi8qKgogKglpMm9fZXhlY193YWl0X2FsbG9jIC0gQWxsb2NhdGUgYSBpMm9fZXhlY193YWl0IHN0cnVjdCBhbiBpbml0aWFsaXplIGl0CiAqCiAqCUFsbG9jYXRlIHRoZSBpMm9fZXhlY193YWl0IHN0cnVjdCBhbmQgaW5pdGlhbGl6ZSB0aGUgd2FpdC4KICoKICoJUmV0dXJucyBpMm9fZXhlY193YWl0IHBvaW50ZXIgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uCiAqCWZhaWx1cmUuCiAqLwpzdGF0aWMgc3RydWN0IGkyb19leGVjX3dhaXQgKmkyb19leGVjX3dhaXRfYWxsb2Modm9pZCkKewoJc3RydWN0IGkyb19leGVjX3dhaXQgKndhaXQ7CgoJd2FpdCA9IGttYWxsb2Moc2l6ZW9mKCp3YWl0KSwgR0ZQX0tFUk5FTCk7CglpZiAoIXdhaXQpCgkJcmV0dXJuIEVSUl9QVFIoLUVOT01FTSk7CgoJbWVtc2V0KHdhaXQsIDAsIHNpemVvZigqd2FpdCkpOwoKCUlOSVRfTElTVF9IRUFEKCZ3YWl0LT5saXN0KTsKCglyZXR1cm4gd2FpdDsKfTsKCi8qKgogKglpMm9fZXhlY193YWl0X2ZyZWUgLSBGcmVlIGEgaTJvX2V4ZWNfd2FpdCBzdHJ1Y3QKICoJQGkyb19leGVjX3dhaXQ6IEkyTyB3YWl0IGRhdGEgd2hpY2ggc2hvdWxkIGJlIGNsZWFuZWQgdXAKICovCnN0YXRpYyB2b2lkIGkyb19leGVjX3dhaXRfZnJlZShzdHJ1Y3QgaTJvX2V4ZWNfd2FpdCAqd2FpdCkKewoJa2ZyZWUod2FpdCk7Cn07CgovKioKICogCWkyb19tc2dfcG9zdF93YWl0X21lbSAtIFBvc3QgYW5kIHdhaXQgYSBtZXNzYWdlIHdpdGggRE1BIGJ1ZmZlcnMKICoJQGM6IGNvbnRyb2xsZXIKICoJQG06IG1lc3NhZ2UgdG8gcG9zdAogKglAdGltZW91dDogdGltZSBpbiBzZWNvbmRzIHRvIHdhaXQKICoJQGRtYTogaTJvX2RtYSBzdHJ1Y3Qgb2YgdGhlIERNQSBidWZmZXIgdG8gZnJlZSBvbiBmYWlsdXJlCiAqCiAqIAlUaGlzIEFQSSBhbGxvd3MgYW4gT1NNIHRvIHBvc3QgYSBtZXNzYWdlIGFuZCB0aGVuIGJlIHRvbGQgd2hldGhlciBvcgogKglub3QgdGhlIHN5c3RlbSByZWNlaXZlZCBhIHN1Y2Nlc3NmdWwgcmVwbHkuIElmIHRoZSBtZXNzYWdlIHRpbWVzIG91dAogKgl0aGVuIHRoZSB2YWx1ZSAnLUVUSU1FRE9VVCcgaXMgcmV0dXJuZWQuIFRoaXMgaXMgYSBzcGVjaWFsIGNhc2UuIEluCiAqCXRoaXMgc2l0dWF0aW9uIHRoZSBtZXNzYWdlIG1heSAoc2hvdWxkKSBjb21wbGV0ZSBhdCBhbiBpbmRlZmluaXRlIHRpbWUKICoJaW4gdGhlIGZ1dHVyZS4gV2hlbiBpdCBjb21wbGV0ZXMgaXQgd2lsbCB1c2UgdGhlIG1lbW9yeSBidWZmZXIKICoJYXR0YWNoZWQgdG8gdGhlIHJlcXVlc3QuIElmIC1FVElNRURPVVQgaXMgcmV0dXJuZWQgdGhlbiB0aGUgbWVtb3J5CiAqCWJ1ZmZlciBtdXN0IG5vdCBiZSBmcmVlZC4gSW5zdGVhZCB0aGUgZXZlbnQgY29tcGxldGlvbiB3aWxsIGZyZWUgdGhlbQogKglmb3IgeW91LiBJbiBhbGwgb3RoZXIgY2FzZXMgdGhlIGJ1ZmZlciBhcmUgeW91ciBwcm9ibGVtLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcywgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiB0aW1lb3V0IG9yIHBvc2l0aXZlIGVycm9yCiAqCWNvZGUgZnJvbSByZXBseS4KICovCmludCBpMm9fbXNnX3Bvc3Rfd2FpdF9tZW0oc3RydWN0IGkyb19jb250cm9sbGVyICpjLCB1MzIgbSwgdW5zaWduZWQgbG9uZwoJCQkgIHRpbWVvdXQsIHN0cnVjdCBpMm9fZG1hICpkbWEpCnsKCURFQ0xBUkVfV0FJVF9RVUVVRV9IRUFEKHdxKTsKCXN0cnVjdCBpMm9fZXhlY193YWl0ICp3YWl0OwoJc3RhdGljIHUzMiB0Y250eHQgPSAweDgwMDAwMDAwOwoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZyA9IGkyb19tc2dfaW5fdG9fdmlydChjLCBtKTsKCWludCByYyA9IDA7CgoJd2FpdCA9IGkyb19leGVjX3dhaXRfYWxsb2MoKTsKCWlmICghd2FpdCkKCQlyZXR1cm4gLUVOT01FTTsKCglpZiAodGNudHh0ID09IDB4ZmZmZmZmZmYpCgkJdGNudHh0ID0gMHg4MDAwMDAwMDsKCglpZiAoZG1hKQoJCXdhaXQtPmRtYSA9ICpkbWE7CgoJLyoKCSAqIEZpbGwgaW4gdGhlIG1lc3NhZ2UgaW5pdGlhdG9yIGNvbnRleHQgYW5kIHRyYW5zYWN0aW9uIGNvbnRleHQuCgkgKiBXZSB3aWxsIG9ubHkgdXNlIHRyYW5zYWN0aW9uIGNvbnRleHRzID49IDB4ODAwMDAwMDAgZm9yIFBPU1QgV0FJVCwKCSAqIHNvIHdlIGNvdWxkIGZpbmQgYSBQT1NUIFdBSVQgcmVwbHkgZWFzaWVyIGluIHRoZSByZXBseSBoYW5kbGVyLgoJICovCgl3cml0ZWwoaTJvX2V4ZWNfZHJpdmVyLmNvbnRleHQsICZtc2ctPnUucy5pY250eHQpOwoJd2FpdC0+dGNudHh0ID0gdGNudHh0Kys7Cgl3cml0ZWwod2FpdC0+dGNudHh0LCAmbXNnLT51LnMudGNudHh0KTsKCgkvKgoJICogUG9zdCB0aGUgbWVzc2FnZSB0byB0aGUgY29udHJvbGxlci4gQXQgc29tZSBwb2ludCBsYXRlciBpdCB3aWxsCgkgKiByZXR1cm4uIElmIHdlIHRpbWUgb3V0IGJlZm9yZSBpdCByZXR1cm5zIHRoZW4gY29tcGxldGUgd2lsbCBiZSB6ZXJvLgoJICovCglpMm9fbXNnX3Bvc3QoYywgbSk7CgoJaWYgKCF3YWl0LT5jb21wbGV0ZSkgewoJCXdhaXQtPndxID0gJndxOwoJCS8qCgkJICogd2UgYWRkIGVsZW1lbnRzIGFkZCB0aGUgaGVhZCwgYmVjYXVzZSBpZiBhIGVudHJ5IGluIHRoZSBsaXN0CgkJICogd2lsbCBuZXZlciBiZSByZW1vdmVkLCB3ZSBoYXZlIHRvIGl0ZXJhdGUgb3ZlciBpdCBldmVyeSB0aW1lCgkJICovCgkJbGlzdF9hZGQoJndhaXQtPmxpc3QsICZpMm9fZXhlY193YWl0X2xpc3QpOwoKCQl3YWl0X2V2ZW50X2ludGVycnVwdGlibGVfdGltZW91dCh3cSwgd2FpdC0+Y29tcGxldGUsCgkJCQkJCSB0aW1lb3V0ICogSFopOwoKCQl3YWl0LT53cSA9IE5VTEw7Cgl9CgoJYmFycmllcigpOwoKCWlmICh3YWl0LT5jb21wbGV0ZSkgewoJCXJjID0gbGUzMl90b19jcHUod2FpdC0+bXNnLT5ib2R5WzBdKSA+PiAyNDsKCQlpMm9fZmx1c2hfcmVwbHkoYywgd2FpdC0+bSk7CgkJaTJvX2V4ZWNfd2FpdF9mcmVlKHdhaXQpOwoJfSBlbHNlIHsKCQkvKgoJCSAqIFdlIGNhbm5vdCByZW1vdmUgaXQgbm93LiBUaGlzIGlzIGltcG9ydGFudC4gV2hlbiBpdCBkb2VzCgkJICogdGVybWluYXRlICh3aGljaCBpdCBtdXN0IGRvIGlmIHRoZSBjb250cm9sbGVyIGhhcyBub3QKCQkgKiBkaWVkLi4uKSB0aGVuIGl0IHdpbGwgb3RoZXJ3aXNlIHNjcmliYmxlIG9uIHN0dWZmLgoJCSAqCgkJICogRklYTUU6IHRyeSBhYm9ydCBtZXNzYWdlCgkJICovCgkJaWYgKGRtYSkKCQkJZG1hLT52aXJ0ID0gTlVMTDsKCgkJcmMgPSAtRVRJTUVET1VUOwoJfQoKCXJldHVybiByYzsKfTsKCi8qKgogKglpMm9fbXNnX3Bvc3Rfd2FpdF9jb21wbGV0ZSAtIFJlcGx5IHRvIGEgaTJvX21zZ19wb3N0IHJlcXVlc3QgZnJvbSBJT1AKICoJQGM6IEkyTyBjb250cm9sbGVyIHdoaWNoIGFuc3dlcnMKICoJQG06IG1lc3NhZ2UgaWQKICoJQG1zZzogcG9pbnRlciB0byB0aGUgSTJPIHJlcGx5IG1lc3NhZ2UKICoJQGNvbnRleHQ6IHRyYW5zYWN0aW9uIGNvbnRleHQgb2YgcmVxdWVzdAogKgogKglUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBpbiBpbnRlcnJ1cHQgY29udGV4dCBvbmx5LiBJZiB0aGUgcmVwbHkgcmVhY2hlZAogKgliZWZvcmUgdGhlIHRpbWVvdXQsIHRoZSBpMm9fZXhlY193YWl0IHN0cnVjdCBpcyBmaWxsZWQgd2l0aCB0aGUgbWVzc2FnZQogKglhbmQgdGhlIHRhc2sgd2lsbCBiZSB3YWtlZCB1cC4gVGhlIHRhc2sgaXMgbm93IHJlc3BvbnNpYmxlIGZvciByZXR1cm5pbmcKICoJdGhlIG1lc3NhZ2UgbSBiYWNrIHRvIHRoZSBjb250cm9sbGVyISBJZiB0aGUgbWVzc2FnZSByZWFjaGVzIHVzIGFmdGVyCiAqCXRoZSB0aW1lb3V0IGNsZWFuIHVwIHRoZSBpMm9fZXhlY193YWl0IHN0cnVjdCAoaW5jbHVkaW5nIGFsbG9jYXRlZAogKglETUEgYnVmZmVyKS4KICoKICoJUmV0dXJuIDAgb24gc3VjY2VzcyBhbmQgaWYgdGhlIG1lc3NhZ2UgbSBzaG91bGQgbm90IGJlIGdpdmVuIGJhY2sgdG8gdGhlCiAqCUkyTyBjb250cm9sbGVyLCBvciA+MCBvbiBzdWNjZXNzIGFuZCBpZiB0aGUgbWVzc2FnZSBzaG91bGQgYmUgZ2l2ZW4gYmFjawogKglhZnRlcndvcmRzLiBSZXR1cm5zIG5lZ2F0aXZlIGVycm9yIGNvZGUgb24gZmFpbHVyZS4gSW4gdGhpcyBjYXNlIHRoZQogKgltZXNzYWdlIG11c3QgYWxzbyBiZSBnaXZlbiBiYWNrIHRvIHRoZSBjb250cm9sbGVyLgogKi8Kc3RhdGljIGludCBpMm9fbXNnX3Bvc3Rfd2FpdF9jb21wbGV0ZShzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMsIHUzMiBtLAoJCQkJICAgICAgc3RydWN0IGkyb19tZXNzYWdlICptc2csIHUzMiBjb250ZXh0KQp7CglzdHJ1Y3QgaTJvX2V4ZWNfd2FpdCAqd2FpdCwgKnRtcDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglzdGF0aWMgc3BpbmxvY2tfdCBsb2NrID0gU1BJTl9MT0NLX1VOTE9DS0VEOwoJaW50IHJjID0gMTsKCgkvKgoJICogV2UgbmVlZCB0byBzZWFyY2ggdGhyb3VnaCB0aGUgaTJvX2V4ZWNfd2FpdF9saXN0IHRvIHNlZSBpZiB0aGUgZ2l2ZW4KCSAqIG1lc3NhZ2UgaXMgc3RpbGwgb3V0c3RhbmRpbmcuIElmIG5vdCwgaXQgbWVhbnMgdGhhdCB0aGUgSU9QIHRvb2sKCSAqIGxvbmdlciB0byByZXNwb25kIHRvIHRoZSBtZXNzYWdlIHRoYW4gd2UgaGFkIGFsbG93ZWQgYW5kIHRpbWVyIGhhcwoJICogYWxyZWFkeSBleHBpcmVkLiBOb3QgbXVjaCB3ZSBjYW4gZG8gYWJvdXQgdGhhdCBleGNlcHQgbG9nIGl0IGZvcgoJICogZGVidWcgcHVycG9zZXMsIGluY3JlYXNlIHRpbWVvdXQsIGFuZCByZWNvbXBpbGUuCgkgKi8KCXNwaW5fbG9ja19pcnFzYXZlKCZsb2NrLCBmbGFncyk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUod2FpdCwgdG1wLCAmaTJvX2V4ZWNfd2FpdF9saXN0LCBsaXN0KSB7CgkJaWYgKHdhaXQtPnRjbnR4dCA9PSBjb250ZXh0KSB7CgkJCWxpc3RfZGVsKCZ3YWl0LT5saXN0KTsKCgkJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmxvY2ssIGZsYWdzKTsKCgkJCXdhaXQtPm0gPSBtOwoJCQl3YWl0LT5tc2cgPSBtc2c7CgkJCXdhaXQtPmNvbXBsZXRlID0gMTsKCgkJCWJhcnJpZXIoKTsKCgkJCWlmICh3YWl0LT53cSkgewoJCQkJd2FrZV91cF9pbnRlcnJ1cHRpYmxlKHdhaXQtPndxKTsKCQkJCXJjID0gMDsKCQkJfSBlbHNlIHsKCQkJCXN0cnVjdCBkZXZpY2UgKmRldjsKCgkJCQlkZXYgPSAmYy0+cGRldi0+ZGV2OwoKCQkJCXByX2RlYnVnKCIlczogdGltZWRvdXQgcmVwbHkgcmVjZWl2ZWQhXG4iLAoJCQkJCSBjLT5uYW1lKTsKCQkJCWkyb19kbWFfZnJlZShkZXYsICZ3YWl0LT5kbWEpOwoJCQkJaTJvX2V4ZWNfd2FpdF9mcmVlKHdhaXQpOwoJCQkJcmMgPSAtMTsKCQkJfQoKCQkJcmV0dXJuIHJjOwoJCX0KCX0KCglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZsb2NrLCBmbGFncyk7CgoJb3NtX3dhcm4oIiVzOiBCb2d1cyByZXBseSBpbiBQT1NUIFdBSVQgKHRyLWNvbnRleHQ6ICUwOHgpIVxuIiwgYy0+bmFtZSwKCQkgY29udGV4dCk7CgoJcmV0dXJuIC0xOwp9OwoKLyoqCiAqCWkyb19leGVjX3Nob3dfdmVuZG9yX2lkIC0gRGlzcGxheXMgVmVuZG9yIElEIG9mIGNvbnRyb2xsZXIKICoJQGQ6IGRldmljZSBvZiB3aGljaCB0aGUgVmVuZG9yIElEIHNob3VsZCBiZSBkaXNwbGF5ZWQKICoJQGJ1ZjogYnVmZmVyIGludG8gd2hpY2ggdGhlIFZlbmRvciBJRCBzaG91bGQgYmUgcHJpbnRlZAogKgogKglSZXR1cm5zIG51bWJlciBvZiBieXRlcyBwcmludGVkIGludG8gYnVmZmVyLgogKi8Kc3RhdGljIHNzaXplX3QgaTJvX2V4ZWNfc2hvd192ZW5kb3JfaWQoc3RydWN0IGRldmljZSAqZCwgc3RydWN0IGRldmljZV9hdHRyaWJ1dGUgKmF0dHIsIGNoYXIgKmJ1ZikKewoJc3RydWN0IGkyb19kZXZpY2UgKmRldiA9IHRvX2kyb19kZXZpY2UoZCk7Cgl1MTYgaWQ7CgoJaWYgKGkyb19wYXJtX2ZpZWxkX2dldChkZXYsIDB4MDAwMCwgMCwgJmlkLCAyKSkgewoJCXNwcmludGYoYnVmLCAiMHglMDR4IiwgaWQpOwoJCXJldHVybiBzdHJsZW4oYnVmKSArIDE7Cgl9CgoJcmV0dXJuIDA7Cn07CgovKioKICoJaTJvX2V4ZWNfc2hvd19wcm9kdWN0X2lkIC0gRGlzcGxheXMgUHJvZHVjdCBJRCBvZiBjb250cm9sbGVyCiAqCUBkOiBkZXZpY2Ugb2Ygd2hpY2ggdGhlIFByb2R1Y3QgSUQgc2hvdWxkIGJlIGRpc3BsYXllZAogKglAYnVmOiBidWZmZXIgaW50byB3aGljaCB0aGUgUHJvZHVjdCBJRCBzaG91bGQgYmUgcHJpbnRlZAogKgogKglSZXR1cm5zIG51bWJlciBvZiBieXRlcyBwcmludGVkIGludG8gYnVmZmVyLgogKi8Kc3RhdGljIHNzaXplX3QgaTJvX2V4ZWNfc2hvd19wcm9kdWN0X2lkKHN0cnVjdCBkZXZpY2UgKmQsIHN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjaGFyICpidWYpCnsKCXN0cnVjdCBpMm9fZGV2aWNlICpkZXYgPSB0b19pMm9fZGV2aWNlKGQpOwoJdTE2IGlkOwoKCWlmIChpMm9fcGFybV9maWVsZF9nZXQoZGV2LCAweDAwMDAsIDEsICZpZCwgMikpIHsKCQlzcHJpbnRmKGJ1ZiwgIjB4JTA0eCIsIGlkKTsKCQlyZXR1cm4gc3RybGVuKGJ1ZikgKyAxOwoJfQoKCXJldHVybiAwOwp9OwoKLyogRXhlYy1PU00gZGV2aWNlIGF0dHJpYnV0ZXMgKi8Kc3RhdGljIERFVklDRV9BVFRSKHZlbmRvcl9pZCwgU19JUlVHTywgaTJvX2V4ZWNfc2hvd192ZW5kb3JfaWQsIE5VTEwpOwpzdGF0aWMgREVWSUNFX0FUVFIocHJvZHVjdF9pZCwgU19JUlVHTywgaTJvX2V4ZWNfc2hvd19wcm9kdWN0X2lkLCBOVUxMKTsKCi8qKgogKglpMm9fZXhlY19wcm9iZSAtIENhbGxlZCBpZiBhIG5ldyBJMk8gZGV2aWNlIChleGVjdXRpdmUgY2xhc3MpIGFwcGVhcnMKICoJQGRldjogSTJPIGRldmljZSB3aGljaCBzaG91bGQgYmUgcHJvYmVkCiAqCiAqCVJlZ2lzdGVycyBldmVudCBub3RpZmljYXRpb24gZm9yIGV2ZXJ5IGV2ZW50IGZyb20gRXhlY3V0aXZlIGRldmljZS4gVGhlCiAqCXJldHVybiBpcyBhbHdheXMgMCwgYmVjYXVzZSB3ZSB3YW50IGFsbCBkZXZpY2VzIG9mIGNsYXNzIEV4ZWN1dGl2ZS4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3MuCiAqLwpzdGF0aWMgaW50IGkyb19leGVjX3Byb2JlKHN0cnVjdCBkZXZpY2UgKmRldikKewoJc3RydWN0IGkyb19kZXZpY2UgKmkyb19kZXYgPSB0b19pMm9fZGV2aWNlKGRldik7CglzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMgPSBpMm9fZGV2LT5pb3A7CgoJaTJvX2V2ZW50X3JlZ2lzdGVyKGkyb19kZXYsICZpMm9fZXhlY19kcml2ZXIsIDAsIDB4ZmZmZmZmZmYpOwoKCWMtPmV4ZWMgPSBpMm9fZGV2OwoKCWkyb19leGVjX2xjdF9ub3RpZnkoYywgYy0+bGN0LT5jaGFuZ2VfaW5kICsgMSk7CgoJZGV2aWNlX2NyZWF0ZV9maWxlKGRldiwgJmRldl9hdHRyX3ZlbmRvcl9pZCk7CglkZXZpY2VfY3JlYXRlX2ZpbGUoZGV2LCAmZGV2X2F0dHJfcHJvZHVjdF9pZCk7CgoJcmV0dXJuIDA7Cn07CgovKioKICoJaTJvX2V4ZWNfcmVtb3ZlIC0gQ2FsbGVkIG9uIEkyTyBkZXZpY2UgcmVtb3ZhbAogKglAZGV2OiBJMk8gZGV2aWNlIHdoaWNoIHdhcyByZW1vdmVkCiAqCiAqCVVucmVnaXN0ZXJzIGV2ZW50IG5vdGlmaWNhdGlvbiBmcm9tIEV4ZWN1dGl2ZSBJMk8gZGV2aWNlLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2Vzcy4KICovCnN0YXRpYyBpbnQgaTJvX2V4ZWNfcmVtb3ZlKHN0cnVjdCBkZXZpY2UgKmRldikKewoJZGV2aWNlX3JlbW92ZV9maWxlKGRldiwgJmRldl9hdHRyX3Byb2R1Y3RfaWQpOwoJZGV2aWNlX3JlbW92ZV9maWxlKGRldiwgJmRldl9hdHRyX3ZlbmRvcl9pZCk7CgoJaTJvX2V2ZW50X3JlZ2lzdGVyKHRvX2kyb19kZXZpY2UoZGV2KSwgJmkyb19leGVjX2RyaXZlciwgMCwgMCk7CgoJcmV0dXJuIDA7Cn07CgovKioKICoJaTJvX2V4ZWNfbGN0X21vZGlmaWVkIC0gQ2FsbGVkIG9uIExDVCBOT1RJRlkgcmVwbHkKICoJQGM6IEkyTyBjb250cm9sbGVyIG9uIHdoaWNoIHRoZSBMQ1QgaGFzIG1vZGlmaWVkCiAqCiAqCVRoaXMgZnVuY3Rpb24gaGFuZGxlcyBhc3luY2hyb251cyBMQ1QgTk9USUZZIHJlcGxpZXMuIEl0IHBhcnNlcyB0aGUKICoJbmV3IExDVCBhbmQgaWYgdGhlIGJ1ZmZlciBmb3IgdGhlIExDVCB3YXMgdG8gc21hbGwgc2VuZHMgYSBMQ1QgTk9USUZZCiAqCWFnYWluLCBvdGhlcndpc2Ugc2VuZCBMQ1QgTk9USUZZIHRvIGdldCBpbmZvcm1lZCBvbiBuZXh0IExDVCBjaGFuZ2UuCiAqLwpzdGF0aWMgdm9pZCBpMm9fZXhlY19sY3RfbW9kaWZpZWQoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7Cgl1MzIgY2hhbmdlX2luZCA9IDA7CgoJaWYgKGkyb19kZXZpY2VfcGFyc2VfbGN0KGMpICE9IC1FQUdBSU4pCgkJY2hhbmdlX2luZCA9IGMtPmxjdC0+Y2hhbmdlX2luZCArIDE7CgoJaTJvX2V4ZWNfbGN0X25vdGlmeShjLCBjaGFuZ2VfaW5kKTsKfTsKCi8qKgogKglpMm9fZXhlY19yZXBseSAtICBJMk8gRXhlY3V0aXZlIHJlcGx5IGhhbmRsZXIKICoJQGM6IEkyTyBjb250cm9sbGVyIGZyb20gd2hpY2ggdGhlIHJlcGx5IGNvbWVzCiAqCUBtOiBtZXNzYWdlIGlkCiAqCUBtc2c6IHBvaW50ZXIgdG8gdGhlIEkyTyByZXBseSBtZXNzYWdlCiAqCiAqCVRoaXMgZnVuY3Rpb24gaXMgYWx3YXlzIGNhbGxlZCBmcm9tIGludGVycnVwdCBjb250ZXh0LiBJZiBhIFBPU1QgV0FJVAogKglyZXBseSB3YXMgcmVjZWl2ZWQsIHBhc3MgaXQgdG8gdGhlIGNvbXBsZXRlIGZ1bmN0aW9uLiBJZiBhIExDVCBOT1RJRlkKICoJcmVwbHkgd2FzIHJlY2VpdmVkLCBhIG5ldyBldmVudCBpcyBjcmVhdGVkIHRvIGhhbmRsZSB0aGUgdXBkYXRlLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBhbmQgaWYgdGhlIHJlcGx5IHNob3VsZCBub3QgYmUgZmx1c2hlZCBvciA+IDAKICoJb24gc3VjY2VzcyBhbmQgaWYgdGhlIHJlcGx5IHNob3VsZCBiZSBmbHVzaGVkLiBSZXR1cm5zIG5lZ2F0aXZlIGVycm9yCiAqCWNvZGUgb24gZmFpbHVyZSBhbmQgaWYgdGhlIHJlcGx5IHNob3VsZCBiZSBmbHVzaGVkLgogKi8Kc3RhdGljIGludCBpMm9fZXhlY19yZXBseShzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMsIHUzMiBtLAoJCQkgIHN0cnVjdCBpMm9fbWVzc2FnZSAqbXNnKQp7Cgl1MzIgY29udGV4dDsKCglpZiAobGUzMl90b19jcHUobXNnLT51LmhlYWRbMF0pICYgTVNHX0ZBSUwpIHsKCQkvKgoJCSAqIElmIEZhaWwgYml0IGlzIHNldCB3ZSBtdXN0IHRha2UgdGhlIHRyYW5zYWN0aW9uIGNvbnRleHQgb2YKCQkgKiB0aGUgcHJlc2VydmVkIG1lc3NhZ2UgdG8gZmluZCB0aGUgcmlnaHQgcmVxdWVzdCBhZ2Fpbi4KCQkgKi8KCQlzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqcG1zZzsKCQl1MzIgcG07CgoJCXBtID0gbGUzMl90b19jcHUobXNnLT5ib2R5WzNdKTsKCgkJcG1zZyA9IGkyb19tc2dfaW5fdG9fdmlydChjLCBwbSk7CgoJCWkyb19yZXBvcnRfc3RhdHVzKEtFUk5fSU5GTywgImkyb19jb3JlIiwgbXNnKTsKCgkJY29udGV4dCA9IHJlYWRsKCZwbXNnLT51LnMudGNudHh0KTsKCgkJLyogUmVsZWFzZSB0aGUgcHJlc2VydmVkIG1zZyAqLwoJCWkyb19tc2dfbm9wKGMsIHBtKTsKCX0gZWxzZQoJCWNvbnRleHQgPSBsZTMyX3RvX2NwdShtc2ctPnUucy50Y250eHQpOwoKCWlmIChjb250ZXh0ICYgMHg4MDAwMDAwMCkKCQlyZXR1cm4gaTJvX21zZ19wb3N0X3dhaXRfY29tcGxldGUoYywgbSwgbXNnLCBjb250ZXh0KTsKCglpZiAoKGxlMzJfdG9fY3B1KG1zZy0+dS5oZWFkWzFdKSA+PiAyNCkgPT0gSTJPX0NNRF9MQ1RfTk9USUZZKSB7CgkJc3RydWN0IHdvcmtfc3RydWN0ICp3b3JrOwoKCQlwcl9kZWJ1ZygiJXM6IExDVCBub3RpZnkgcmVjZWl2ZWRcbiIsIGMtPm5hbWUpOwoKCQl3b3JrID0ga21hbGxvYyhzaXplb2YoKndvcmspLCBHRlBfQVRPTUlDKTsKCQlpZiAoIXdvcmspCgkJCXJldHVybiAtRU5PTUVNOwoKCQlJTklUX1dPUksod29yaywgKHZvaWQgKCopKHZvaWQgKikpaTJvX2V4ZWNfbGN0X21vZGlmaWVkLCBjKTsKCQlxdWV1ZV93b3JrKGkyb19leGVjX2RyaXZlci5ldmVudF9xdWV1ZSwgd29yayk7CgkJcmV0dXJuIDE7Cgl9CgoJLyoKCSAqIElmIHRoaXMgaGFwcGVucywgd2Ugd2FudCB0byBkdW1wIHRoZSBtZXNzYWdlIHRvIHRoZSBzeXNsb2cgc28KCSAqIGl0IGNhbiBiZSBzZW50IGJhY2sgdG8gdGhlIGNhcmQgbWFudWZhY3R1cmVyIGJ5IHRoZSBlbmQgdXNlcgoJICogdG8gYWlkIGluIGRlYnVnZ2luZy4KCSAqCgkgKi8KCXByaW50ayhLRVJOX1dBUk5JTkcgIiVzOiBVbnNvbGljaXRlZCBtZXNzYWdlIHJlcGx5IHNlbnQgdG8gY29yZSEiCgkgICAgICAgIk1lc3NhZ2UgZHVtcGVkIHRvIHN5c2xvZ1xuIiwgYy0+bmFtZSk7CglpMm9fZHVtcF9tZXNzYWdlKG1zZyk7CgoJcmV0dXJuIC1FRkFVTFQ7Cn0KCi8qKgogKglpMm9fZXhlY19ldmVudCAtIEV2ZW50IGhhbmRsaW5nIGZ1bmN0aW9uCiAqCUBldnQ6IEV2ZW50IHdoaWNoIG9jY3VycwogKgogKglIYW5kbGVzIGV2ZW50cyBzZW5kIGJ5IHRoZSBFeGVjdXRpdmUgZGV2aWNlLiBBdCB0aGUgbW9tZW50IGRvZXMgbm90IGRvCiAqCWFueXRoaW5nIHVzZWZ1bC4KICovCnN0YXRpYyB2b2lkIGkyb19leGVjX2V2ZW50KHN0cnVjdCBpMm9fZXZlbnQgKmV2dCkKewoJaWYgKGxpa2VseShldnQtPmkyb19kZXYpKQoJCW9zbV9kZWJ1ZygiRXZlbnQgcmVjZWl2ZWQgZnJvbSBkZXZpY2U6ICVkXG4iLAoJCQkgIGV2dC0+aTJvX2Rldi0+bGN0X2RhdGEudGlkKTsKCWtmcmVlKGV2dCk7Cn07CgovKioKICoJaTJvX2V4ZWNfbGN0X2dldCAtIEdldCB0aGUgSU9QJ3MgTG9naWNhbCBDb25maWd1cmF0aW9uIFRhYmxlCiAqCUBjOiBJMk8gY29udHJvbGxlciBmcm9tIHdoaWNoIHRoZSBMQ1Qgc2hvdWxkIGJlIGZldGNoZWQKICoKICoJU2VuZCBhIExDVCBOT1RJRlkgcmVxdWVzdCB0byB0aGUgY29udHJvbGxlciwgYW5kIHdhaXQKICoJSTJPX1RJTUVPVVRfTENUX0dFVCBzZWNvbmRzIHVudGlsIGFycml2YWwgb2YgcmVzcG9uc2UuIElmIHRoZSBMQ1QgaXMKICoJdG8gbGFyZ2UsIHJldHJ5IGl0LgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwppbnQgaTJvX2V4ZWNfbGN0X2dldChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2c7Cgl1MzIgbTsKCWludCBpID0gMDsKCWludCByYyA9IC1FQUdBSU47CgoJZm9yIChpID0gMTsgaSA8PSBJMk9fTENUX0dFVF9UUklFUzsgaSsrKSB7CgkJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJCWlmIChtID09IEkyT19RVUVVRV9FTVBUWSkKCQkJcmV0dXJuIC1FVElNRURPVVQ7CgoJCXdyaXRlbChFSUdIVF9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF82LCAmbXNnLT51LmhlYWRbMF0pOwoJCXdyaXRlbChJMk9fQ01EX0xDVF9OT1RJRlkgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElELAoJCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoJCXdyaXRlbCgweGZmZmZmZmZmLCAmbXNnLT5ib2R5WzBdKTsKCQl3cml0ZWwoMHgwMDAwMDAwMCwgJm1zZy0+Ym9keVsxXSk7CgkJd3JpdGVsKDB4ZDAwMDAwMDAgfCBjLT5kbGN0LmxlbiwgJm1zZy0+Ym9keVsyXSk7CgkJd3JpdGVsKGMtPmRsY3QucGh5cywgJm1zZy0+Ym9keVszXSk7CgoJCXJjID0gaTJvX21zZ19wb3N0X3dhaXQoYywgbSwgSTJPX1RJTUVPVVRfTENUX0dFVCk7CgkJaWYgKHJjIDwgMCkKCQkJYnJlYWs7CgoJCXJjID0gaTJvX2RldmljZV9wYXJzZV9sY3QoYyk7CgkJaWYgKHJjICE9IC1FQUdBSU4pCgkJCWJyZWFrOwoJfQoKCXJldHVybiByYzsKfQoKLyoqCiAqCWkyb19leGVjX2xjdF9ub3RpZnkgLSBTZW5kIGEgYXN5bmNocm9udXMgTENUIE5PVElGWSByZXF1ZXN0CiAqCUBjOiBJMk8gY29udHJvbGxlciB0byB3aGljaCB0aGUgcmVxdWVzdCBzaG91bGQgYmUgc2VuZAogKglAY2hhbmdlX2luZDogY2hhbmdlIGluZGljYXRvcgogKgogKglUaGlzIGZ1bmN0aW9uIHNlbmRzIGEgTENUIE5PVElGWSByZXF1ZXN0IHRvIHRoZSBJMk8gY29udHJvbGxlciB3aXRoCiAqCXRoZSBjaGFuZ2UgaW5kaWNhdG9yIGNoYW5nZV9pbmQuIElmIHRoZSBjaGFuZ2VfaW5kID09IDAgdGhlIGNvbnRyb2xsZXIKICoJcmVwbGllcyBpbW1lZGlhdGVseSBhZnRlciB0aGUgcmVxdWVzdC4gSWYgY2hhbmdlX2luZCA+IDAgdGhlIHJlcGx5IGlzCiAqCXNlbmQgYWZ0ZXIgY2hhbmdlIGluZGljYXRvciBvZiB0aGUgTENUIGlzID4gY2hhbmdlX2luZC4KICovCnN0YXRpYyBpbnQgaTJvX2V4ZWNfbGN0X25vdGlmeShzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMsIHUzMiBjaGFuZ2VfaW5kKQp7CglpMm9fc3RhdHVzX2Jsb2NrICpzYiA9IGMtPnN0YXR1c19ibG9jay52aXJ0OwoJc3RydWN0IGRldmljZSAqZGV2OwoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZzsKCXUzMiBtOwoKCWRldiA9ICZjLT5wZGV2LT5kZXY7CgoJaWYgKGkyb19kbWFfcmVhbGxvYyhkZXYsICZjLT5kbGN0LCBzYi0+ZXhwZWN0ZWRfbGN0X3NpemUsIEdGUF9LRVJORUwpKQoJCXJldHVybiAtRU5PTUVNOwoKCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCWlmIChtID09IEkyT19RVUVVRV9FTVBUWSkKCQlyZXR1cm4gLUVUSU1FRE9VVDsKCgl3cml0ZWwoRUlHSFRfV09SRF9NU0dfU0laRSB8IFNHTF9PRkZTRVRfNiwgJm1zZy0+dS5oZWFkWzBdKTsKCXdyaXRlbChJMk9fQ01EX0xDVF9OT1RJRlkgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElELAoJICAgICAgICZtc2ctPnUuaGVhZFsxXSk7Cgl3cml0ZWwoaTJvX2V4ZWNfZHJpdmVyLmNvbnRleHQsICZtc2ctPnUucy5pY250eHQpOwoJd3JpdGVsKDAsICZtc2ctPnUucy50Y250eHQpOwkvKiBGSVhNRSAqLwoJd3JpdGVsKDB4ZmZmZmZmZmYsICZtc2ctPmJvZHlbMF0pOwoJd3JpdGVsKGNoYW5nZV9pbmQsICZtc2ctPmJvZHlbMV0pOwoJd3JpdGVsKDB4ZDAwMDAwMDAgfCBjLT5kbGN0LmxlbiwgJm1zZy0+Ym9keVsyXSk7Cgl3cml0ZWwoYy0+ZGxjdC5waHlzLCAmbXNnLT5ib2R5WzNdKTsKCglpMm9fbXNnX3Bvc3QoYywgbSk7CgoJcmV0dXJuIDA7Cn07CgovKiBFeGVjIE9TTSBkcml2ZXIgc3RydWN0ICovCnN0cnVjdCBpMm9fZHJpdmVyIGkyb19leGVjX2RyaXZlciA9IHsKCS5uYW1lID0gT1NNX05BTUUsCgkucmVwbHkgPSBpMm9fZXhlY19yZXBseSwKCS5ldmVudCA9IGkyb19leGVjX2V2ZW50LAoJLmNsYXNzZXMgPSBpMm9fZXhlY19jbGFzc19pZCwKCS5kcml2ZXIgPSB7CgkJICAgLnByb2JlID0gaTJvX2V4ZWNfcHJvYmUsCgkJICAgLnJlbW92ZSA9IGkyb19leGVjX3JlbW92ZSwKCQkgICB9LAp9OwoKLyoqCiAqCWkyb19leGVjX2luaXQgLSBSZWdpc3RlcnMgdGhlIEV4ZWMgT1NNCiAqCiAqCVJlZ2lzdGVycyB0aGUgRXhlYyBPU00gaW4gdGhlIEkyTyBjb3JlLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwppbnQgX19pbml0IGkyb19leGVjX2luaXQodm9pZCkKewoJcmV0dXJuIGkyb19kcml2ZXJfcmVnaXN0ZXIoJmkyb19leGVjX2RyaXZlcik7Cn07CgovKioKICoJaTJvX2V4ZWNfZXhpdCAtIFJlbW92ZXMgdGhlIEV4ZWMgT1NNCiAqCiAqCVVucmVnaXN0ZXJzIHRoZSBFeGVjIE9TTSBmcm9tIHRoZSBJMk8gY29yZS4KICovCnZvaWQgX19leGl0IGkyb19leGVjX2V4aXQodm9pZCkKewoJaTJvX2RyaXZlcl91bnJlZ2lzdGVyKCZpMm9fZXhlY19kcml2ZXIpOwp9OwoKRVhQT1JUX1NZTUJPTChpMm9fbXNnX3Bvc3Rfd2FpdF9tZW0pOwpFWFBPUlRfU1lNQk9MKGkyb19leGVjX2xjdF9nZXQpOwo=