LyoKICoJRXhlY3V0aXZlIE9TTQogKgogKiAJQ29weXJpZ2h0IChDKSAxOTk5LTIwMDIJUmVkIEhhdCBTb2Z0d2FyZQogKgogKglXcml0dGVuIGJ5IEFsYW4gQ294LCBCdWlsZGluZyBOdW1iZXIgVGhyZWUgTHRkCiAqCiAqCVRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5IGl0CiAqCXVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5IHRoZQogKglGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyCiAqCW9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqCUEgbG90IG9mIHRoZSBJMk8gbWVzc2FnZSBzaWRlIGNvZGUgZnJvbSB0aGlzIGlzIHRha2VuIGZyb20gdGhlIFJlZAogKglDcmVlayBSQ1BDSTQ1IGFkYXB0ZXIgZHJpdmVyIGJ5IFJlZCBDcmVlayBDb21tdW5pY2F0aW9ucwogKgogKglGaXhlcy9hZGRpdGlvbnM6CiAqCQlQaGlsaXBwIFJ1bXBmCiAqCQlKdWhhIFNpZXbkbmVuIDxKdWhhLlNpZXZhbmVuQGNzLkhlbHNpbmtpLkZJPgogKgkJQXV2byBI5GtraW5lbiA8QXV2by5IYWtraW5lbkBjcy5IZWxzaW5raS5GST4KICoJCURlZXBhayBTYXhlbmEgPGRlZXBha0BwbGV4aXR5Lm5ldD4KICoJCUJvamkgVCBLYW5uYW50aGFuYW0gPGJvamkudC5rYW5uYW50aGFuYW1AaW50ZWwuY29tPgogKgkJQWxhbiBDb3ggPGFsYW5AcmVkaGF0LmNvbT46CiAqCQkJUG9ydGVkIHRvIExpbnV4IDIuNS4KICoJCU1hcmt1cyBMaWRlbCA8TWFya3VzLkxpZGVsQHNoYWRvd2Nvbm5lY3QuY29tPjoKICoJCQlNaW5vciBmaXhlcyBmb3IgMi42LgogKgkJTWFya3VzIExpZGVsIDxNYXJrdXMuTGlkZWxAc2hhZG93Y29ubmVjdC5jb20+OgogKgkJCVN1cHBvcnQgZm9yIHN5c2ZzIGluY2x1ZGVkLgogKi8KCiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2kyby5oPgojaW5jbHVkZSA8bGludXgvZGVsYXkuaD4KCiNkZWZpbmUgT1NNX05BTUUgImV4ZWMtb3NtIgoKc3RydWN0IGkyb19kcml2ZXIgaTJvX2V4ZWNfZHJpdmVyOwoKc3RhdGljIGludCBpMm9fZXhlY19sY3Rfbm90aWZ5KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgdTMyIGNoYW5nZV9pbmQpOwoKLyogTW9kdWxlIGludGVybmFsIGZ1bmN0aW9ucyBmcm9tIG90aGVyIHNvdXJjZXMgKi8KZXh0ZXJuIGludCBpMm9fZGV2aWNlX3BhcnNlX2xjdChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKik7CgovKiBnbG9iYWwgd2FpdCBsaXN0IGZvciBQT1NUIFdBSVQgKi8Kc3RhdGljIExJU1RfSEVBRChpMm9fZXhlY193YWl0X2xpc3QpOwoKLyogV2FpdCBzdHJ1Y3QgbmVlZGVkIGZvciBQT1NUIFdBSVQgKi8Kc3RydWN0IGkyb19leGVjX3dhaXQgewoJd2FpdF9xdWV1ZV9oZWFkX3QgKndxOwkvKiBQb2ludGVyIHRvIFdhaXQgcXVldWUgKi8KCXN0cnVjdCBpMm9fZG1hIGRtYTsJLyogRE1BIGJ1ZmZlcnMgdG8gZnJlZSBvbiBmYWlsdXJlICovCgl1MzIgdGNudHh0OwkJLyogdHJhbnNhY3Rpb24gY29udGV4dCBmcm9tIHJlcGx5ICovCglpbnQgY29tcGxldGU7CQkvKiAxIGlmIHJlcGx5IHJlY2VpdmVkIG90aGVyd2lzZSAwICovCgl1MzIgbTsJCQkvKiBtZXNzYWdlIGlkICovCglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnOwkvKiBwb2ludGVyIHRvIHRoZSByZXBseSBtZXNzYWdlICovCglzdHJ1Y3QgbGlzdF9oZWFkIGxpc3Q7CS8qIG5vZGUgaW4gZ2xvYmFsIHdhaXQgbGlzdCAqLwp9OwoKLyogRXhlYyBPU00gY2xhc3MgaGFuZGxpbmcgZGVmaW5pdGlvbiAqLwpzdGF0aWMgc3RydWN0IGkyb19jbGFzc19pZCBpMm9fZXhlY19jbGFzc19pZFtdID0gewoJe0kyT19DTEFTU19FWEVDVVRJVkV9LAoJe0kyT19DTEFTU19FTkR9Cn07CgovKioKICoJaTJvX2V4ZWNfd2FpdF9hbGxvYyAtIEFsbG9jYXRlIGEgaTJvX2V4ZWNfd2FpdCBzdHJ1Y3QgYW4gaW5pdGlhbGl6ZSBpdAogKgogKglBbGxvY2F0ZSB0aGUgaTJvX2V4ZWNfd2FpdCBzdHJ1Y3QgYW5kIGluaXRpYWxpemUgdGhlIHdhaXQuCiAqCiAqCVJldHVybnMgaTJvX2V4ZWNfd2FpdCBwb2ludGVyIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbgogKglmYWlsdXJlLgogKi8Kc3RhdGljIHN0cnVjdCBpMm9fZXhlY193YWl0ICppMm9fZXhlY193YWl0X2FsbG9jKHZvaWQpCnsKCXN0cnVjdCBpMm9fZXhlY193YWl0ICp3YWl0OwoKCXdhaXQgPSBrbWFsbG9jKHNpemVvZigqd2FpdCksIEdGUF9LRVJORUwpOwoJaWYgKCF3YWl0KQoJCXJldHVybiBFUlJfUFRSKC1FTk9NRU0pOwoKCW1lbXNldCh3YWl0LCAwLCBzaXplb2YoKndhaXQpKTsKCglJTklUX0xJU1RfSEVBRCgmd2FpdC0+bGlzdCk7CgoJcmV0dXJuIHdhaXQ7Cn07CgovKioKICoJaTJvX2V4ZWNfd2FpdF9mcmVlIC0gRnJlZSBhIGkyb19leGVjX3dhaXQgc3RydWN0CiAqCUBpMm9fZXhlY193YWl0OiBJMk8gd2FpdCBkYXRhIHdoaWNoIHNob3VsZCBiZSBjbGVhbmVkIHVwCiAqLwpzdGF0aWMgdm9pZCBpMm9fZXhlY193YWl0X2ZyZWUoc3RydWN0IGkyb19leGVjX3dhaXQgKndhaXQpCnsKCWtmcmVlKHdhaXQpOwp9OwoKLyoqCiAqIAlpMm9fbXNnX3Bvc3Rfd2FpdF9tZW0gLSBQb3N0IGFuZCB3YWl0IGEgbWVzc2FnZSB3aXRoIERNQSBidWZmZXJzCiAqCUBjOiBjb250cm9sbGVyCiAqCUBtOiBtZXNzYWdlIHRvIHBvc3QKICoJQHRpbWVvdXQ6IHRpbWUgaW4gc2Vjb25kcyB0byB3YWl0CiAqCUBkbWE6IGkyb19kbWEgc3RydWN0IG9mIHRoZSBETUEgYnVmZmVyIHRvIGZyZWUgb24gZmFpbHVyZQogKgogKiAJVGhpcyBBUEkgYWxsb3dzIGFuIE9TTSB0byBwb3N0IGEgbWVzc2FnZSBhbmQgdGhlbiBiZSB0b2xkIHdoZXRoZXIgb3IKICoJbm90IHRoZSBzeXN0ZW0gcmVjZWl2ZWQgYSBzdWNjZXNzZnVsIHJlcGx5LiBJZiB0aGUgbWVzc2FnZSB0aW1lcyBvdXQKICoJdGhlbiB0aGUgdmFsdWUgJy1FVElNRURPVVQnIGlzIHJldHVybmVkLiBUaGlzIGlzIGEgc3BlY2lhbCBjYXNlLiBJbgogKgl0aGlzIHNpdHVhdGlvbiB0aGUgbWVzc2FnZSBtYXkgKHNob3VsZCkgY29tcGxldGUgYXQgYW4gaW5kZWZpbml0ZSB0aW1lCiAqCWluIHRoZSBmdXR1cmUuIFdoZW4gaXQgY29tcGxldGVzIGl0IHdpbGwgdXNlIHRoZSBtZW1vcnkgYnVmZmVyCiAqCWF0dGFjaGVkIHRvIHRoZSByZXF1ZXN0LiBJZiAtRVRJTUVET1VUIGlzIHJldHVybmVkIHRoZW4gdGhlIG1lbW9yeQogKglidWZmZXIgbXVzdCBub3QgYmUgZnJlZWQuIEluc3RlYWQgdGhlIGV2ZW50IGNvbXBsZXRpb24gd2lsbCBmcmVlIHRoZW0KICoJZm9yIHlvdS4gSW4gYWxsIG90aGVyIGNhc2VzIHRoZSBidWZmZXIgYXJlIHlvdXIgcHJvYmxlbS4KICoKICoJUmV0dXJucyAwIG9uIHN1Y2Nlc3Mgb3IgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLgogKi8KaW50IGkyb19tc2dfcG9zdF93YWl0X21lbShzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMsIHUzMiBtLCB1bnNpZ25lZCBsb25nCgkJCSAgdGltZW91dCwgc3RydWN0IGkyb19kbWEgKmRtYSkKewoJREVDTEFSRV9XQUlUX1FVRVVFX0hFQUQod3EpOwoJc3RydWN0IGkyb19leGVjX3dhaXQgKndhaXQ7CglzdGF0aWMgdTMyIHRjbnR4dCA9IDB4ODAwMDAwMDA7CglzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnID0gYy0+aW5fcXVldWUudmlydCArIG07CglpbnQgcmMgPSAwOwoKCXdhaXQgPSBpMm9fZXhlY193YWl0X2FsbG9jKCk7CglpZiAoIXdhaXQpCgkJcmV0dXJuIC1FTk9NRU07CgoJaWYgKHRjbnR4dCA9PSAweGZmZmZmZmZmKQoJCXRjbnR4dCA9IDB4ODAwMDAwMDA7CgoJaWYgKGRtYSkKCQl3YWl0LT5kbWEgPSAqZG1hOwoKCS8qCgkgKiBGaWxsIGluIHRoZSBtZXNzYWdlIGluaXRpYXRvciBjb250ZXh0IGFuZCB0cmFuc2FjdGlvbiBjb250ZXh0LgoJICogV2Ugd2lsbCBvbmx5IHVzZSB0cmFuc2FjdGlvbiBjb250ZXh0cyA+PSAweDgwMDAwMDAwIGZvciBQT1NUIFdBSVQsCgkgKiBzbyB3ZSBjb3VsZCBmaW5kIGEgUE9TVCBXQUlUIHJlcGx5IGVhc2llciBpbiB0aGUgcmVwbHkgaGFuZGxlci4KCSAqLwoJd3JpdGVsKGkyb19leGVjX2RyaXZlci5jb250ZXh0LCAmbXNnLT51LnMuaWNudHh0KTsKCXdhaXQtPnRjbnR4dCA9IHRjbnR4dCsrOwoJd3JpdGVsKHdhaXQtPnRjbnR4dCwgJm1zZy0+dS5zLnRjbnR4dCk7CgoJLyoKCSAqIFBvc3QgdGhlIG1lc3NhZ2UgdG8gdGhlIGNvbnRyb2xsZXIuIEF0IHNvbWUgcG9pbnQgbGF0ZXIgaXQgd2lsbAoJICogcmV0dXJuLiBJZiB3ZSB0aW1lIG91dCBiZWZvcmUgaXQgcmV0dXJucyB0aGVuIGNvbXBsZXRlIHdpbGwgYmUgemVyby4KCSAqLwoJaTJvX21zZ19wb3N0KGMsIG0pOwoKCWlmICghd2FpdC0+Y29tcGxldGUpIHsKCQl3YWl0LT53cSA9ICZ3cTsKCQkvKgoJCSAqIHdlIGFkZCBlbGVtZW50cyBhZGQgdGhlIGhlYWQsIGJlY2F1c2UgaWYgYSBlbnRyeSBpbiB0aGUgbGlzdAoJCSAqIHdpbGwgbmV2ZXIgYmUgcmVtb3ZlZCwgd2UgaGF2ZSB0byBpdGVyYXRlIG92ZXIgaXQgZXZlcnkgdGltZQoJCSAqLwoJCWxpc3RfYWRkKCZ3YWl0LT5saXN0LCAmaTJvX2V4ZWNfd2FpdF9saXN0KTsKCgkJd2FpdF9ldmVudF9pbnRlcnJ1cHRpYmxlX3RpbWVvdXQod3EsIHdhaXQtPmNvbXBsZXRlLAoJCQl0aW1lb3V0ICogSFopOwoKCQl3YWl0LT53cSA9IE5VTEw7Cgl9CgoJYmFycmllcigpOwoKCWlmICh3YWl0LT5jb21wbGV0ZSkgewoJCWlmIChyZWFkbCgmd2FpdC0+bXNnLT5ib2R5WzBdKSA+PiAyNCkKCQkJcmMgPSByZWFkbCgmd2FpdC0+bXNnLT5ib2R5WzBdKSAmIDB4ZmY7CgkJaTJvX2ZsdXNoX3JlcGx5KGMsIHdhaXQtPm0pOwoJCWkyb19leGVjX3dhaXRfZnJlZSh3YWl0KTsKCX0gZWxzZSB7CgkJLyoKCQkgKiBXZSBjYW5ub3QgcmVtb3ZlIGl0IG5vdy4gVGhpcyBpcyBpbXBvcnRhbnQuIFdoZW4gaXQgZG9lcwoJCSAqIHRlcm1pbmF0ZSAod2hpY2ggaXQgbXVzdCBkbyBpZiB0aGUgY29udHJvbGxlciBoYXMgbm90CgkJICogZGllZC4uLikgdGhlbiBpdCB3aWxsIG90aGVyd2lzZSBzY3JpYmJsZSBvbiBzdHVmZi4KCQkgKgoJCSAqIEZJWE1FOiB0cnkgYWJvcnQgbWVzc2FnZQoJCSAqLwoJCWlmIChkbWEpCgkJCWRtYS0+dmlydCA9IE5VTEw7CgoJCXJjID0gLUVUSU1FRE9VVDsKCX0KCglyZXR1cm4gcmM7Cn07CgovKioKICoJaTJvX21zZ19wb3N0X3dhaXRfY29tcGxldGUgLSBSZXBseSB0byBhIGkyb19tc2dfcG9zdCByZXF1ZXN0IGZyb20gSU9QCiAqCUBjOiBJMk8gY29udHJvbGxlciB3aGljaCBhbnN3ZXJzCiAqCUBtOiBtZXNzYWdlIGlkCiAqCUBtc2c6IHBvaW50ZXIgdG8gdGhlIEkyTyByZXBseSBtZXNzYWdlCiAqCiAqCVRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIGluIGludGVycnVwdCBjb250ZXh0IG9ubHkuIElmIHRoZSByZXBseSByZWFjaGVkCiAqCWJlZm9yZSB0aGUgdGltZW91dCwgdGhlIGkyb19leGVjX3dhaXQgc3RydWN0IGlzIGZpbGxlZCB3aXRoIHRoZSBtZXNzYWdlCiAqCWFuZCB0aGUgdGFzayB3aWxsIGJlIHdha2VkIHVwLiBUaGUgdGFzayBpcyBub3cgcmVzcG9uc2libGUgZm9yIHJldHVybmluZwogKgl0aGUgbWVzc2FnZSBtIGJhY2sgdG8gdGhlIGNvbnRyb2xsZXIhIElmIHRoZSBtZXNzYWdlIHJlYWNoZXMgdXMgYWZ0ZXIKICoJdGhlIHRpbWVvdXQgY2xlYW4gdXAgdGhlIGkyb19leGVjX3dhaXQgc3RydWN0IChpbmNsdWRpbmcgYWxsb2NhdGVkCiAqCURNQSBidWZmZXIpLgogKgogKglSZXR1cm4gMCBvbiBzdWNjZXNzIGFuZCBpZiB0aGUgbWVzc2FnZSBtIHNob3VsZCBub3QgYmUgZ2l2ZW4gYmFjayB0byB0aGUKICoJSTJPIGNvbnRyb2xsZXIsIG9yID4wIG9uIHN1Y2Nlc3MgYW5kIGlmIHRoZSBtZXNzYWdlIHNob3VsZCBiZSBnaXZlbiBiYWNrCiAqCWFmdGVyd29yZHMuIFJldHVybnMgbmVnYXRpdmUgZXJyb3IgY29kZSBvbiBmYWlsdXJlLiBJbiB0aGlzIGNhc2UgdGhlCiAqCW1lc3NhZ2UgbXVzdCBhbHNvIGJlIGdpdmVuIGJhY2sgdG8gdGhlIGNvbnRyb2xsZXIuCiAqLwpzdGF0aWMgaW50IGkyb19tc2dfcG9zdF93YWl0X2NvbXBsZXRlKHN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgdTMyIG0sCgkJCQkgICAgICBzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqbXNnKQp7CglzdHJ1Y3QgaTJvX2V4ZWNfd2FpdCAqd2FpdCwgKnRtcDsKCXN0YXRpYyBzcGlubG9ja190IGxvY2s7CglpbnQgcmMgPSAxOwoJdTMyIGNvbnRleHQ7CgoJc3Bpbl9sb2NrX2luaXQoJmxvY2spOwoKCWNvbnRleHQgPSByZWFkbCgmbXNnLT51LnMudGNudHh0KTsKCgkvKgoJICogV2UgbmVlZCB0byBzZWFyY2ggdGhyb3VnaCB0aGUgaTJvX2V4ZWNfd2FpdF9saXN0IHRvIHNlZSBpZiB0aGUgZ2l2ZW4KCSAqIG1lc3NhZ2UgaXMgc3RpbGwgb3V0c3RhbmRpbmcuIElmIG5vdCwgaXQgbWVhbnMgdGhhdCB0aGUgSU9QIHRvb2sKCSAqIGxvbmdlciB0byByZXNwb25kIHRvIHRoZSBtZXNzYWdlIHRoYW4gd2UgaGFkIGFsbG93ZWQgYW5kIHRpbWVyIGhhcwoJICogYWxyZWFkeSBleHBpcmVkLiBOb3QgbXVjaCB3ZSBjYW4gZG8gYWJvdXQgdGhhdCBleGNlcHQgbG9nIGl0IGZvcgoJICogZGVidWcgcHVycG9zZXMsIGluY3JlYXNlIHRpbWVvdXQsIGFuZCByZWNvbXBpbGUuCgkgKi8KCXNwaW5fbG9jaygmbG9jayk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5X3NhZmUod2FpdCwgdG1wLCAmaTJvX2V4ZWNfd2FpdF9saXN0LCBsaXN0KSB7CgkJaWYgKHdhaXQtPnRjbnR4dCA9PSBjb250ZXh0KSB7CgkJCWxpc3RfZGVsKCZ3YWl0LT5saXN0KTsKCgkJCXdhaXQtPm0gPSBtOwoJCQl3YWl0LT5tc2cgPSBtc2c7CgkJCXdhaXQtPmNvbXBsZXRlID0gMTsKCgkJCWJhcnJpZXIoKTsKCgkJCWlmICh3YWl0LT53cSkgewoJCQkJd2FrZV91cF9pbnRlcnJ1cHRpYmxlKHdhaXQtPndxKTsKCQkJCXJjID0gMDsKCQkJfSBlbHNlIHsKCQkJCXN0cnVjdCBkZXZpY2UgKmRldjsKCgkJCQlkZXYgPSAmYy0+cGRldi0+ZGV2OwoKCQkJCXByX2RlYnVnKCIlczogdGltZWRvdXQgcmVwbHkgcmVjZWl2ZWQhXG4iLAoJCQkJCSBjLT5uYW1lKTsKCQkJCWkyb19kbWFfZnJlZShkZXYsICZ3YWl0LT5kbWEpOwoJCQkJaTJvX2V4ZWNfd2FpdF9mcmVlKHdhaXQpOwoJCQkJcmMgPSAtMTsKCQkJfQoKCQkJc3Bpbl91bmxvY2soJmxvY2spOwoKCQkJcmV0dXJuIHJjOwoJCX0KCX0KCglzcGluX3VubG9jaygmbG9jayk7CgoJcHJfZGVidWcoIiVzOiBCb2d1cyByZXBseSBpbiBQT1NUIFdBSVQgKHRyLWNvbnRleHQ6ICUwOHgpIVxuIiwgYy0+bmFtZSwKCQkgY29udGV4dCk7CgoJcmV0dXJuIC0xOwp9OwoKLyoqCiAqCWkyb19leGVjX3Byb2JlIC0gQ2FsbGVkIGlmIGEgbmV3IEkyTyBkZXZpY2UgKGV4ZWN1dGl2ZSBjbGFzcykgYXBwZWFycwogKglAZGV2OiBJMk8gZGV2aWNlIHdoaWNoIHNob3VsZCBiZSBwcm9iZWQKICoKICoJUmVnaXN0ZXJzIGV2ZW50IG5vdGlmaWNhdGlvbiBmb3IgZXZlcnkgZXZlbnQgZnJvbSBFeGVjdXRpdmUgZGV2aWNlLiBUaGUKICoJcmV0dXJuIGlzIGFsd2F5cyAwLCBiZWNhdXNlIHdlIHdhbnQgYWxsIGRldmljZXMgb2YgY2xhc3MgRXhlY3V0aXZlLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2Vzcy4KICovCnN0YXRpYyBpbnQgaTJvX2V4ZWNfcHJvYmUoc3RydWN0IGRldmljZSAqZGV2KQp7CglzdHJ1Y3QgaTJvX2RldmljZSAqaTJvX2RldiA9IHRvX2kyb19kZXZpY2UoZGV2KTsKCglpMm9fZXZlbnRfcmVnaXN0ZXIoaTJvX2RldiwgJmkyb19leGVjX2RyaXZlciwgMCwgMHhmZmZmZmZmZik7CgoJaTJvX2Rldi0+aW9wLT5leGVjID0gaTJvX2RldjsKCglyZXR1cm4gMDsKfTsKCi8qKgogKglpMm9fZXhlY19yZW1vdmUgLSBDYWxsZWQgb24gSTJPIGRldmljZSByZW1vdmFsCiAqCUBkZXY6IEkyTyBkZXZpY2Ugd2hpY2ggd2FzIHJlbW92ZWQKICoKICoJVW5yZWdpc3RlcnMgZXZlbnQgbm90aWZpY2F0aW9uIGZyb20gRXhlY3V0aXZlIEkyTyBkZXZpY2UuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzLgogKi8Kc3RhdGljIGludCBpMm9fZXhlY19yZW1vdmUoc3RydWN0IGRldmljZSAqZGV2KQp7CglpMm9fZXZlbnRfcmVnaXN0ZXIodG9faTJvX2RldmljZShkZXYpLCAmaTJvX2V4ZWNfZHJpdmVyLCAwLCAwKTsKCglyZXR1cm4gMDsKfTsKCi8qKgogKglpMm9fZXhlY19sY3RfbW9kaWZpZWQgLSBDYWxsZWQgb24gTENUIE5PVElGWSByZXBseQogKglAYzogSTJPIGNvbnRyb2xsZXIgb24gd2hpY2ggdGhlIExDVCBoYXMgbW9kaWZpZWQKICoKICoJVGhpcyBmdW5jdGlvbiBoYW5kbGVzIGFzeW5jaHJvbnVzIExDVCBOT1RJRlkgcmVwbGllcy4gSXQgcGFyc2VzIHRoZQogKgluZXcgTENUIGFuZCBpZiB0aGUgYnVmZmVyIGZvciB0aGUgTENUIHdhcyB0byBzbWFsbCBzZW5kcyBhIExDVCBOT1RJRlkKICoJYWdhaW4uCiAqLwpzdGF0aWMgdm9pZCBpMm9fZXhlY19sY3RfbW9kaWZpZWQoc3RydWN0IGkyb19jb250cm9sbGVyICpjKQp7CglpZiAoaTJvX2RldmljZV9wYXJzZV9sY3QoYykgPT0gLUVBR0FJTikKCQlpMm9fZXhlY19sY3Rfbm90aWZ5KGMsIDApOwp9OwoKLyoqCiAqCWkyb19leGVjX3JlcGx5IC0gIEkyTyBFeGVjdXRpdmUgcmVwbHkgaGFuZGxlcgogKglAYzogSTJPIGNvbnRyb2xsZXIgZnJvbSB3aGljaCB0aGUgcmVwbHkgY29tZXMKICoJQG06IG1lc3NhZ2UgaWQKICoJQG1zZzogcG9pbnRlciB0byB0aGUgSTJPIHJlcGx5IG1lc3NhZ2UKICoKICoJVGhpcyBmdW5jdGlvbiBpcyBhbHdheXMgY2FsbGVkIGZyb20gaW50ZXJydXB0IGNvbnRleHQuIElmIGEgUE9TVCBXQUlUCiAqCXJlcGx5IHdhcyByZWNlaXZlZCwgcGFzcyBpdCB0byB0aGUgY29tcGxldGUgZnVuY3Rpb24uIElmIGEgTENUIE5PVElGWQogKglyZXBseSB3YXMgcmVjZWl2ZWQsIGEgbmV3IGV2ZW50IGlzIGNyZWF0ZWQgdG8gaGFuZGxlIHRoZSB1cGRhdGUuCiAqCiAqCVJldHVybnMgMCBvbiBzdWNjZXNzIGFuZCBpZiB0aGUgcmVwbHkgc2hvdWxkIG5vdCBiZSBmbHVzaGVkIG9yID4gMAogKglvbiBzdWNjZXNzIGFuZCBpZiB0aGUgcmVwbHkgc2hvdWxkIGJlIGZsdXNoZWQuIFJldHVybnMgbmVnYXRpdmUgZXJyb3IKICoJY29kZSBvbiBmYWlsdXJlIGFuZCBpZiB0aGUgcmVwbHkgc2hvdWxkIGJlIGZsdXNoZWQuCiAqLwpzdGF0aWMgaW50IGkyb19leGVjX3JlcGx5KHN0cnVjdCBpMm9fY29udHJvbGxlciAqYywgdTMyIG0sCgkJCSAgc3RydWN0IGkyb19tZXNzYWdlICptc2cpCnsKCWlmIChsZTMyX3RvX2NwdShtc2ctPnUuaGVhZFswXSkgJiBNU0dfRkFJTCkgewkvLyBGYWlsIGJpdCBpcyBzZXQKCQlzdHJ1Y3QgaTJvX21lc3NhZ2UgX19pb21lbSAqcG1zZzsJLyogcHJlc2VydmVkIG1lc3NhZ2UgKi8KCQl1MzIgcG07CgoJCXBtID0gbGUzMl90b19jcHUobXNnLT5ib2R5WzNdKTsKCgkJcG1zZyA9IGkyb19tc2dfaW5fdG9fdmlydChjLCBwbSk7CgoJCWkyb19yZXBvcnRfc3RhdHVzKEtFUk5fSU5GTywgImkyb19jb3JlIiwgbXNnKTsKCgkJLyogUmVsZWFzZSB0aGUgcHJlc2VydmVkIG1zZyBieSByZXN1Ym1pdHRpbmcgaXQgYXMgYSBOT1AgKi8KCQlpMm9fbXNnX25vcChjLCBwbSk7CgoJCS8qIElmIHJlcGx5IHRvIGkyb19wb3N0X3dhaXQgZmFpbGVkLCByZXR1cm4gY2F1c2VzIGEgdGltZW91dCAqLwoJCXJldHVybiAtMTsKCX0KCglpZiAobGUzMl90b19jcHUobXNnLT51LnMudGNudHh0KSAmIDB4ODAwMDAwMDApCgkJcmV0dXJuIGkyb19tc2dfcG9zdF93YWl0X2NvbXBsZXRlKGMsIG0sIG1zZyk7CgoJaWYgKChsZTMyX3RvX2NwdShtc2ctPnUuaGVhZFsxXSkgPj4gMjQpID09IEkyT19DTURfTENUX05PVElGWSkgewoJCXN0cnVjdCB3b3JrX3N0cnVjdCAqd29yazsKCgkJcHJfZGVidWcoIiVzOiBMQ1Qgbm90aWZ5IHJlY2VpdmVkXG4iLCBjLT5uYW1lKTsKCgkJd29yayA9IGttYWxsb2Moc2l6ZW9mKCp3b3JrKSwgR0ZQX0FUT01JQyk7CgkJaWYgKCF3b3JrKQoJCQlyZXR1cm4gLUVOT01FTTsKCgkJSU5JVF9XT1JLKHdvcmssICh2b2lkICgqKSh2b2lkICopKWkyb19leGVjX2xjdF9tb2RpZmllZCwgYyk7CgkJcXVldWVfd29yayhpMm9fZXhlY19kcml2ZXIuZXZlbnRfcXVldWUsIHdvcmspOwoJCXJldHVybiAxOwoJfQoKCS8qCgkgKiBJZiB0aGlzIGhhcHBlbnMsIHdlIHdhbnQgdG8gZHVtcCB0aGUgbWVzc2FnZSB0byB0aGUgc3lzbG9nIHNvCgkgKiBpdCBjYW4gYmUgc2VudCBiYWNrIHRvIHRoZSBjYXJkIG1hbnVmYWN0dXJlciBieSB0aGUgZW5kIHVzZXIKCSAqIHRvIGFpZCBpbiBkZWJ1Z2dpbmcuCgkgKgoJICovCglwcmludGsoS0VSTl9XQVJOSU5HICIlczogVW5zb2xpY2l0ZWQgbWVzc2FnZSByZXBseSBzZW50IHRvIGNvcmUhIgoJICAgICAgICJNZXNzYWdlIGR1bXBlZCB0byBzeXNsb2dcbiIsIGMtPm5hbWUpOwoJaTJvX2R1bXBfbWVzc2FnZShtc2cpOwoKCXJldHVybiAtRUZBVUxUOwp9CgovKioKICoJaTJvX2V4ZWNfZXZlbnQgLSBFdmVudCBoYW5kbGluZyBmdW5jdGlvbgogKglAZXZ0OiBFdmVudCB3aGljaCBvY2N1cnMKICoKICoJSGFuZGxlcyBldmVudHMgc2VuZCBieSB0aGUgRXhlY3V0aXZlIGRldmljZS4gQXQgdGhlIG1vbWVudCBkb2VzIG5vdCBkbwogKglhbnl0aGluZyB1c2VmdWwuCiAqLwpzdGF0aWMgdm9pZCBpMm9fZXhlY19ldmVudChzdHJ1Y3QgaTJvX2V2ZW50ICpldnQpCnsKCW9zbV9pbmZvKCJFdmVudCByZWNlaXZlZCBmcm9tIGRldmljZTogJWRcbiIsCgkJIGV2dC0+aTJvX2Rldi0+bGN0X2RhdGEudGlkKTsKCWtmcmVlKGV2dCk7Cn07CgovKioKICoJaTJvX2V4ZWNfbGN0X2dldCAtIEdldCB0aGUgSU9QJ3MgTG9naWNhbCBDb25maWd1cmF0aW9uIFRhYmxlCiAqCUBjOiBJMk8gY29udHJvbGxlciBmcm9tIHdoaWNoIHRoZSBMQ1Qgc2hvdWxkIGJlIGZldGNoZWQKICoKICoJU2VuZCBhIExDVCBOT1RJRlkgcmVxdWVzdCB0byB0aGUgY29udHJvbGxlciwgYW5kIHdhaXQKICoJSTJPX1RJTUVPVVRfTENUX0dFVCBzZWNvbmRzIHVudGlsIGFycml2YWwgb2YgcmVzcG9uc2UuIElmIHRoZSBMQ1QgaXMKICoJdG8gbGFyZ2UsIHJldHJ5IGl0LgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwppbnQgaTJvX2V4ZWNfbGN0X2dldChzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMpCnsKCXN0cnVjdCBpMm9fbWVzc2FnZSBfX2lvbWVtICptc2c7Cgl1MzIgbTsKCWludCBpID0gMDsKCWludCByYyA9IC1FQUdBSU47CgoJZm9yIChpID0gMTsgaSA8PSBJMk9fTENUX0dFVF9UUklFUzsgaSsrKSB7CgkJbSA9IGkyb19tc2dfZ2V0X3dhaXQoYywgJm1zZywgSTJPX1RJTUVPVVRfTUVTU0FHRV9HRVQpOwoJCWlmIChtID09IEkyT19RVUVVRV9FTVBUWSkKCQkJcmV0dXJuIC1FVElNRURPVVQ7CgoJCXdyaXRlbChFSUdIVF9XT1JEX01TR19TSVpFIHwgU0dMX09GRlNFVF82LCAmbXNnLT51LmhlYWRbMF0pOwoJCXdyaXRlbChJMk9fQ01EX0xDVF9OT1RJRlkgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElELAoJCSAgICAgICAmbXNnLT51LmhlYWRbMV0pOwoJCXdyaXRlbCgweGZmZmZmZmZmLCAmbXNnLT5ib2R5WzBdKTsKCQl3cml0ZWwoMHgwMDAwMDAwMCwgJm1zZy0+Ym9keVsxXSk7CgkJd3JpdGVsKDB4ZDAwMDAwMDAgfCBjLT5kbGN0LmxlbiwgJm1zZy0+Ym9keVsyXSk7CgkJd3JpdGVsKGMtPmRsY3QucGh5cywgJm1zZy0+Ym9keVszXSk7CgoJCXJjID0gaTJvX21zZ19wb3N0X3dhaXQoYywgbSwgSTJPX1RJTUVPVVRfTENUX0dFVCk7CgkJaWYgKHJjIDwgMCkKCQkJYnJlYWs7CgoJCXJjID0gaTJvX2RldmljZV9wYXJzZV9sY3QoYyk7CgkJaWYgKHJjICE9IC1FQUdBSU4pCgkJCWJyZWFrOwoJfQoKCXJldHVybiByYzsKfQoKLyoqCiAqCWkyb19leGVjX2xjdF9ub3RpZnkgLSBTZW5kIGEgYXN5bmNocm9udXMgTENUIE5PVElGWSByZXF1ZXN0CiAqCUBjOiBJMk8gY29udHJvbGxlciB0byB3aGljaCB0aGUgcmVxdWVzdCBzaG91bGQgYmUgc2VuZAogKglAY2hhbmdlX2luZDogY2hhbmdlIGluZGljYXRvcgogKgogKglUaGlzIGZ1bmN0aW9uIHNlbmRzIGEgTENUIE5PVElGWSByZXF1ZXN0IHRvIHRoZSBJMk8gY29udHJvbGxlciB3aXRoCiAqCXRoZSBjaGFuZ2UgaW5kaWNhdG9yIGNoYW5nZV9pbmQuIElmIHRoZSBjaGFuZ2VfaW5kID09IDAgdGhlIGNvbnRyb2xsZXIKICoJcmVwbGllcyBpbW1lZGlhdGVseSBhZnRlciB0aGUgcmVxdWVzdC4gSWYgY2hhbmdlX2luZCA+IDAgdGhlIHJlcGx5IGlzCiAqCXNlbmQgYWZ0ZXIgY2hhbmdlIGluZGljYXRvciBvZiB0aGUgTENUIGlzID4gY2hhbmdlX2luZC4KICovCnN0YXRpYyBpbnQgaTJvX2V4ZWNfbGN0X25vdGlmeShzdHJ1Y3QgaTJvX2NvbnRyb2xsZXIgKmMsIHUzMiBjaGFuZ2VfaW5kKQp7CglpMm9fc3RhdHVzX2Jsb2NrICpzYiA9IGMtPnN0YXR1c19ibG9jay52aXJ0OwoJc3RydWN0IGRldmljZSAqZGV2OwoJc3RydWN0IGkyb19tZXNzYWdlIF9faW9tZW0gKm1zZzsKCXUzMiBtOwoKCWRldiA9ICZjLT5wZGV2LT5kZXY7CgoJaWYgKGkyb19kbWFfcmVhbGxvYyhkZXYsICZjLT5kbGN0LCBzYi0+ZXhwZWN0ZWRfbGN0X3NpemUsIEdGUF9LRVJORUwpKQoJCXJldHVybiAtRU5PTUVNOwoKCW0gPSBpMm9fbXNnX2dldF93YWl0KGMsICZtc2csIEkyT19USU1FT1VUX01FU1NBR0VfR0VUKTsKCWlmIChtID09IEkyT19RVUVVRV9FTVBUWSkKCQlyZXR1cm4gLUVUSU1FRE9VVDsKCgl3cml0ZWwoRUlHSFRfV09SRF9NU0dfU0laRSB8IFNHTF9PRkZTRVRfNiwgJm1zZy0+dS5oZWFkWzBdKTsKCXdyaXRlbChJMk9fQ01EX0xDVF9OT1RJRlkgPDwgMjQgfCBIT1NUX1RJRCA8PCAxMiB8IEFEQVBURVJfVElELAoJICAgICAgICZtc2ctPnUuaGVhZFsxXSk7Cgl3cml0ZWwoaTJvX2V4ZWNfZHJpdmVyLmNvbnRleHQsICZtc2ctPnUucy5pY250eHQpOwoJd3JpdGVsKDAsICZtc2ctPnUucy50Y250eHQpOwkvKiBGSVhNRSAqLwoJd3JpdGVsKDB4ZmZmZmZmZmYsICZtc2ctPmJvZHlbMF0pOwoJd3JpdGVsKGNoYW5nZV9pbmQsICZtc2ctPmJvZHlbMV0pOwoJd3JpdGVsKDB4ZDAwMDAwMDAgfCBjLT5kbGN0LmxlbiwgJm1zZy0+Ym9keVsyXSk7Cgl3cml0ZWwoYy0+ZGxjdC5waHlzLCAmbXNnLT5ib2R5WzNdKTsKCglpMm9fbXNnX3Bvc3QoYywgbSk7CgoJcmV0dXJuIDA7Cn07CgovKiBFeGVjIE9TTSBkcml2ZXIgc3RydWN0ICovCnN0cnVjdCBpMm9fZHJpdmVyIGkyb19leGVjX2RyaXZlciA9IHsKCS5uYW1lID0gT1NNX05BTUUsCgkucmVwbHkgPSBpMm9fZXhlY19yZXBseSwKCS5ldmVudCA9IGkyb19leGVjX2V2ZW50LAoJLmNsYXNzZXMgPSBpMm9fZXhlY19jbGFzc19pZCwKCS5kcml2ZXIgPSB7CgkJICAgLnByb2JlID0gaTJvX2V4ZWNfcHJvYmUsCgkJICAgLnJlbW92ZSA9IGkyb19leGVjX3JlbW92ZSwKCQkgICB9LAp9OwoKLyoqCiAqCWkyb19leGVjX2luaXQgLSBSZWdpc3RlcnMgdGhlIEV4ZWMgT1NNCiAqCiAqCVJlZ2lzdGVycyB0aGUgRXhlYyBPU00gaW4gdGhlIEkyTyBjb3JlLgogKgogKglSZXR1cm5zIDAgb24gc3VjY2VzcyBvciBuZWdhdGl2ZSBlcnJvciBjb2RlIG9uIGZhaWx1cmUuCiAqLwppbnQgX19pbml0IGkyb19leGVjX2luaXQodm9pZCkKewoJcmV0dXJuIGkyb19kcml2ZXJfcmVnaXN0ZXIoJmkyb19leGVjX2RyaXZlcik7Cn07CgovKioKICoJaTJvX2V4ZWNfZXhpdCAtIFJlbW92ZXMgdGhlIEV4ZWMgT1NNCiAqCiAqCVVucmVnaXN0ZXJzIHRoZSBFeGVjIE9TTSBmcm9tIHRoZSBJMk8gY29yZS4KICovCnZvaWQgX19leGl0IGkyb19leGVjX2V4aXQodm9pZCkKewoJaTJvX2RyaXZlcl91bnJlZ2lzdGVyKCZpMm9fZXhlY19kcml2ZXIpOwp9OwoKRVhQT1JUX1NZTUJPTChpMm9fbXNnX3Bvc3Rfd2FpdF9tZW0pOwpFWFBPUlRfU1lNQk9MKGkyb19leGVjX2xjdF9nZXQpOwo=