LyoKICogTW9kaWZpZWQgaW4gb3JkZXIgdG8ga2VlcCBpdCBjb21wYXRpYmxlIGJvdGggd2l0aCBuZXcgYW5kIG9sZCB2aWRlb3RleHQgSU9DVExzIGJ5CiAqIE1pY2hhZWwgR2VuZyA8bGludXhATWljaGFlbEdlbmcuZGU+CiAqCiAqCUNsZWFuZWQgdXAgdG8gdXNlIGV4aXN0aW5nIHZpZGVvZGV2IGludGVyZmFjZSBhbmQgYWxsb3cgdGhlIGlkZWEKICoJb2YgbXVsdGlwbGUgdGVsZXRleHQgZGVjb2RlcnMgb24gdGhlIHZpZGVvNGxpbnV4IGlmYWNlLiBDaGFuZ2VkIGkyYwogKgl0byBjb3ZlciBhZGRyZXNzaW5nIGNsYXNoZXMgb24gZGV2aWNlIGJ1c3Nlcy4gSXQncyBhbHNvIHJlYnVpbHQgc28KICoJeW91IGNhbiBhZGQgYXJiaXRhcnkgbXVsdGlwbGUgdGVsZXRleHQgZGV2aWNlcyB0byBMaW51eCB2aWRlbzRsaW51eAogKglub3cgKHdlbGwgMzIgYW55d2F5KS4KICoKICoJQWxhbiBDb3ggPEFsYW4uQ294QGxpbnV4Lm9yZz4KICoKICoJVGhlIG9yaWdpbmFsIGRyaXZlciB3YXMgaGVhdmlseSBtb2RpZmllZCB0byBtYXRjaCB0aGUgaTJjIGludGVyZmFjZQogKglJdCB3YXMgdHJ1bmNhdGVkIHRvIHVzZSB0aGUgV2luVFYgYm9hcmRzLCB0b28uCiAqCiAqCUNvcHlyaWdodCAoYykgMTk5OCBSaWNoYXJkIEd1ZW50aGVyIDxyaWNoYXJkLmd1ZW50aGVyQHN0dWRlbnQudW5pLXR1ZWJpbmdlbi5kZT4KICoKICogJElkOiBzYWE1MjQ5LmMsdiAxLjEgMTk5OC8wMy8zMCAyMjoyMzoyMyBhbGFuIEV4cCAkCiAqCiAqCURlcml2ZWQgRnJvbQogKgogKiB2dHguYzoKICogVGhpcyBpcyBhIGxvYWRhYmxlIGNoYXJhY3Rlci1kZXZpY2UtZHJpdmVyIGZvciB2aWRlb3RleHQtaW50ZXJmYWNlcwogKiAoYWthIHRlbGV0ZXh0KS4gUGxlYXNlIGNoZWNrIHRoZSBNYWtlZmlsZS9SRUFETUUgZm9yIGEgbGlzdCBvZiBzdXBwb3J0ZWQKICogaW50ZXJmYWNlcy4KICoKICogQ29weXJpZ2h0IChjKSAxOTk0LTk3IE1hcnRpbiBCdWNrICA8bWFydGluLTIuYnVja0BzdHVkZW50LnVuaS11bG0uZGU+CiAqCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LAogKiBVU0EuCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgojaW5jbHVkZSA8bGludXgvbW0uaD4KI2luY2x1ZGUgPGxpbnV4L2Vycm5vLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvaW9wb3J0Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxzdGRhcmcuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvdmlkZW90ZXh0Lmg+CiNpbmNsdWRlIDxsaW51eC92aWRlb2Rldi5oPgojaW5jbHVkZSA8bWVkaWEvdjRsMi1jb21tb24uaD4KI2luY2x1ZGUgPGxpbnV4L211dGV4Lmg+CgoKI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8YXNtL3VhY2Nlc3MuaD4KCiNkZWZpbmUgVlRYX1ZFUl9NQUogMQojZGVmaW5lIFZUWF9WRVJfTUlOIDgKCgoKI2RlZmluZSBOVU1fREFVUyA0CiNkZWZpbmUgTlVNX0JVRlMgOAojZGVmaW5lIElGX05BTUUgIlNBQTUyNDkiCgpzdGF0aWMgY29uc3QgaW50IGRpc3BfbW9kZXNbOF1bM10gPQp7Cgl7IDB4NDYsIDB4MDMsIDB4MDMgfSwJLyogRElTUE9GRiAqLwoJeyAweDQ2LCAweGNjLCAweGNjIH0sCS8qIERJU1BOT1JNICovCgl7IDB4NDQsIDB4MGYsIDB4MGYgfSwJLyogRElTUFRSQU5TICovCgl7IDB4NDYsIDB4Y2MsIDB4NDYgfSwJLyogRElTUElOUyAqLwoJeyAweDQ0LCAweDAzLCAweDAzIH0sCS8qIERJU1BPRkYsIGludGVybGFjZWQgKi8KCXsgMHg0NCwgMHhjYywgMHhjYyB9LAkvKiBESVNQTk9STSwgaW50ZXJsYWNlZCAqLwoJeyAweDQ0LCAweDBmLCAweDBmIH0sCS8qIERJU1BUUkFOUywgaW50ZXJsYWNlZCAqLwoJeyAweDQ0LCAweGNjLCAweDQ2IH0JLyogRElTUElOUywgaW50ZXJsYWNlZCAqLwp9OwoKCgojZGVmaW5lIFBBR0VfV0FJVCAgICBtc2Vjc190b19qaWZmaWVzKDMwMCkJLyogVGltZSBiZXR3ZWVuIHJlcXVlc3RpbmcgcGFnZSBhbmQgKi8KCQkJCQkJLyogY2hlY2tpbmcgc3RhdHVzIGJpdHMgKi8KI2RlZmluZSBQR0JVRl9FWFBJUkUgbXNlY3NfdG9famlmZmllcygxNTAwMCkJLyogVGltZSB0byB3YWl0IGJlZm9yZSByZXRyYW5zbWl0dGluZyAqLwoJCQkJCQkvKiBwYWdlIHJlZ2FyZGxlc3Mgb2YgaW5mb2JpdHMgKi8KdHlwZWRlZiBzdHJ1Y3QgewoJdTggcGdidWZbVlRYX1ZJUlRVQUxTSVpFXTsJCS8qIFBhZ2UtYnVmZmVyICovCgl1OCBsYXN0c3RhdFsxMF07CQkJLyogTGFzdCB2YWx1ZSBvZiBpbmZvYml0cyBmb3IgREFVICovCgl1OCBzcmVnc1s3XTsJCQkJLyogUGFnZS1yZXF1ZXN0IHJlZ2lzdGVycyAqLwoJdW5zaWduZWQgbG9uZyBleHBpcmU7CQkJLyogVGltZSB3aGVuIHBhZ2Ugd2lsbCBiZSBleHBpcmVkICovCgl1bnNpZ25lZCBjbHJmb3VuZCA6IDE7CQkJLyogVlRYSU9DQ0xSRk9VTkQgaGFzIGJlZW4gY2FsbGVkICovCgl1bnNpZ25lZCBzdG9wcGVkIDogMTsJCQkvKiBWVFhJT0NTVE9QREFVIGhhcyBiZWVuIGNhbGxlZCAqLwp9IHZkYXVfdDsKCnN0cnVjdCBzYWE1MjQ5X2RldmljZQp7Cgl2ZGF1X3QgdmRhdVtOVU1fREFVU107CQkJLyogRGF0YSBmb3IgdmlydHVhbCBEQVVzICh0aGUgNTI0OSBvbmx5IGhhcyBvbmUgKi8KCQkJCQkJLyogcmVhbCBEQVUsIHNvIHdlIGhhdmUgdG8gc2ltdWxhdGUgc29tZSBtb3JlKSAqLwoJaW50IHZ0eF91c2VfY291bnQ7CglpbnQgaXNfc2VhcmNoaW5nW05VTV9EQVVTXTsKCWludCBkaXNwX21vZGU7CglpbnQgdmlydHVhbF9tb2RlOwoJc3RydWN0IGkyY19jbGllbnQgKmNsaWVudDsKCXN0cnVjdCBtdXRleCBsb2NrOwp9OwoKCiNkZWZpbmUgQ0NUV1IgMzQJCS8qIEmyQyB3cml0ZS9yZWFkLWFkZHJlc3Mgb2YgdnR4LWNoaXAgKi8KI2RlZmluZSBDQ1RSRCAzNQojZGVmaW5lIE5PQUNLX1JFUEVBVCAxMAkJLyogUmV0cnkgYWNjZXNzIHRoaXMgbWFueSB0aW1lcyBvbiBmYWlsdXJlICovCiNkZWZpbmUgQ0xFQVJfREVMQVkgICBtc2Vjc190b19qaWZmaWVzKDUwKQkvKiBUaW1lIHJlcXVpcmVkIHRvIGNsZWFyIGEgcGFnZSAqLwojZGVmaW5lIFJFQURZX1RJTUVPVVQgbXNlY3NfdG9famlmZmllcygzMCkJLyogVGltZSB0byB3YWl0IGZvciByZWFkeSBzaWduYWwgb2YgSTJDLWJ1cyBpbnRlcmZhY2UgKi8KI2RlZmluZSBJTklUX0RFTEFZIDUwMAkJLyogVGltZSBpbiB1c2VjIHRvIHdhaXQgYXQgaW5pdGlhbGl6YXRpb24gb2YgQ0VBIGludGVyZmFjZSAqLwojZGVmaW5lIFNUQVJUX0RFTEFZIDEwCQkvKiBUaW1lIGluIHVzZWMgdG8gd2FpdCBiZWZvcmUgc3RhcnRpbmcgd3JpdGUtY3ljbGUgKENFQSkgKi8KCiNkZWZpbmUgVlRYX0RFVl9NSU5PUiAwCgovKiBHZW5lcmFsIGRlZmluZXMgYW5kIGRlYnVnZ2luZyBzdXBwb3J0ICovCgojZGVmaW5lIFJFU0NIRUQgZG8geyBjb25kX3Jlc2NoZWQoKTsgfSB3aGlsZSgwKQoKc3RhdGljIHN0cnVjdCB2aWRlb19kZXZpY2Ugc2FhX3RlbXBsYXRlOwkvKiBEZWNsYXJlZCBuZWFyIGJvdHRvbSAqLwoKLyogQWRkcmVzc2VzIHRvIHNjYW4gKi8Kc3RhdGljIHVuc2lnbmVkIHNob3J0IG5vcm1hbF9pMmNbXSA9IHszND4+MSxJMkNfQ0xJRU5UX0VORH07CkkyQ19DTElFTlRfSU5TTU9EOwoKc3RhdGljIHN0cnVjdCBpMmNfY2xpZW50IGNsaWVudF90ZW1wbGF0ZTsKCnN0YXRpYyBpbnQgc2FhNTI0OV9hdHRhY2goc3RydWN0IGkyY19hZGFwdGVyICphZGFwLCBpbnQgYWRkciwgaW50IGtpbmQpCnsKCWludCBwZ2J1ZjsKCWludCBlcnI7CglzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50OwoJc3RydWN0IHZpZGVvX2RldmljZSAqdmQ7CglzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UgKnQ7CgoJcHJpbnRrKEtFUk5fSU5GTyAic2FhNTI0OTogdGVsZXRleHQgY2hpcCBmb3VuZC5cbiIpOwoJY2xpZW50PWttYWxsb2Moc2l6ZW9mKCpjbGllbnQpLCBHRlBfS0VSTkVMKTsKCWlmKGNsaWVudD09TlVMTCkKCQlyZXR1cm4gLUVOT01FTTsKCWNsaWVudF90ZW1wbGF0ZS5hZGFwdGVyID0gYWRhcDsKCWNsaWVudF90ZW1wbGF0ZS5hZGRyID0gYWRkcjsKCW1lbWNweShjbGllbnQsICZjbGllbnRfdGVtcGxhdGUsIHNpemVvZigqY2xpZW50KSk7Cgl0ID0ga3phbGxvYyhzaXplb2YoKnQpLCBHRlBfS0VSTkVMKTsKCWlmKHQ9PU5VTEwpCgl7CgkJa2ZyZWUoY2xpZW50KTsKCQlyZXR1cm4gLUVOT01FTTsKCX0KCXN0cmxjcHkoY2xpZW50LT5uYW1lLCBJRl9OQU1FLCBJMkNfTkFNRV9TSVpFKTsKCW11dGV4X2luaXQoJnQtPmxvY2spOwoKCS8qCgkgKglOb3cgY3JlYXRlIGEgdmlkZW80bGludXggZGV2aWNlCgkgKi8KCgl2ZCA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCB2aWRlb19kZXZpY2UpLCBHRlBfS0VSTkVMKTsKCWlmKHZkPT1OVUxMKQoJewoJCWtmcmVlKHQpOwoJCWtmcmVlKGNsaWVudCk7CgkJcmV0dXJuIC1FTk9NRU07Cgl9CglpMmNfc2V0X2NsaWVudGRhdGEoY2xpZW50LCB2ZCk7CgltZW1jcHkodmQsICZzYWFfdGVtcGxhdGUsIHNpemVvZigqdmQpKTsKCglmb3IgKHBnYnVmID0gMDsgcGdidWYgPCBOVU1fREFVUzsgcGdidWYrKykKCXsKCQltZW1zZXQodC0+dmRhdVtwZ2J1Zl0ucGdidWYsICcgJywgc2l6ZW9mKHQtPnZkYXVbMF0ucGdidWYpKTsKCQltZW1zZXQodC0+dmRhdVtwZ2J1Zl0uc3JlZ3MsIDAsIHNpemVvZih0LT52ZGF1WzBdLnNyZWdzKSk7CgkJbWVtc2V0KHQtPnZkYXVbcGdidWZdLmxhc3RzdGF0LCAwLCBzaXplb2YodC0+dmRhdVswXS5sYXN0c3RhdCkpOwoJCXQtPnZkYXVbcGdidWZdLmV4cGlyZSA9IDA7CgkJdC0+dmRhdVtwZ2J1Zl0uY2xyZm91bmQgPSB0cnVlOwoJCXQtPnZkYXVbcGdidWZdLnN0b3BwZWQgPSB0cnVlOwoJCXQtPmlzX3NlYXJjaGluZ1twZ2J1Zl0gPSBmYWxzZTsKCX0KCXZkLT5wcml2PXQ7CgoKCS8qCgkgKglSZWdpc3RlciBpdAoJICovCgoJaWYoKGVycj12aWRlb19yZWdpc3Rlcl9kZXZpY2UodmQsIFZGTF9UWVBFX1ZUWCwtMSkpPDApCgl7CgkJa2ZyZWUodCk7CgkJa2ZyZWUodmQpOwoJCWtmcmVlKGNsaWVudCk7CgkJcmV0dXJuIGVycjsKCX0KCXQtPmNsaWVudCA9IGNsaWVudDsKCWkyY19hdHRhY2hfY2xpZW50KGNsaWVudCk7CglyZXR1cm4gMDsKfQoKLyoKICoJV2UgZG8gbW9zdCBvZiB0aGUgaGFyZCB3b3JrIHdoZW4gd2UgYmVjb21lIGEgZGV2aWNlIG9uIHRoZSBpMmMuCiAqLwoKc3RhdGljIGludCBzYWE1MjQ5X3Byb2JlKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCkKewoJaWYgKGFkYXAtPmNsYXNzICYgSTJDX0NMQVNTX1RWX0FOQUxPRykKCQlyZXR1cm4gaTJjX3Byb2JlKGFkYXAsICZhZGRyX2RhdGEsIHNhYTUyNDlfYXR0YWNoKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IHNhYTUyNDlfZGV0YWNoKHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQpCnsKCXN0cnVjdCB2aWRlb19kZXZpY2UgKnZkID0gaTJjX2dldF9jbGllbnRkYXRhKGNsaWVudCk7CglpMmNfZGV0YWNoX2NsaWVudChjbGllbnQpOwoJdmlkZW9fdW5yZWdpc3Rlcl9kZXZpY2UodmQpOwoJa2ZyZWUodmQtPnByaXYpOwoJa2ZyZWUodmQpOwoJa2ZyZWUoY2xpZW50KTsKCXJldHVybiAwOwp9CgovKiBuZXcgSTJDIGRyaXZlciBzdXBwb3J0ICovCgpzdGF0aWMgc3RydWN0IGkyY19kcml2ZXIgaTJjX2RyaXZlcl92aWRlb3RleHQgPQp7CgkuZHJpdmVyID0gewoJCS5uYW1lIAk9IElGX05BTUUsCQkvKiBuYW1lICovCgl9LAoJLmlkIAkJPSBJMkNfRFJJVkVSSURfU0FBNTI0OSwgLyogaW4gaTJjLmggKi8KCS5hdHRhY2hfYWRhcHRlciA9IHNhYTUyNDlfcHJvYmUsCgkuZGV0YWNoX2NsaWVudCAgPSBzYWE1MjQ5X2RldGFjaCwKfTsKCnN0YXRpYyBzdHJ1Y3QgaTJjX2NsaWVudCBjbGllbnRfdGVtcGxhdGUgPSB7CgkuZHJpdmVyCQk9ICZpMmNfZHJpdmVyX3ZpZGVvdGV4dCwKCS5uYW1lCQk9ICIodW5zZXQpIiwKfTsKCi8qCiAqCVdhaXQgdGhlIGdpdmVuIG51bWJlciBvZiBqaWZmaWVzICgxMG1zKS4gVGhpcyBjYWxscyB0aGUgc2NoZWR1bGVyLCBzbyB0aGUgYWN0dWFsCiAqCWRlbGF5IG1heSBiZSBsb25nZXIuCiAqLwoKc3RhdGljIHZvaWQgamRlbGF5KHVuc2lnbmVkIGxvbmcgZGVsYXkpCnsKCXNpZ3NldF90IG9sZGJsb2NrZWQgPSBjdXJyZW50LT5ibG9ja2VkOwoKCXNwaW5fbG9ja19pcnEoJmN1cnJlbnQtPnNpZ2hhbmQtPnNpZ2xvY2spOwoJc2lnZmlsbHNldCgmY3VycmVudC0+YmxvY2tlZCk7CglyZWNhbGNfc2lncGVuZGluZygpOwoJc3Bpbl91bmxvY2tfaXJxKCZjdXJyZW50LT5zaWdoYW5kLT5zaWdsb2NrKTsKCW1zbGVlcF9pbnRlcnJ1cHRpYmxlKGppZmZpZXNfdG9fbXNlY3MoZGVsYXkpKTsKCglzcGluX2xvY2tfaXJxKCZjdXJyZW50LT5zaWdoYW5kLT5zaWdsb2NrKTsKCWN1cnJlbnQtPmJsb2NrZWQgPSBvbGRibG9ja2VkOwoJcmVjYWxjX3NpZ3BlbmRpbmcoKTsKCXNwaW5fdW5sb2NrX2lycSgmY3VycmVudC0+c2lnaGFuZC0+c2lnbG9jayk7Cn0KCgovKgogKglJMkMgaW50ZXJmYWNlcwogKi8KCnN0YXRpYyBpbnQgaTJjX3NlbmRidWYoc3RydWN0IHNhYTUyNDlfZGV2aWNlICp0LCBpbnQgcmVnLCBpbnQgY291bnQsIHU4ICpkYXRhKQp7CgljaGFyIGJ1Zls2NF07CgoJYnVmWzBdID0gcmVnOwoJbWVtY3B5KGJ1ZisxLCBkYXRhLCBjb3VudCk7CgoJaWYoaTJjX21hc3Rlcl9zZW5kKHQtPmNsaWVudCwgYnVmLCBjb3VudCsxKT09Y291bnQrMSkKCQlyZXR1cm4gMDsKCXJldHVybiAtMTsKfQoKc3RhdGljIGludCBpMmNfc2VuZGRhdGEoc3RydWN0IHNhYTUyNDlfZGV2aWNlICp0LCAuLi4pCnsKCXVuc2lnbmVkIGNoYXIgYnVmWzY0XTsKCWludCB2OwoJaW50IGN0PTA7Cgl2YV9saXN0IGFyZ3A7Cgl2YV9zdGFydChhcmdwLHQpOwoKCXdoaWxlKCh2PXZhX2FyZyhhcmdwLGludCkpIT0tMSkKCQlidWZbY3QrK109djsKCXJldHVybiBpMmNfc2VuZGJ1Zih0LCBidWZbMF0sIGN0LTEsIGJ1ZisxKTsKfQoKLyogR2V0IGNvdW50IG51bWJlciBvZiBieXRlcyBmcm9tIEmyQy1kZXZpY2UgYXQgYWRkcmVzcyBhZHIsIHN0b3JlIHRoZW0gaW4gYnVmLiBTdGFydCAmIHN0b3AKICogaGFuZHNoYWtpbmcgaXMgZG9uZSBieSB0aGlzIHJvdXRpbmUsIGFjayB3aWxsIGJlIHNlbnQgYWZ0ZXIgdGhlIGxhc3QgYnl0ZSB0byBpbmhpYml0IGZ1cnRoZXIKICogc2VuZGluZyBvZiBkYXRhLiBJZiB1YWNjZXNzIGlzICd0cnVlJywgZGF0YSBpcyB3cml0dGVuIHRvIHVzZXItc3BhY2Ugd2l0aCBwdXRfdXNlci4KICogUmV0dXJucyAtMSBpZiBJskMtZGV2aWNlIGRpZG4ndCBzZW5kIGFja25vd2xlZGdlLCAwIG90aGVyd2lzZQogKi8KCnN0YXRpYyBpbnQgaTJjX2dldGRhdGEoc3RydWN0IHNhYTUyNDlfZGV2aWNlICp0LCBpbnQgY291bnQsIHU4ICpidWYpCnsKCWlmKGkyY19tYXN0ZXJfcmVjdih0LT5jbGllbnQsIGJ1ZiwgY291bnQpIT1jb3VudCkKCQlyZXR1cm4gLTE7CglyZXR1cm4gMDsKfQoKCi8qCiAqCVN0YW5kYXJkIGNoYXJhY3Rlci1kZXZpY2UtZHJpdmVyIGZ1bmN0aW9ucwogKi8KCnN0YXRpYyBpbnQgZG9fc2FhNTI0OV9pb2N0bChzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSwKCQkJICAgIHVuc2lnbmVkIGludCBjbWQsIHZvaWQgKmFyZykKewoJc3RhdGljIGludCB2aXJ0dWFsX21vZGUgPSBmYWxzZTsKCXN0cnVjdCB2aWRlb19kZXZpY2UgKnZkID0gdmlkZW9fZGV2ZGF0YShmaWxlKTsKCXN0cnVjdCBzYWE1MjQ5X2RldmljZSAqdD12ZC0+cHJpdjsKCglzd2l0Y2goY21kKQoJewoJCWNhc2UgVlRYSU9DR0VUSU5GTzoKCQl7CgkJCXZ0eF9pbmZvX3QgKmluZm8gPSBhcmc7CgkJCWluZm8tPnZlcnNpb25fbWFqb3IgPSBWVFhfVkVSX01BSjsKCQkJaW5mby0+dmVyc2lvbl9taW5vciA9IFZUWF9WRVJfTUlOOwoJCQlpbmZvLT5udW1wYWdlcyA9IE5VTV9EQVVTOwoJCQkvKmluZm8tPmNjdF90eXBlID0gQ0NUX1RZUEU7Ki8KCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ0NMUlBBR0U6CgkJewoJCQl2dHhfcGFnZXJlcV90ICpyZXEgPSBhcmc7CgoJCQlpZiAocmVxLT5wZ2J1ZiA8IDAgfHwgcmVxLT5wZ2J1ZiA+PSBOVU1fREFVUykKCQkJCXJldHVybiAtRUlOVkFMOwoJCQltZW1zZXQodC0+dmRhdVtyZXEtPnBnYnVmXS5wZ2J1ZiwgJyAnLCBzaXplb2YodC0+dmRhdVswXS5wZ2J1ZikpOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLmNscmZvdW5kID0gdHJ1ZTsKCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ0NMUkZPVU5EOgoJCXsKCQkJdnR4X3BhZ2VyZXFfdCAqcmVxID0gYXJnOwoKCQkJaWYgKHJlcS0+cGdidWYgPCAwIHx8IHJlcS0+cGdidWYgPj0gTlVNX0RBVVMpCgkJCQlyZXR1cm4gLUVJTlZBTDsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5jbHJmb3VuZCA9IHRydWU7CgkJCXJldHVybiAwOwoJCX0KCgkJY2FzZSBWVFhJT0NQQUdFUkVROgoJCXsKCQkJdnR4X3BhZ2VyZXFfdCAqcmVxID0gYXJnOwoJCQlpZiAoIShyZXEtPnBhZ2VtYXNrICYgUEdNQVNLX1BBR0UpKQoJCQkJcmVxLT5wYWdlID0gMDsKCQkJaWYgKCEocmVxLT5wYWdlbWFzayAmIFBHTUFTS19IT1VSKSkKCQkJCXJlcS0+aG91ciA9IDA7CgkJCWlmICghKHJlcS0+cGFnZW1hc2sgJiBQR01BU0tfTUlOVVRFKSkKCQkJCXJlcS0+bWludXRlID0gMDsKCQkJaWYgKHJlcS0+cGFnZSA8IDAgfHwgcmVxLT5wYWdlID4gMHg4ZmYpIC8qIDdGRiA/PyAqLwoJCQkJcmV0dXJuIC1FSU5WQUw7CgkJCXJlcS0+cGFnZSAmPSAweDdmZjsKCQkJaWYgKHJlcS0+aG91ciA8IDAgfHwgcmVxLT5ob3VyID4gMHgzZiB8fCByZXEtPm1pbnV0ZSA8IDAgfHwgcmVxLT5taW51dGUgPiAweDdmIHx8CgkJCQlyZXEtPnBhZ2VtYXNrIDwgMCB8fCByZXEtPnBhZ2VtYXNrID49IFBHTUFTS19NQVggfHwgcmVxLT5wZ2J1ZiA8IDAgfHwgcmVxLT5wZ2J1ZiA+PSBOVU1fREFVUykKCQkJCXJldHVybiAtRUlOVkFMOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzWzBdID0gKHJlcS0+cGFnZW1hc2sgJiBQR19IVU5EID8gMHgxMCA6IDApIHwgKHJlcS0+cGFnZSAvIDB4MTAwKTsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5zcmVnc1sxXSA9IChyZXEtPnBhZ2VtYXNrICYgUEdfVEVOID8gMHgxMCA6IDApIHwgKChyZXEtPnBhZ2UgLyAweDEwKSAmIDB4Zik7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3JlZ3NbMl0gPSAocmVxLT5wYWdlbWFzayAmIFBHX1VOSVQgPyAweDEwIDogMCkgfCAocmVxLT5wYWdlICYgMHhmKTsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5zcmVnc1szXSA9IChyZXEtPnBhZ2VtYXNrICYgSFJfVEVOID8gMHgxMCA6IDApIHwgKHJlcS0+aG91ciAvIDB4MTApOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzWzRdID0gKHJlcS0+cGFnZW1hc2sgJiBIUl9VTklUID8gMHgxMCA6IDApIHwgKHJlcS0+aG91ciAmIDB4Zik7CgkJCXQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3JlZ3NbNV0gPSAocmVxLT5wYWdlbWFzayAmIE1JTl9URU4gPyAweDEwIDogMCkgfCAocmVxLT5taW51dGUgLyAweDEwKTsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5zcmVnc1s2XSA9IChyZXEtPnBhZ2VtYXNrICYgTUlOX1VOSVQgPyAweDEwIDogMCkgfCAocmVxLT5taW51dGUgJiAweGYpOwoJCQl0LT52ZGF1W3JlcS0+cGdidWZdLnN0b3BwZWQgPSBmYWxzZTsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5jbHJmb3VuZCA9IHRydWU7CgkJCXQtPmlzX3NlYXJjaGluZ1tyZXEtPnBnYnVmXSA9IHRydWU7CgkJCXJldHVybiAwOwoJCX0KCgkJY2FzZSBWVFhJT0NHRVRTVEFUOgoJCXsKCQkJdnR4X3BhZ2VyZXFfdCAqcmVxID0gYXJnOwoJCQl1OCBpbmZvYml0c1sxMF07CgkJCXZ0eF9wYWdlaW5mb190IGluZm87CgkJCWludCBhOwoKCQkJaWYgKHJlcS0+cGdidWYgPCAwIHx8IHJlcS0+cGdidWYgPj0gTlVNX0RBVVMpCgkJCQlyZXR1cm4gLUVJTlZBTDsKCQkJaWYgKCF0LT52ZGF1W3JlcS0+cGdidWZdLnN0b3BwZWQpCgkJCXsKCQkJCWlmIChpMmNfc2VuZGRhdGEodCwgMiwgMCwgLTEpIHx8CgkJCQkJaTJjX3NlbmRidWYodCwgMywgc2l6ZW9mKHQtPnZkYXVbMF0uc3JlZ3MpLCB0LT52ZGF1W3JlcS0+cGdidWZdLnNyZWdzKSB8fAoJCQkJCWkyY19zZW5kZGF0YSh0LCA4LCAwLCAyNSwgMCwgJyAnLCAnICcsICcgJywgJyAnLCAnICcsICcgJywgJyAnLCAnICcsICcgJywgLTEpIHx8CgkJCQkJaTJjX3NlbmRkYXRhKHQsIDIsIDAsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0uc3JlZ3NbMF0gfCA4LCAtMSkgfHwKCQkJCQlpMmNfc2VuZGRhdGEodCwgOCwgMCwgMjUsIDAsIC0xKSkKCQkJCQlyZXR1cm4gLUVJTzsKCQkJCWpkZWxheShQQUdFX1dBSVQpOwoJCQkJaWYgKGkyY19nZXRkYXRhKHQsIDEwLCBpbmZvYml0cykpCgkJCQkJcmV0dXJuIC1FSU87CgoJCQkJaWYgKCEoaW5mb2JpdHNbOF0gJiAweDEwKSAmJiAhKGluZm9iaXRzWzddICYgMHhmMCkgJiYJLyogY2hlY2sgRk9VTkQtYml0ICovCgkJCQkJKG1lbWNtcChpbmZvYml0cywgdC0+dmRhdVtyZXEtPnBnYnVmXS5sYXN0c3RhdCwgc2l6ZW9mKGluZm9iaXRzKSkgfHwKCQkJCQl0aW1lX2FmdGVyX2VxKGppZmZpZXMsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0uZXhwaXJlKSkpCgkJCQl7CQkvKiBjaGVjayBpZiBuZXcgcGFnZSBhcnJpdmVkICovCgkJCQkJaWYgKGkyY19zZW5kZGF0YSh0LCA4LCAwLCAwLCAwLCAtMSkgfHwKCQkJCQkJaTJjX2dldGRhdGEodCwgVlRYX1BBR0VTSVpFLCB0LT52ZGF1W3JlcS0+cGdidWZdLnBnYnVmKSkKCQkJCQkJcmV0dXJuIC1FSU87CgkJCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5leHBpcmUgPSBqaWZmaWVzICsgUEdCVUZfRVhQSVJFOwoJCQkJCW1lbXNldCh0LT52ZGF1W3JlcS0+cGdidWZdLnBnYnVmICsgVlRYX1BBR0VTSVpFLCAnICcsIFZUWF9WSVJUVUFMU0laRSAtIFZUWF9QQUdFU0laRSk7CgkJCQkJaWYgKHQtPnZpcnR1YWxfbW9kZSkKCQkJCQl7CgkJCQkJCS8qIFBhY2tldCBYLzI0ICovCgkJCQkJCWlmIChpMmNfc2VuZGRhdGEodCwgOCwgMCwgMHgyMCwgMCwgLTEpIHx8CgkJCQkJCQlpMmNfZ2V0ZGF0YSh0LCA0MCwgdC0+dmRhdVtyZXEtPnBnYnVmXS5wZ2J1ZiArIFZUWF9QQUdFU0laRSArIDIwICogNDApKQoJCQkJCQkJcmV0dXJuIC1FSU87CgkJCQkJCS8qIFBhY2tldCBYLzI3LzAgKi8KCQkJCQkJaWYgKGkyY19zZW5kZGF0YSh0LCA4LCAwLCAweDIxLCAwLCAtMSkgfHwKCQkJCQkJCWkyY19nZXRkYXRhKHQsIDQwLCB0LT52ZGF1W3JlcS0+cGdidWZdLnBnYnVmICsgVlRYX1BBR0VTSVpFICsgMTYgKiA0MCkpCgkJCQkJCQlyZXR1cm4gLUVJTzsKCQkJCQkJLyogUGFja2V0IDgvMzAvMC4uLjgvMzAvMTUKCQkJCQkJICogRklYTUU6IEFGQUlLLCB0aGUgNTI0OSBkb2VzIGhhbW1pbmctZGVjb2RpbmcgZm9yIHNvbWUgYnl0ZXMgaW4gcGFja2V0IDgvMzAsCgkJCQkJCSAqICAgICAgICBzbyB3ZSBzaG91bGQgdW5kbyB0aGlzIGhlcmUuCgkJCQkJCSAqLwoJCQkJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDgsIDAsIDB4MjIsIDAsIC0xKSB8fAoJCQkJCQkJaTJjX2dldGRhdGEodCwgNDAsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0ucGdidWYgKyBWVFhfUEFHRVNJWkUgKyAyMyAqIDQwKSkKCQkJCQkJCXJldHVybiAtRUlPOwoJCQkJCX0KCQkJCQl0LT52ZGF1W3JlcS0+cGdidWZdLmNscmZvdW5kID0gZmFsc2U7CgkJCQkJbWVtY3B5KHQtPnZkYXVbcmVxLT5wZ2J1Zl0ubGFzdHN0YXQsIGluZm9iaXRzLCBzaXplb2YoaW5mb2JpdHMpKTsKCQkJCX0KCQkJCWVsc2UKCQkJCXsKCQkJCQltZW1jcHkoaW5mb2JpdHMsIHQtPnZkYXVbcmVxLT5wZ2J1Zl0ubGFzdHN0YXQsIHNpemVvZihpbmZvYml0cykpOwoJCQkJfQoJCQl9CgkJCWVsc2UKCQkJewoJCQkJbWVtY3B5KGluZm9iaXRzLCB0LT52ZGF1W3JlcS0+cGdidWZdLmxhc3RzdGF0LCBzaXplb2YoaW5mb2JpdHMpKTsKCQkJfQoKCQkJaW5mby5wYWdlbnVtID0gKChpbmZvYml0c1s4XSA8PCA4KSAmIDB4NzAwKSB8ICgoaW5mb2JpdHNbMV0gPDwgNCkgJiAweGYwKSB8IChpbmZvYml0c1swXSAmIDB4MGYpOwoJCQlpZiAoaW5mby5wYWdlbnVtIDwgMHgxMDApCgkJCQlpbmZvLnBhZ2VudW0gKz0gMHg4MDA7CgkJCWluZm8uaG91ciA9ICgoaW5mb2JpdHNbNV0gPDwgNCkgJiAweDMwKSB8IChpbmZvYml0c1s0XSAmIDB4MGYpOwoJCQlpbmZvLm1pbnV0ZSA9ICgoaW5mb2JpdHNbM10gPDwgNCkgJiAweDcwKSB8IChpbmZvYml0c1syXSAmIDB4MGYpOwoJCQlpbmZvLmNoYXJzZXQgPSAoKGluZm9iaXRzWzddID4+IDEpICYgNyk7CgkJCWluZm8uZGVsZXRlID0gISEoaW5mb2JpdHNbM10gJiA4KTsKCQkJaW5mby5oZWFkbGluZSA9ICEhKGluZm9iaXRzWzVdICYgNCk7CgkJCWluZm8uc3VidGl0bGUgPSAhIShpbmZvYml0c1s1XSAmIDgpOwoJCQlpbmZvLnN1cHBfaGVhZGVyID0gISEoaW5mb2JpdHNbNl0gJiAxKTsKCQkJaW5mby51cGRhdGUgPSAhIShpbmZvYml0c1s2XSAmIDIpOwoJCQlpbmZvLmludGVyX3NlcSA9ICEhKGluZm9iaXRzWzZdICYgNCk7CgkJCWluZm8uZGlzX2Rpc3AgPSAhIShpbmZvYml0c1s2XSAmIDgpOwoJCQlpbmZvLnNlcmlhbCA9ICEhKGluZm9iaXRzWzddICYgMSk7CgkJCWluZm8ubm90Zm91bmQgPSAhIShpbmZvYml0c1s4XSAmIDB4MTApOwoJCQlpbmZvLnBibGYgPSAhIShpbmZvYml0c1s5XSAmIDB4MjApOwoJCQlpbmZvLmhhbW1pbmcgPSAwOwoJCQlmb3IgKGEgPSAwOyBhIDw9IDc7IGErKykKCQkJewoJCQkJaWYgKGluZm9iaXRzW2FdICYgMHhmMCkKCQkJCXsKCQkJCQlpbmZvLmhhbW1pbmcgPSAxOwoJCQkJCWJyZWFrOwoJCQkJfQoJCQl9CgkJCWlmICh0LT52ZGF1W3JlcS0+cGdidWZdLmNscmZvdW5kKQoJCQkJaW5mby5ub3Rmb3VuZCA9IDE7CgkJCWlmKGNvcHlfdG9fdXNlcihyZXEtPmJ1ZmZlciwgJmluZm8sIHNpemVvZih2dHhfcGFnZWluZm9fdCkpKQoJCQkJcmV0dXJuIC1FRkFVTFQ7CgkJCWlmICghaW5mby5oYW1taW5nICYmICFpbmZvLm5vdGZvdW5kKQoJCQl7CgkJCQl0LT5pc19zZWFyY2hpbmdbcmVxLT5wZ2J1Zl0gPSBmYWxzZTsKCQkJfQoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DR0VUUEFHRToKCQl7CgkJCXZ0eF9wYWdlcmVxX3QgKnJlcSA9IGFyZzsKCQkJaW50IHN0YXJ0LCBlbmQ7CgoJCQlpZiAocmVxLT5wZ2J1ZiA8IDAgfHwgcmVxLT5wZ2J1ZiA+PSBOVU1fREFVUyB8fCByZXEtPnN0YXJ0IDwgMCB8fAoJCQkJcmVxLT5zdGFydCA+IHJlcS0+ZW5kIHx8IHJlcS0+ZW5kID49ICh2aXJ0dWFsX21vZGUgPyBWVFhfVklSVFVBTFNJWkUgOiBWVFhfUEFHRVNJWkUpKQoJCQkJcmV0dXJuIC1FSU5WQUw7CgkJCWlmKGNvcHlfdG9fdXNlcihyZXEtPmJ1ZmZlciwgJnQtPnZkYXVbcmVxLT5wZ2J1Zl0ucGdidWZbcmVxLT5zdGFydF0sIHJlcS0+ZW5kIC0gcmVxLT5zdGFydCArIDEpKQoJCQkJcmV0dXJuIC1FRkFVTFQ7CgoJCQkgLyoKCQkJICAqCUFsd2F5cyByZWFkIHRoZSB0aW1lIGRpcmVjdGx5IGZyb20gU0FBNTI0OQoJCQkgICovCgoJCQlpZiAocmVxLT5zdGFydCA8PSAzOSAmJiByZXEtPmVuZCA+PSAzMikKCQkJewoJCQkJaW50IGxlbjsKCQkJCWNoYXIgYnVmWzE2XTsKCQkJCXN0YXJ0ID0gbWF4KHJlcS0+c3RhcnQsIDMyKTsKCQkJCWVuZCA9IG1pbihyZXEtPmVuZCwgMzkpOwoJCQkJbGVuPWVuZC1zdGFydCsxOwoJCQkJaWYgKGkyY19zZW5kZGF0YSh0LCA4LCAwLCAwLCBzdGFydCwgLTEpIHx8CgkJCQkJaTJjX2dldGRhdGEodCwgbGVuLCBidWYpKQoJCQkJCXJldHVybiAtRUlPOwoJCQkJaWYoY29weV90b191c2VyKHJlcS0+YnVmZmVyK3N0YXJ0LXJlcS0+c3RhcnQsIGJ1ZiwgbGVuKSkKCQkJCQlyZXR1cm4gLUVGQVVMVDsKCQkJfQoJCQkvKiBJbnNlcnQgdGhlIGN1cnJlbnQgaGVhZGVyIGlmIERBVSBpcyBzdGlsbCBzZWFyY2hpbmcgZm9yIGEgcGFnZSAqLwoJCQlpZiAocmVxLT5zdGFydCA8PSAzMSAmJiByZXEtPmVuZCA+PSA3ICYmIHQtPmlzX3NlYXJjaGluZ1tyZXEtPnBnYnVmXSkKCQkJewoJCQkJY2hhciBidWZbMzJdOwoJCQkJaW50IGxlbjsKCQkJCXN0YXJ0ID0gbWF4KHJlcS0+c3RhcnQsIDcpOwoJCQkJZW5kID0gbWluKHJlcS0+ZW5kLCAzMSk7CgkJCQlsZW49ZW5kLXN0YXJ0KzE7CgkJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDgsIDAsIDAsIHN0YXJ0LCAtMSkgfHwKCQkJCQlpMmNfZ2V0ZGF0YSh0LCBsZW4sIGJ1ZikpCgkJCQkJcmV0dXJuIC1FSU87CgkJCQlpZihjb3B5X3RvX3VzZXIocmVxLT5idWZmZXIrc3RhcnQtcmVxLT5zdGFydCwgYnVmLCBsZW4pKQoJCQkJCXJldHVybiAtRUZBVUxUOwoJCQl9CgkJCXJldHVybiAwOwoJCX0KCgkJY2FzZSBWVFhJT0NTVE9QREFVOgoJCXsKCQkJdnR4X3BhZ2VyZXFfdCAqcmVxID0gYXJnOwoKCQkJaWYgKHJlcS0+cGdidWYgPCAwIHx8IHJlcS0+cGdidWYgPj0gTlVNX0RBVVMpCgkJCQlyZXR1cm4gLUVJTlZBTDsKCQkJdC0+dmRhdVtyZXEtPnBnYnVmXS5zdG9wcGVkID0gdHJ1ZTsKCQkJdC0+aXNfc2VhcmNoaW5nW3JlcS0+cGdidWZdID0gZmFsc2U7CgkJCXJldHVybiAwOwoJCX0KCgkJY2FzZSBWVFhJT0NQVVRQQUdFOgoJCWNhc2UgVlRYSU9DU0VURElTUDoKCQljYXNlIFZUWElPQ1BVVFNUQVQ6CgkJCXJldHVybiAwOwoKCQljYXNlIFZUWElPQ0NMUkNBQ0hFOgoJCXsKCQkJaWYgKGkyY19zZW5kZGF0YSh0LCAwLCBOVU1fREFVUywgMCwgOCwgLTEpIHx8IGkyY19zZW5kZGF0YSh0LCAxMSwKCQkJCScgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLAoJCQkJJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsJyAnLCcgJywnICcsIC0xKSkKCQkJCXJldHVybiAtRUlPOwoJCQlpZiAoaTJjX3NlbmRkYXRhKHQsIDMsIDB4MjAsIC0xKSkKCQkJCXJldHVybiAtRUlPOwoJCQlqZGVsYXkoMTAgKiBDTEVBUl9ERUxBWSk7CQkJLyogSSBoYXZlIG5vIGlkZWEgaG93IGxvbmcgd2UgaGF2ZSB0byB3YWl0IGhlcmUgKi8KCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ1NFVFZJUlQ6CgkJewoJCQkvKiBUaGUgU0FBNTI0OSBoYXMgdmlydHVhbC1yb3cgcmVjZXB0aW9uIHR1cm5lZCBvbiBhbHdheXMgKi8KCQkJdC0+dmlydHVhbF9tb2RlID0gKGludCkobG9uZylhcmc7CgkJCXJldHVybiAwOwoJCX0KCX0KCXJldHVybiAtRUlOVkFMOwp9CgovKgogKiBUcmFuc2xhdGVzIG9sZCB2dHggSU9DVExzIHRvIG5ldyBvbmVzCiAqCiAqIFRoaXMga2VlcHMgbmV3IGtlcm5lbCB2ZXJzaW9ucyBjb21wYXRpYmxlIHdpdGggb2xkIHVzZXJzcGFjZSBwcm9ncmFtcy4KICovCnN0YXRpYyBpbmxpbmUgdW5zaWduZWQgaW50IHZ0eF9maXhfY29tbWFuZCh1bnNpZ25lZCBpbnQgY21kKQp7Cglzd2l0Y2ggKGNtZCkgewoJY2FzZSBWVFhJT0NHRVRJTkZPX09MRDoKCQljbWQgPSBWVFhJT0NHRVRJTkZPOwoJCWJyZWFrOwoJY2FzZSBWVFhJT0NDTFJQQUdFX09MRDoKCQljbWQgPSBWVFhJT0NDTFJQQUdFOwoJCWJyZWFrOwoJY2FzZSBWVFhJT0NDTFJGT1VORF9PTEQ6CgkJY21kID0gVlRYSU9DQ0xSRk9VTkQ7CgkJYnJlYWs7CgljYXNlIFZUWElPQ1BBR0VSRVFfT0xEOgoJCWNtZCA9IFZUWElPQ1BBR0VSRVE7CgkJYnJlYWs7CgljYXNlIFZUWElPQ0dFVFNUQVRfT0xEOgoJCWNtZCA9IFZUWElPQ0dFVFNUQVQ7CgkJYnJlYWs7CgljYXNlIFZUWElPQ0dFVFBBR0VfT0xEOgoJCWNtZCA9IFZUWElPQ0dFVFBBR0U7CgkJYnJlYWs7CgljYXNlIFZUWElPQ1NUT1BEQVVfT0xEOgoJCWNtZCA9IFZUWElPQ1NUT1BEQVU7CgkJYnJlYWs7CgljYXNlIFZUWElPQ1BVVFBBR0VfT0xEOgoJCWNtZCA9IFZUWElPQ1BVVFBBR0U7CgkJYnJlYWs7CgljYXNlIFZUWElPQ1NFVERJU1BfT0xEOgoJCWNtZCA9IFZUWElPQ1NFVERJU1A7CgkJYnJlYWs7CgljYXNlIFZUWElPQ1BVVFNUQVRfT0xEOgoJCWNtZCA9IFZUWElPQ1BVVFNUQVQ7CgkJYnJlYWs7CgljYXNlIFZUWElPQ0NMUkNBQ0hFX09MRDoKCQljbWQgPSBWVFhJT0NDTFJDQUNIRTsKCQlicmVhazsKCWNhc2UgVlRYSU9DU0VUVklSVF9PTEQ6CgkJY21kID0gVlRYSU9DU0VUVklSVDsKCQlicmVhazsKCX0KCXJldHVybiBjbWQ7Cn0KCi8qCiAqCUhhbmRsZSB0aGUgbG9ja2luZwogKi8KCnN0YXRpYyBpbnQgc2FhNTI0OV9pb2N0bChzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSwKCQkJIHVuc2lnbmVkIGludCBjbWQsIHVuc2lnbmVkIGxvbmcgYXJnKQp7CglzdHJ1Y3QgdmlkZW9fZGV2aWNlICp2ZCA9IHZpZGVvX2RldmRhdGEoZmlsZSk7CglzdHJ1Y3Qgc2FhNTI0OV9kZXZpY2UgKnQ9dmQtPnByaXY7CglpbnQgZXJyOwoKCWNtZCA9IHZ0eF9maXhfY29tbWFuZChjbWQpOwoJbXV0ZXhfbG9jaygmdC0+bG9jayk7CgllcnIgPSB2aWRlb191c2VyY29weShpbm9kZSxmaWxlLGNtZCxhcmcsZG9fc2FhNTI0OV9pb2N0bCk7CgltdXRleF91bmxvY2soJnQtPmxvY2spOwoJcmV0dXJuIGVycjsKfQoKc3RhdGljIGludCBzYWE1MjQ5X29wZW4oc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCnsKCXN0cnVjdCB2aWRlb19kZXZpY2UgKnZkID0gdmlkZW9fZGV2ZGF0YShmaWxlKTsKCXN0cnVjdCBzYWE1MjQ5X2RldmljZSAqdD12ZC0+cHJpdjsKCWludCBlcnIscGdidWY7CgoJZXJyID0gdmlkZW9fZXhjbHVzaXZlX29wZW4oaW5vZGUsZmlsZSk7CglpZiAoZXJyIDwgMCkKCQlyZXR1cm4gZXJyOwoKCWlmICh0LT5jbGllbnQ9PU5VTEwpIHsKCQllcnIgPSAtRU5PREVWOwoJCWdvdG8gZmFpbDsKCX0KCglpZiAoaTJjX3NlbmRkYXRhKHQsIDAsIDAsIC0xKSB8fAkJLyogU2VsZWN0IFIxMSAqLwoJCQkJCQkvKiBUdXJuIG9mZiBwYXJpdHkgY2hlY2tzICh3ZSBkbyB0aGlzIG91cnNlbHZlcykgKi8KCQlpMmNfc2VuZGRhdGEodCwgMSwgZGlzcF9tb2Rlc1t0LT5kaXNwX21vZGVdWzBdLCAwLCAtMSkgfHwKCQkJCQkJLyogRGlzcGxheSBUVi1waWN0dXJlLCBubyB2aXJ0dWFsIHJvd3MgKi8KCQlpMmNfc2VuZGRhdGEodCwgNCwgTlVNX0RBVVMsIGRpc3BfbW9kZXNbdC0+ZGlzcF9tb2RlXVsxXSwgZGlzcF9tb2Rlc1t0LT5kaXNwX21vZGVdWzJdLCA3LCAtMSkpIC8qIFNldCBkaXNwbGF5IHRvIHBhZ2UgNCAqLwoKCXsKCQllcnIgPSAtRUlPOwoJCWdvdG8gZmFpbDsKCX0KCglmb3IgKHBnYnVmID0gMDsgcGdidWYgPCBOVU1fREFVUzsgcGdidWYrKykKCXsKCQltZW1zZXQodC0+dmRhdVtwZ2J1Zl0ucGdidWYsICcgJywgc2l6ZW9mKHQtPnZkYXVbMF0ucGdidWYpKTsKCQltZW1zZXQodC0+dmRhdVtwZ2J1Zl0uc3JlZ3MsIDAsIHNpemVvZih0LT52ZGF1WzBdLnNyZWdzKSk7CgkJbWVtc2V0KHQtPnZkYXVbcGdidWZdLmxhc3RzdGF0LCAwLCBzaXplb2YodC0+dmRhdVswXS5sYXN0c3RhdCkpOwoJCXQtPnZkYXVbcGdidWZdLmV4cGlyZSA9IDA7CgkJdC0+dmRhdVtwZ2J1Zl0uY2xyZm91bmQgPSB0cnVlOwoJCXQtPnZkYXVbcGdidWZdLnN0b3BwZWQgPSB0cnVlOwoJCXQtPmlzX3NlYXJjaGluZ1twZ2J1Zl0gPSBmYWxzZTsKCX0KCXQtPnZpcnR1YWxfbW9kZSA9IGZhbHNlOwoJcmV0dXJuIDA7CgogZmFpbDoKCXZpZGVvX2V4Y2x1c2l2ZV9yZWxlYXNlKGlub2RlLGZpbGUpOwoJcmV0dXJuIGVycjsKfQoKCgpzdGF0aWMgaW50IHNhYTUyNDlfcmVsZWFzZShzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSkKewoJc3RydWN0IHZpZGVvX2RldmljZSAqdmQgPSB2aWRlb19kZXZkYXRhKGZpbGUpOwoJc3RydWN0IHNhYTUyNDlfZGV2aWNlICp0PXZkLT5wcml2OwoJaTJjX3NlbmRkYXRhKHQsIDEsIDB4MjAsIC0xKTsJCS8qIFR1cm4gb2ZmIENDVCAqLwoJaTJjX3NlbmRkYXRhKHQsIDUsIDMsIDMsIC0xKTsJCS8qIFR1cm4gb2ZmIFRWLWRpc3BsYXkgKi8KCXZpZGVvX2V4Y2x1c2l2ZV9yZWxlYXNlKGlub2RlLGZpbGUpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgX19pbml0IGluaXRfc2FhXzUyNDkgKHZvaWQpCnsKCXByaW50ayhLRVJOX0lORk8gIlNBQTUyNDkgZHJpdmVyICgiIElGX05BTUUgIiBpbnRlcmZhY2UpIGZvciBWaWRlb1RleHQgdmVyc2lvbiAlZC4lZFxuIiwKCQkJVlRYX1ZFUl9NQUosIFZUWF9WRVJfTUlOKTsKCXJldHVybiBpMmNfYWRkX2RyaXZlcigmaTJjX2RyaXZlcl92aWRlb3RleHQpOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgY2xlYW51cF9zYWFfNTI0OSAodm9pZCkKewoJaTJjX2RlbF9kcml2ZXIoJmkyY19kcml2ZXJfdmlkZW90ZXh0KTsKfQoKbW9kdWxlX2luaXQoaW5pdF9zYWFfNTI0OSk7Cm1vZHVsZV9leGl0KGNsZWFudXBfc2FhXzUyNDkpOwoKc3RhdGljIGNvbnN0IHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgc2FhX2ZvcHMgPSB7Cgkub3duZXIJCT0gVEhJU19NT0RVTEUsCgkub3BlbgkJPSBzYWE1MjQ5X29wZW4sCgkucmVsZWFzZSAgICAgICAJPSBzYWE1MjQ5X3JlbGVhc2UsCgkuaW9jdGwgICAgICAgICAgPSBzYWE1MjQ5X2lvY3RsLAoJLmNvbXBhdF9pb2N0bAk9IHY0bF9jb21wYXRfaW9jdGwzMiwKCS5sbHNlZWsgICAgICAgICA9IG5vX2xsc2VlaywKfTsKCnN0YXRpYyBzdHJ1Y3QgdmlkZW9fZGV2aWNlIHNhYV90ZW1wbGF0ZSA9CnsKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKCS5uYW1lCQk9IElGX05BTUUsCgkudHlwZQkJPSBWSURfVFlQRV9URUxFVEVYVCwJLyp8IFZJRF9UWVBFX1RVTkVSID8/ICovCgkuZm9wcyAgICAgICAgICAgPSAmc2FhX2ZvcHMsCn07CgpNT0RVTEVfTElDRU5TRSgiR1BMIik7Cg==