LyoKICogRHJpdmVyIGZvciB0aGUgU0FBNTI0NkEgb3IgU0FBNTI4MSBUZWxldGV4dCAoPVZpZGVvdGV4dCkgZGVjb2RlciBjaGlwcyBmcm9tCiAqIFBoaWxpcHMuCiAqCiAqIE9ubHkgY2FwdHVyaW5nIG9mIFRlbGV0ZXh0IHBhZ2VzIGlzIHRlc3RlZC4gVGhlIHZpZGVvdGV4dCBjaGlwcyBhbHNvIGhhdmUgYQogKiBUViBvdXRwdXQgYnV0IG15IGhhcmR3YXJlIGRvZXNuJ3QgdXNlIGl0LiBGb3IgdGhpcyByZWFzb24gdGhpcyBkcml2ZXIgZG9lcwogKiBub3Qgc3VwcG9ydCBjaGFuZ2luZyBhbnkgVFYgZGlzcGxheSBzZXR0aW5ncy4KICoKICogQ29weXJpZ2h0IChDKSAyMDA0IE1pY2hhZWwgR2VuZyA8bGludXhATWljaGFlbEdlbmcuZGU+CiAqCiAqIERlcml2ZWQgZnJvbQogKgogKiBzYWE1MjQ5IGRyaXZlcgogKiBDb3B5cmlnaHQgKEMpIDE5OTggUmljaGFyZCBHdWVudGhlcgogKiA8cmljaGFyZC5ndWVudGhlckBzdHVkZW50LnVuaS10dWViaW5nZW4uZGU+CiAqCiAqIHdpdGggY2hhbmdlcyBieQogKiBBbGFuIENveCA8QWxhbi5Db3hAbGludXgub3JnPgogKgogKiBhbmQKICoKICogdnR4LmMKICogQ29weXJpZ2h0IChDKSAxOTk0LTk3IE1hcnRpbiBCdWNrICA8bWFydGluLTIuYnVja0BzdHVkZW50LnVuaS11bG0uZGU+CiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5CiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YgdGhlIExpY2Vuc2UsIG9yCiAqIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlCiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuCiAqCiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlCiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtOyBpZiBub3QsIHdyaXRlIHRvIHRoZSBGcmVlIFNvZnR3YXJlCiAqIEZvdW5kYXRpb24sIEluYy4sIDU5IFRlbXBsZSBQbGFjZSAtIFN1aXRlIDMzMCwgQm9zdG9uLCBNQSAwMjExMS0xMzA3LAogKiBVU0EuCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9zY2hlZC5oPgojaW5jbHVkZSA8bGludXgvbW0uaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvdmlkZW90ZXh0Lmg+CiNpbmNsdWRlIDxsaW51eC92aWRlb2Rldi5oPgojaW5jbHVkZSAic2FhNTI0NmEuaCIKCk1PRFVMRV9BVVRIT1IoIk1pY2hhZWwgR2VuZyA8bGludXhATWljaGFlbEdlbmcuZGU+Iik7Ck1PRFVMRV9ERVNDUklQVElPTigiUGhpbGlwcyBTQUE1MjQ2QSwgU0FBNTI4MSBUZWxldGV4dCBkZWNvZGVyIGRyaXZlciIpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7CgpzdHJ1Y3Qgc2FhNTI0NmFfZGV2aWNlCnsKCXU4ICAgICBwZ2J1ZltOVU1fREFVU11bVlRYX1ZJUlRVQUxTSVpFXTsKCWludCAgICBpc19zZWFyY2hpbmdbTlVNX0RBVVNdOwoJc3RydWN0IGkyY19jbGllbnQgKmNsaWVudDsKCXN0cnVjdCBzZW1hcGhvcmUgbG9jazsKfTsKCnN0YXRpYyBzdHJ1Y3QgdmlkZW9fZGV2aWNlIHNhYV90ZW1wbGF0ZTsJLyogRGVjbGFyZWQgbmVhciBib3R0b20gKi8KCi8qIEFkZHJlc3NlcyB0byBzY2FuICovCnN0YXRpYyB1bnNpZ25lZCBzaG9ydCBub3JtYWxfaTJjW10JID0geyBJMkNfQUREUkVTUywgSTJDX0NMSUVOVF9FTkQgfTsKSTJDX0NMSUVOVF9JTlNNT0Q7CgpzdGF0aWMgc3RydWN0IGkyY19jbGllbnQgY2xpZW50X3RlbXBsYXRlOwoKc3RhdGljIGludCBzYWE1MjQ2YV9hdHRhY2goc3RydWN0IGkyY19hZGFwdGVyICphZGFwLCBpbnQgYWRkciwgaW50IGtpbmQpCnsKCWludCBwZ2J1ZjsKCWludCBlcnI7CglzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50OwoJc3RydWN0IHZpZGVvX2RldmljZSAqdmQ7CglzdHJ1Y3Qgc2FhNTI0NmFfZGV2aWNlICp0OwoKCXByaW50ayhLRVJOX0lORk8gInNhYTUyNDZhOiB0ZWxldGV4dCBjaGlwIGZvdW5kLlxuIik7CgljbGllbnQ9a21hbGxvYyhzaXplb2YoKmNsaWVudCksIEdGUF9LRVJORUwpOwoJaWYoY2xpZW50PT1OVUxMKQoJCXJldHVybiAtRU5PTUVNOwoJY2xpZW50X3RlbXBsYXRlLmFkYXB0ZXIgPSBhZGFwOwoJY2xpZW50X3RlbXBsYXRlLmFkZHIgPSBhZGRyOwoJbWVtY3B5KGNsaWVudCwgJmNsaWVudF90ZW1wbGF0ZSwgc2l6ZW9mKCpjbGllbnQpKTsKCXQgPSBremFsbG9jKHNpemVvZigqdCksIEdGUF9LRVJORUwpOwoJaWYodD09TlVMTCkKCXsKCQlrZnJlZShjbGllbnQpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoJc3RybGNweShjbGllbnQtPm5hbWUsIElGX05BTUUsIEkyQ19OQU1FX1NJWkUpOwoJaW5pdF9NVVRFWCgmdC0+bG9jayk7CgoJLyoKCSAqCU5vdyBjcmVhdGUgYSB2aWRlbzRsaW51eCBkZXZpY2UKCSAqLwoKCXZkID0gdmlkZW9fZGV2aWNlX2FsbG9jKCk7CglpZih2ZD09TlVMTCkKCXsKCQlrZnJlZSh0KTsKCQlrZnJlZShjbGllbnQpOwoJCXJldHVybiAtRU5PTUVNOwoJfQoJaTJjX3NldF9jbGllbnRkYXRhKGNsaWVudCwgdmQpOwoJbWVtY3B5KHZkLCAmc2FhX3RlbXBsYXRlLCBzaXplb2YoKnZkKSk7CgoJZm9yIChwZ2J1ZiA9IDA7IHBnYnVmIDwgTlVNX0RBVVM7IHBnYnVmKyspCgl7CgkJbWVtc2V0KHQtPnBnYnVmW3BnYnVmXSwgJyAnLCBzaXplb2YodC0+cGdidWZbMF0pKTsKCQl0LT5pc19zZWFyY2hpbmdbcGdidWZdID0gRkFMU0U7Cgl9Cgl2ZC0+cHJpdj10OwoKCgkvKgoJICoJUmVnaXN0ZXIgaXQKCSAqLwoKCWlmKChlcnI9dmlkZW9fcmVnaXN0ZXJfZGV2aWNlKHZkLCBWRkxfVFlQRV9WVFgsLTEpKTwwKQoJewoJCWtmcmVlKHQpOwoJCWtmcmVlKGNsaWVudCk7CgkJdmlkZW9fZGV2aWNlX3JlbGVhc2UodmQpOwoJCXJldHVybiBlcnI7Cgl9Cgl0LT5jbGllbnQgPSBjbGllbnQ7CglpMmNfYXR0YWNoX2NsaWVudChjbGllbnQpOwoJcmV0dXJuIDA7Cn0KCi8qCiAqCVdlIGRvIG1vc3Qgb2YgdGhlIGhhcmQgd29yayB3aGVuIHdlIGJlY29tZSBhIGRldmljZSBvbiB0aGUgaTJjLgogKi8Kc3RhdGljIGludCBzYWE1MjQ2YV9wcm9iZShzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApCnsKCWlmIChhZGFwLT5jbGFzcyAmIEkyQ19DTEFTU19UVl9BTkFMT0cpCgkJcmV0dXJuIGkyY19wcm9iZShhZGFwLCAmYWRkcl9kYXRhLCBzYWE1MjQ2YV9hdHRhY2gpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgc2FhNTI0NmFfZGV0YWNoKHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQpCnsKCXN0cnVjdCB2aWRlb19kZXZpY2UgKnZkID0gaTJjX2dldF9jbGllbnRkYXRhKGNsaWVudCk7CglpMmNfZGV0YWNoX2NsaWVudChjbGllbnQpOwoJdmlkZW9fdW5yZWdpc3Rlcl9kZXZpY2UodmQpOwoJa2ZyZWUodmQtPnByaXYpOwoJa2ZyZWUoY2xpZW50KTsKCXJldHVybiAwOwp9CgovKgogKglJMkMgaW50ZXJmYWNlcwogKi8KCnN0YXRpYyBzdHJ1Y3QgaTJjX2RyaXZlciBpMmNfZHJpdmVyX3ZpZGVvdGV4dCA9CnsKCS5kcml2ZXIgPSB7CgkJLm5hbWUgCT0gSUZfTkFNRSwJCS8qIG5hbWUgKi8KCX0sCgkuaWQgCQk9IEkyQ19EUklWRVJJRF9TQUE1MjQ5LCAvKiBpbiBpMmMuaCAqLwoJLmF0dGFjaF9hZGFwdGVyID0gc2FhNTI0NmFfcHJvYmUsCgkuZGV0YWNoX2NsaWVudCAgPSBzYWE1MjQ2YV9kZXRhY2gsCn07CgpzdGF0aWMgc3RydWN0IGkyY19jbGllbnQgY2xpZW50X3RlbXBsYXRlID0gewoJLmRyaXZlcgkJPSAmaTJjX2RyaXZlcl92aWRlb3RleHQsCgkubmFtZQkJPSAiKHVuc2V0KSIsCn07CgpzdGF0aWMgaW50IGkyY19zZW5kYnVmKHN0cnVjdCBzYWE1MjQ2YV9kZXZpY2UgKnQsIGludCByZWcsIGludCBjb3VudCwgdTggKmRhdGEpCnsKCWNoYXIgYnVmWzY0XTsKCglidWZbMF0gPSByZWc7CgltZW1jcHkoYnVmKzEsIGRhdGEsIGNvdW50KTsKCglpZihpMmNfbWFzdGVyX3NlbmQodC0+Y2xpZW50LCBidWYsIGNvdW50KzEpPT1jb3VudCsxKQoJCXJldHVybiAwOwoJcmV0dXJuIC0xOwp9CgpzdGF0aWMgaW50IGkyY19zZW5kZGF0YShzdHJ1Y3Qgc2FhNTI0NmFfZGV2aWNlICp0LCAuLi4pCnsKCXVuc2lnbmVkIGNoYXIgYnVmWzY0XTsKCWludCB2OwoJaW50IGN0PTA7Cgl2YV9saXN0IGFyZ3A7Cgl2YV9zdGFydChhcmdwLHQpOwoKCXdoaWxlKCh2PXZhX2FyZyhhcmdwLGludCkpIT0tMSkKCQlidWZbY3QrK109djsKCXJldHVybiBpMmNfc2VuZGJ1Zih0LCBidWZbMF0sIGN0LTEsIGJ1ZisxKTsKfQoKLyogR2V0IGNvdW50IG51bWJlciBvZiBieXRlcyBmcm9tIEmyQy1kZXZpY2UgYXQgYWRkcmVzcyBhZHIsIHN0b3JlIHRoZW0gaW4gYnVmLgogKiBTdGFydCAmIHN0b3AgaGFuZHNoYWtpbmcgaXMgZG9uZSBieSB0aGlzIHJvdXRpbmUsIGFjayB3aWxsIGJlIHNlbnQgYWZ0ZXIgdGhlCiAqIGxhc3QgYnl0ZSB0byBpbmhpYml0IGZ1cnRoZXIgc2VuZGluZyBvZiBkYXRhLiBJZiB1YWNjZXNzIGlzIFRSVUUsIGRhdGEgaXMKICogd3JpdHRlbiB0byB1c2VyLXNwYWNlIHdpdGggcHV0X3VzZXIuIFJldHVybnMgLTEgaWYgSbJDLWRldmljZSBkaWRuJ3Qgc2VuZAogKiBhY2tub3dsZWRnZSwgMCBvdGhlcndpc2UKICovCnN0YXRpYyBpbnQgaTJjX2dldGRhdGEoc3RydWN0IHNhYTUyNDZhX2RldmljZSAqdCwgaW50IGNvdW50LCB1OCAqYnVmKQp7CglpZihpMmNfbWFzdGVyX3JlY3YodC0+Y2xpZW50LCBidWYsIGNvdW50KSE9Y291bnQpCgkJcmV0dXJuIC0xOwoJcmV0dXJuIDA7Cn0KCi8qIFdoZW4gYSBwYWdlIGlzIGZvdW5kIHRoZW4gdGhlIG5vdCBGT1VORCBiaXQgaW4gb25lIG9mIHRoZSBzdGF0dXMgcmVnaXN0ZXJzCiAqIG9mIHRoZSBTQUE1MjY0QSBjaGlwIGlzIGNsZWFyZWQuIFVuZm9ydHVuYXRlbHkgdGhpcyBiaXQgaXMgbm90IHNldAogKiBhdXRvbWF0aWNhbGx5IHdoZW4gYSBuZXcgcGFnZSBpcyByZXF1ZXN0ZWQuIEluc3RlYWQgdGhpcyBmdW5jdGlvbiBtdXN0IGJlCiAqIGNhbGxlZCBhZnRlciBhIHBhZ2UgaGFzIGJlZW4gcmVxdWVzdGVkLgogKgogKiBSZXR1cm4gdmFsdWU6IDAgaWYgc3VjY2Vzc2Z1bAogKi8Kc3RhdGljIGludCBzYWE1MjQ2YV9jbGVhcl9mb3VuZF9iaXQoc3RydWN0IHNhYTUyNDZhX2RldmljZSAqdCwKCXVuc2lnbmVkIGNoYXIgZGF1X25vKQp7Cgl1bnNpZ25lZCBjaGFyIHJvd18yNV9jb2x1bW5fODsKCglpZiAoaTJjX3NlbmRkYXRhKHQsIFNBQTUyNDZBX1JFR0lTVEVSX1I4LAoKCQlkYXVfbm8gfAoJCVI4X0RPX05PVF9DTEVBUl9NRU1PUlksCgoJCVI5X0NVUlNFUl9ST1dfMjUsCgoJCVIxMF9DVVJTRVJfQ09MVU1OXzgsCgoJCUNPTU1BTkRfRU5EKSB8fAoJCWkyY19nZXRkYXRhKHQsIDEsICZyb3dfMjVfY29sdW1uXzgpKQoJewoJCXJldHVybiAtRUlPOwoJfQoJcm93XzI1X2NvbHVtbl84IHw9IFJPVzI1X0NPTFVNTjhfUEFHRV9OT1RfRk9VTkQ7CglpZiAoaTJjX3NlbmRkYXRhKHQsIFNBQTUyNDZBX1JFR0lTVEVSX1I4LAoKCQlkYXVfbm8gfAoJCVI4X0RPX05PVF9DTEVBUl9NRU1PUlksCgoJCVI5X0NVUlNFUl9ST1dfMjUsCgoJCVIxMF9DVVJTRVJfQ09MVU1OXzgsCgoJCXJvd18yNV9jb2x1bW5fOCwKCgkJQ09NTUFORF9FTkQpKQoJewoJCXJldHVybiAtRUlPOwoJfQoKCXJldHVybiAwOwp9CgovKiBSZXF1ZXN0cyBvbmUgdmlkZW90ZXh0IHBhZ2UgYXMgZGVzY3JpYmVkIGluIHJlcS4gVGhlIGZpZWxkcyBvZiByZXEgYXJlCiAqIGNoZWNrZWQgYW5kIGFuIGVycm9yIGlzIHJldHVybmVkIGlmIHNvbWV0aGluZyBpcyBpbnZhbGlkLgogKgogKiBSZXR1cm4gdmFsdWU6IDAgaWYgc3VjY2Vzc2Z1bAogKi8Kc3RhdGljIGludCBzYWE1MjQ2YV9yZXF1ZXN0X3BhZ2Uoc3RydWN0IHNhYTUyNDZhX2RldmljZSAqdCwKICAgIHZ0eF9wYWdlcmVxX3QgKnJlcSkKewoJaWYgKHJlcS0+cGFnZW1hc2sgPCAwIHx8IHJlcS0+cGFnZW1hc2sgPj0gUEdNQVNLX01BWCkKCQlyZXR1cm4gLUVJTlZBTDsKCWlmIChyZXEtPnBhZ2VtYXNrICYgUEdNQVNLX1BBR0UpCgkJaWYgKHJlcS0+cGFnZSA8IDAgfHwgcmVxLT5wYWdlID4gUEFHRV9NQVgpCgkJCXJldHVybiAtRUlOVkFMOwoJaWYgKHJlcS0+cGFnZW1hc2sgJiBQR01BU0tfSE9VUikKCQlpZiAocmVxLT5ob3VyIDwgMCB8fCByZXEtPmhvdXIgPiBIT1VSX01BWCkKCQkJcmV0dXJuIC1FSU5WQUw7CglpZiAocmVxLT5wYWdlbWFzayAmIFBHTUFTS19NSU5VVEUpCgkJaWYgKHJlcS0+bWludXRlIDwgMCB8fCByZXEtPm1pbnV0ZSA+IE1JTlVURV9NQVgpCgkJCXJldHVybiAtRUlOVkFMOwoJaWYgKHJlcS0+cGdidWYgPCAwIHx8IHJlcS0+cGdidWYgPj0gTlVNX0RBVVMpCgkJcmV0dXJuIC1FSU5WQUw7CgoJaWYgKGkyY19zZW5kZGF0YSh0LCBTQUE1MjQ2QV9SRUdJU1RFUl9SMiwKCgkJUjJfSU5fUjNfU0VMRUNUX1BBR0VfSFVORFJFRFMgfAoJCXJlcS0+cGdidWYgPDwgNCB8CgkJUjJfQkFOS18wIHwKCQlSMl9IQU1NSU5HX0NIRUNLX09GRiwKCgkJSFVORFJFRFNfT0ZfUEFHRShyZXEtPnBhZ2UpIHwKCQlSM19IT0xEX1BBR0UgfAoJCShyZXEtPnBhZ2VtYXNrICYgUEdfSFVORCA/CgkJCVIzX1BBR0VfSFVORFJFRFNfRE9fQ0FSRSA6CgkJCVIzX1BBR0VfSFVORFJFRFNfRE9fTk9UX0NBUkUpLAoKCQlURU5TX09GX1BBR0UocmVxLT5wYWdlKSB8CgkJKHJlcS0+cGFnZW1hc2sgJiBQR19URU4gPwoJCQlSM19QQUdFX1RFTlNfRE9fQ0FSRSA6CgkJCVIzX1BBR0VfVEVOU19ET19OT1RfQ0FSRSksCgoJCVVOSVRTX09GX1BBR0UocmVxLT5wYWdlKSB8CgkJKHJlcS0+cGFnZW1hc2sgJiBQR19VTklUID8KCQkJUjNfUEFHRV9VTklUU19ET19DQVJFIDoKCQkJUjNfUEFHRV9VTklUU19ET19OT1RfQ0FSRSksCgoJCVRFTlNfT0ZfSE9VUihyZXEtPmhvdXIpIHwKCQkocmVxLT5wYWdlbWFzayAmIEhSX1RFTiA/CgkJCVIzX0hPVVJTX1RFTlNfRE9fQ0FSRSA6CgkJCVIzX0hPVVJTX1RFTlNfRE9fTk9UX0NBUkUpLAoKCQlVTklUU19PRl9IT1VSKHJlcS0+aG91cikgfAoJCShyZXEtPnBhZ2VtYXNrICYgSFJfVU5JVCA/CgkJCVIzX0hPVVJTX1VOSVRTX0RPX0NBUkUgOgoJCQlSM19IT1VSU19VTklUU19ET19OT1RfQ0FSRSksCgoJCVRFTlNfT0ZfTUlOVVRFKHJlcS0+bWludXRlKSB8CgkJKHJlcS0+cGFnZW1hc2sgJiBNSU5fVEVOID8KCQkJUjNfTUlOVVRFU19URU5TX0RPX0NBUkUgOgoJCQlSM19NSU5VVEVTX1RFTlNfRE9fTk9UX0NBUkUpLAoKCQlVTklUU19PRl9NSU5VVEUocmVxLT5taW51dGUpIHwKCQkocmVxLT5wYWdlbWFzayAmIE1JTl9VTklUID8KCQkJUjNfTUlOVVRFU19VTklUU19ET19DQVJFIDoKCQkJUjNfTUlOVVRFU19VTklUU19ET19OT1RfQ0FSRSksCgoJCUNPTU1BTkRfRU5EKSB8fCBpMmNfc2VuZGRhdGEodCwgU0FBNTI0NkFfUkVHSVNURVJfUjIsCgoJCVIyX0lOX1IzX1NFTEVDVF9QQUdFX0hVTkRSRURTIHwKCQlyZXEtPnBnYnVmIDw8IDQgfAoJCVIyX0JBTktfMCB8CgkJUjJfSEFNTUlOR19DSEVDS19PRkYsCgoJCUhVTkRSRURTX09GX1BBR0UocmVxLT5wYWdlKSB8CgkJUjNfVVBEQVRFX1BBR0UgfAoJCShyZXEtPnBhZ2VtYXNrICYgUEdfSFVORCA/CgkJCVIzX1BBR0VfSFVORFJFRFNfRE9fQ0FSRSA6CgkJCVIzX1BBR0VfSFVORFJFRFNfRE9fTk9UX0NBUkUpLAoKCQlDT01NQU5EX0VORCkpCgl7CgkJcmV0dXJuIC1FSU87Cgl9CgoJdC0+aXNfc2VhcmNoaW5nW3JlcS0+cGdidWZdID0gVFJVRTsKCXJldHVybiAwOwp9CgovKiBUaGlzIHJvdXRpbmUgZGVjb2RlcyB0aGUgcGFnZSBudW1iZXIgZnJvbSB0aGUgaW5mb2JpdHMgY29udGFpbmVkIGluIGxpbmUgMjUuCiAqCiAqIFBhcmFtZXRlcnM6CiAqIGluZm9iaXRzOiBtdXN0IGJlIGJpdHMgMCB0byA5IG9mIGNvbHVtbiAyNQogKgogKiBSZXR1cm4gdmFsdWU6IHBhZ2UgbnVtYmVyIGNvZGVkIGluIGhleGFkZWNpbWFsLCBpLiBlLiBwYWdlIDEyMyBpcyBjb2RlZCAweDEyMwogKi8Kc3RhdGljIGlubGluZSBpbnQgc2FhNTI0NmFfZXh0cmFjdF9wYWdlbnVtX2Zyb21faW5mb2JpdHMoCiAgICB1bnNpZ25lZCBjaGFyIGluZm9iaXRzWzEwXSkKewoJaW50IHBhZ2VfaHVuZHJlZHMsIHBhZ2VfdGVucywgcGFnZV91bml0czsKCglwYWdlX3VuaXRzICAgID0gaW5mb2JpdHNbMF0gJiBST1cyNV9DT0xVTU4wX1BBR0VfVU5JVFM7CglwYWdlX3RlbnMgICAgID0gaW5mb2JpdHNbMV0gJiBST1cyNV9DT0xVTU4xX1BBR0VfVEVOUzsKCXBhZ2VfaHVuZHJlZHMgPSBpbmZvYml0c1s4XSAmIFJPVzI1X0NPTFVNTjhfUEFHRV9IVU5EUkVEUzsKCgkvKiBwYWdlIDB4Li4gbWVhbnMgcGFnZSA4Li4gKi8KCWlmIChwYWdlX2h1bmRyZWRzID09IDApCgkJcGFnZV9odW5kcmVkcyA9IDg7CgoJcmV0dXJuKChwYWdlX2h1bmRyZWRzIDw8IDgpIHwgKHBhZ2VfdGVucyA8PCA0KSB8IHBhZ2VfdW5pdHMpOwp9CgovKiBEZWNvZGVzIHRoZSBob3VyIGZyb20gdGhlIGluZm9iaXRzIGNvbnRhaW5lZCBpbiBsaW5lIDI1LgogKgogKiBQYXJhbWV0ZXJzOgogKiBpbmZvYml0czogbXVzdCBiZSBiaXRzIDAgdG8gOSBvZiBjb2x1bW4gMjUKICoKICogUmV0dXJuOiBob3VyIGNvZGVkIGluIGhleGFkZWNpbWFsLCBpLiBlLiAxMmggaXMgY29kZWQgMHgxMgogKi8Kc3RhdGljIGlubGluZSBpbnQgc2FhNTI0NmFfZXh0cmFjdF9ob3VyX2Zyb21faW5mb2JpdHMoCiAgICB1bnNpZ25lZCBjaGFyIGluZm9iaXRzWzEwXSkKewoJaW50IGhvdXJfdGVucywgaG91cl91bml0czsKCglob3VyX3VuaXRzID0gaW5mb2JpdHNbNF0gJiBST1cyNV9DT0xVTU40X0hPVVJfVU5JVFM7Cglob3VyX3RlbnMgID0gaW5mb2JpdHNbNV0gJiBST1cyNV9DT0xVTU41X0hPVVJfVEVOUzsKCglyZXR1cm4oKGhvdXJfdGVucyA8PCA0KSB8IGhvdXJfdW5pdHMpOwp9CgovKiBEZWNvZGVzIHRoZSBtaW51dGVzIGZyb20gdGhlIGluZm9iaXRzIGNvbnRhaW5lZCBpbiBsaW5lIDI1LgogKgogKiBQYXJhbWV0ZXJzOgogKiBpbmZvYml0czogbXVzdCBiZSBiaXRzIDAgdG8gOSBvZiBjb2x1bW4gMjUKICoKICogUmV0dXJuOiBtaW51dGVzIGNvZGVkIGluIGhleGFkZWNpbWFsLCBpLiBlLiAxMG1pbiBpcyBjb2RlZCAweDEwCiAqLwpzdGF0aWMgaW5saW5lIGludCBzYWE1MjQ2YV9leHRyYWN0X21pbnV0ZXNfZnJvbV9pbmZvYml0cygKICAgIHVuc2lnbmVkIGNoYXIgaW5mb2JpdHNbMTBdKQp7CglpbnQgbWludXRlc190ZW5zLCBtaW51dGVzX3VuaXRzOwoKCW1pbnV0ZXNfdW5pdHMgPSBpbmZvYml0c1syXSAmIFJPVzI1X0NPTFVNTjJfTUlOVVRFU19VTklUUzsKCW1pbnV0ZXNfdGVucyAgPSBpbmZvYml0c1szXSAmIFJPVzI1X0NPTFVNTjNfTUlOVVRFU19URU5TOwoKCXJldHVybigobWludXRlc190ZW5zIDw8IDQpIHwgbWludXRlc191bml0cyk7Cn0KCi8qIFJlYWRzIHRoZSBzdGF0dXMgYml0cyBjb250YWluZWQgaW4gdGhlIGZpcnN0IDEwIGNvbHVtbnMgb2YgdGhlIGZpcnN0IGxpbmUKICogYW5kIGV4dHJhY3RzIHRoZSBpbmZvcm1hdGlvbiBpbnRvIGluZm8uCiAqCiAqIFJldHVybiB2YWx1ZTogMCBpZiBzdWNjZXNzZnVsCiAqLwpzdGF0aWMgaW5saW5lIGludCBzYWE1MjQ2YV9nZXRfc3RhdHVzKHN0cnVjdCBzYWE1MjQ2YV9kZXZpY2UgKnQsCiAgICB2dHhfcGFnZWluZm9fdCAqaW5mbywgdW5zaWduZWQgY2hhciBkYXVfbm8pCnsKCXVuc2lnbmVkIGNoYXIgaW5mb2JpdHNbMTBdOwoJaW50IGNvbHVtbjsKCglpZiAoZGF1X25vID49IE5VTV9EQVVTKQoJCXJldHVybiAtRUlOVkFMOwoKCWlmIChpMmNfc2VuZGRhdGEodCwgU0FBNTI0NkFfUkVHSVNURVJfUjgsCgoJCWRhdV9ubyB8CgkJUjhfRE9fTk9UX0NMRUFSX01FTU9SWSwKCgkJUjlfQ1VSU0VSX1JPV18yNSwKCgkJUjEwX0NVUlNFUl9DT0xVTU5fMCwKCgkJQ09NTUFORF9FTkQpIHx8CgkJaTJjX2dldGRhdGEodCwgMTAsIGluZm9iaXRzKSkKCXsKCQlyZXR1cm4gLUVJTzsKCX0KCglpbmZvLT5wYWdlbnVtID0gc2FhNTI0NmFfZXh0cmFjdF9wYWdlbnVtX2Zyb21faW5mb2JpdHMoaW5mb2JpdHMpOwoJaW5mby0+aG91ciAgICA9IHNhYTUyNDZhX2V4dHJhY3RfaG91cl9mcm9tX2luZm9iaXRzKGluZm9iaXRzKTsKCWluZm8tPm1pbnV0ZSAgPSBzYWE1MjQ2YV9leHRyYWN0X21pbnV0ZXNfZnJvbV9pbmZvYml0cyhpbmZvYml0cyk7CglpbmZvLT5jaGFyc2V0ID0gKChpbmZvYml0c1s3XSAmIFJPVzI1X0NPTFVNTjdfQ0hBUkFDVEVSX1NFVCkgPj4gMSk7CglpbmZvLT5kZWxldGUgPSAhIShpbmZvYml0c1szXSAmIFJPVzI1X0NPTFVNTjNfREVMRVRFX1BBR0UpOwoJaW5mby0+aGVhZGxpbmUgPSAhIShpbmZvYml0c1s1XSAmIFJPVzI1X0NPTFVNTjVfSU5TRVJUX0hFQURMSU5FKTsKCWluZm8tPnN1YnRpdGxlID0gISEoaW5mb2JpdHNbNV0gJiBST1cyNV9DT0xVTU41X0lOU0VSVF9TVUJUSVRMRSk7CglpbmZvLT5zdXBwX2hlYWRlciA9ICEhKGluZm9iaXRzWzZdICYgUk9XMjVfQ09MVU1ONl9TVVBQUkVTU19IRUFERVIpOwoJaW5mby0+dXBkYXRlID0gISEoaW5mb2JpdHNbNl0gJiBST1cyNV9DT0xVTU42X1VQREFURV9QQUdFKTsKCWluZm8tPmludGVyX3NlcSA9ICEhKGluZm9iaXRzWzZdICYgUk9XMjVfQ09MVU1ONl9JTlRFUlJVUFRFRF9TRVFVRU5DRSk7CglpbmZvLT5kaXNfZGlzcCA9ICEhKGluZm9iaXRzWzZdICYgUk9XMjVfQ09MVU1ONl9TVVBQUkVTU19ESVNQTEFZKTsKCWluZm8tPnNlcmlhbCA9ICEhKGluZm9iaXRzWzddICYgUk9XMjVfQ09MVU1ON19TRVJJQUxfTU9ERSk7CglpbmZvLT5ub3Rmb3VuZCA9ICEhKGluZm9iaXRzWzhdICYgUk9XMjVfQ09MVU1OOF9QQUdFX05PVF9GT1VORCk7CglpbmZvLT5wYmxmID0gISEoaW5mb2JpdHNbOV0gJiBST1cyNV9DT0xVTU45X1BBR0VfQkVJTkdfTE9PS0VEX0ZPUik7CglpbmZvLT5oYW1taW5nID0gMDsKCWZvciAoY29sdW1uID0gMDsgY29sdW1uIDw9IDc7IGNvbHVtbisrKSB7CgkJaWYgKGluZm9iaXRzW2NvbHVtbl0gJiBST1cyNV9DT0xVTU4wX1RPXzdfSEFNTUlOR19FUlJPUikgewoJCQlpbmZvLT5oYW1taW5nID0gMTsKCQkJYnJlYWs7CgkJfQoJfQoJaWYgKCFpbmZvLT5oYW1taW5nICYmICFpbmZvLT5ub3Rmb3VuZCkKCQl0LT5pc19zZWFyY2hpbmdbZGF1X25vXSA9IEZBTFNFOwoJcmV0dXJuIDA7Cn0KCi8qIFJlYWRzIDEgdmlkZW90ZXh0IHBhZ2UgYnVmZmVyIG9mIHRoZSBTQUE1MjQ2QS4KICoKICogcmVxIGlzIHVzZWQgYm90aCBhcyBpbnB1dCBhbmQgYXMgb3V0cHV0LiBJdCBjb250YWlucyBpbmZvcm1hdGlvbiB3aGljaCBwYXJ0CiAqIG11c3QgYmUgcmVhZC4gVGhlIHZpZGVvdGV4dCBwYWdlIGlzIGNvcGllZCBpbnRvIHJlcS0+YnVmZmVyLgogKgogKiBSZXR1cm4gdmFsdWU6IDAgaWYgc3VjY2Vzc2Z1bAogKi8Kc3RhdGljIGlubGluZSBpbnQgc2FhNTI0NmFfZ2V0X3BhZ2Uoc3RydWN0IHNhYTUyNDZhX2RldmljZSAqdCwKCXZ0eF9wYWdlcmVxX3QgKnJlcSkKewoJaW50IHN0YXJ0LCBlbmQsIHNpemU7CgljaGFyICpidWY7CglpbnQgZXJyOwoKCWlmIChyZXEtPnBnYnVmIDwgMCB8fCByZXEtPnBnYnVmID49IE5VTV9EQVVTIHx8CgkgICAgcmVxLT5zdGFydCA8IDAgfHwgcmVxLT5zdGFydCA+IHJlcS0+ZW5kIHx8IHJlcS0+ZW5kID49IFZUWF9QQUdFU0laRSkKCQlyZXR1cm4gLUVJTlZBTDsKCglidWYgPSBrbWFsbG9jKFZUWF9QQUdFU0laRSwgR0ZQX0tFUk5FTCk7CglpZiAoIWJ1ZikKCQlyZXR1cm4gLUVOT01FTTsKCgkvKiBSZWFkICJub3JtYWwiIHBhcnQgb2YgcGFnZSAqLwoJZXJyID0gLUVJTzsKCgllbmQgPSBtaW4ocmVxLT5lbmQsIFZUWF9QQUdFU0laRSAtIDEpOwoJaWYgKGkyY19zZW5kZGF0YSh0LCBTQUE1MjQ2QV9SRUdJU1RFUl9SOCwKCQkJcmVxLT5wZ2J1ZiB8IFI4X0RPX05PVF9DTEVBUl9NRU1PUlksCgkJCVJPVyhyZXEtPnN0YXJ0KSwgQ09MVU1OKHJlcS0+c3RhcnQpLCBDT01NQU5EX0VORCkpCgkJZ290byBvdXQ7CglpZiAoaTJjX2dldGRhdGEodCwgZW5kIC0gcmVxLT5zdGFydCArIDEsIGJ1ZikpCgkJZ290byBvdXQ7CgllcnIgPSAtRUZBVUxUOwoJaWYgKGNvcHlfdG9fdXNlcihyZXEtPmJ1ZmZlciwgYnVmLCBlbmQgLSByZXEtPnN0YXJ0ICsgMSkpCgkJZ290byBvdXQ7CgoJLyogQWx3YXlzIGdldCB0aGUgdGltZSBmcm9tIGJ1ZmZlciA0LCBzaW5jZSB0aGlzIHN0dXBpZCBTQUE1MjQ2QSBvbmx5CgkgKiB1cGRhdGVzIHRoZSBjdXJyZW50bHkgZGlzcGxheWVkIGJ1ZmZlci4uLgoJICovCglpZiAoUkVRX0NPTlRBSU5TX1RJTUUocmVxKSkgewoJCXN0YXJ0ID0gbWF4KHJlcS0+c3RhcnQsIFBPU19USU1FX1NUQVJUKTsKCQllbmQgICA9IG1pbihyZXEtPmVuZCwgICBQT1NfVElNRV9FTkQpOwoJCXNpemUgPSBlbmQgLSBzdGFydCArIDE7CgkJZXJyID0gLUVJTlZBTDsKCQlpZiAoc2l6ZSA8IDApCgkJCWdvdG8gb3V0OwoJCWVyciA9IC1FSU87CgkJaWYgKGkyY19zZW5kZGF0YSh0LCBTQUE1MjQ2QV9SRUdJU1RFUl9SOCwKCQkJCVI4X0FDVElWRV9DSEFQVEVSXzQgfCBSOF9ET19OT1RfQ0xFQVJfTUVNT1JZLAoJCQkJUjlfQ1VSU0VSX1JPV18wLCBzdGFydCwgQ09NTUFORF9FTkQpKQoJCQlnb3RvIG91dDsKCQlpZiAoaTJjX2dldGRhdGEodCwgc2l6ZSwgYnVmKSkKCQkJZ290byBvdXQ7CgkJZXJyID0gLUVGQVVMVDsKCQlpZiAoY29weV90b191c2VyKHJlcS0+YnVmZmVyICsgc3RhcnQgLSByZXEtPnN0YXJ0LCBidWYsIHNpemUpKQoJCQlnb3RvIG91dDsKCX0KCS8qIEluc2VydCB0aGUgaGVhZGVyIGZyb20gYnVmZmVyIDQgb25seSwgaWYgYWNxdWlzaXRpb24gY2lyY3VpdCBpcyBzdGlsbCBzZWFyY2hpbmcgZm9yIGEgcGFnZSAqLwoJaWYgKFJFUV9DT05UQUlOU19IRUFERVIocmVxKSAmJiB0LT5pc19zZWFyY2hpbmdbcmVxLT5wZ2J1Zl0pIHsKCQlzdGFydCA9IG1heChyZXEtPnN0YXJ0LCBQT1NfSEVBREVSX1NUQVJUKTsKCQllbmQgICA9IG1pbihyZXEtPmVuZCwgICBQT1NfSEVBREVSX0VORCk7CgkJc2l6ZSA9IGVuZCAtIHN0YXJ0ICsgMTsKCQllcnIgPSAtRUlOVkFMOwoJCWlmIChzaXplIDwgMCkKCQkJZ290byBvdXQ7CgkJZXJyID0gLUVJTzsKCQlpZiAoaTJjX3NlbmRkYXRhKHQsIFNBQTUyNDZBX1JFR0lTVEVSX1I4LAoJCQkJUjhfQUNUSVZFX0NIQVBURVJfNCB8IFI4X0RPX05PVF9DTEVBUl9NRU1PUlksCgkJCQlSOV9DVVJTRVJfUk9XXzAsIHN0YXJ0LCBDT01NQU5EX0VORCkpCgkJCWdvdG8gb3V0OwoJCWlmIChpMmNfZ2V0ZGF0YSh0LCBlbmQgLSBzdGFydCArIDEsIGJ1ZikpCgkJCWdvdG8gb3V0OwoJCWVyciA9IC1FRkFVTFQ7CgkJaWYgKGNvcHlfdG9fdXNlcihyZXEtPmJ1ZmZlciArIHN0YXJ0IC0gcmVxLT5zdGFydCwgYnVmLCBzaXplKSkKCQkJZ290byBvdXQ7Cgl9CgllcnIgPSAwOwpvdXQ6CglrZnJlZShidWYpOwoJcmV0dXJuIGVycjsKfQoKLyogU3RvcHMgdGhlIGFjcXVpc2l0aW9uIGNpcmN1aXQgZ2l2ZW4gaW4gZGF1X25vLiBUaGUgcGFnZSBidWZmZXIgYXNzb2NpYXRlZAogKiB3aXRoIHRoaXMgYWNxdWlzaXRpb24gY2lyY3VpdCB3aWxsIG5vIG1vcmUgYmUgdXBkYXRlZC4gVGhlIG90aGVyIGRhdXMgYXJlCiAqIG5vdCBhZmZlY3RlZC4KICoKICogUmV0dXJuIHZhbHVlOiAwIGlmIHN1Y2Nlc3NmdWwKICovCnN0YXRpYyBpbmxpbmUgaW50IHNhYTUyNDZhX3N0b3BfZGF1KHN0cnVjdCBzYWE1MjQ2YV9kZXZpY2UgKnQsCiAgICB1bnNpZ25lZCBjaGFyIGRhdV9ubykKewoJaWYgKGRhdV9ubyA+PSBOVU1fREFVUykKCQlyZXR1cm4gLUVJTlZBTDsKCWlmIChpMmNfc2VuZGRhdGEodCwgU0FBNTI0NkFfUkVHSVNURVJfUjIsCgoJCVIyX0lOX1IzX1NFTEVDVF9QQUdFX0hVTkRSRURTIHwKCQlkYXVfbm8gPDwgNCB8CgkJUjJfQkFOS18wIHwKCQlSMl9IQU1NSU5HX0NIRUNLX09GRiwKCgkJUjNfUEFHRV9IVU5EUkVEU18wIHwKCQlSM19IT0xEX1BBR0UgfAoJCVIzX1BBR0VfSFVORFJFRFNfRE9fTk9UX0NBUkUsCgoJCUNPTU1BTkRfRU5EKSkKCXsKCQlyZXR1cm4gLUVJTzsKCX0KCXQtPmlzX3NlYXJjaGluZ1tkYXVfbm9dID0gRkFMU0U7CglyZXR1cm4gMDsKfQoKLyogIEhhbmRsZXMgaW9jdGxzIGRlZmluZWQgaW4gdmlkZW90ZXh0LmgKICoKICogIFJldHVybnMgMCBpZiBzdWNjZXNzZnVsCiAqLwpzdGF0aWMgaW50IGRvX3NhYTUyNDZhX2lvY3RsKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlLAoJCQkgICAgdW5zaWduZWQgaW50IGNtZCwgdm9pZCAqYXJnKQp7CglzdHJ1Y3QgdmlkZW9fZGV2aWNlICp2ZCA9IHZpZGVvX2RldmRhdGEoZmlsZSk7CglzdHJ1Y3Qgc2FhNTI0NmFfZGV2aWNlICp0PXZkLT5wcml2OwoJc3dpdGNoKGNtZCkKCXsKCQljYXNlIFZUWElPQ0dFVElORk86CgkJewoJCQl2dHhfaW5mb190ICppbmZvID0gYXJnOwoKCQkJaW5mby0+dmVyc2lvbl9tYWpvciA9IE1BSk9SX1ZFUlNJT047CgkJCWluZm8tPnZlcnNpb25fbWlub3IgPSBNSU5PUl9WRVJTSU9OOwoJCQlpbmZvLT5udW1wYWdlcyA9IE5VTV9EQVVTOwoJCQlyZXR1cm4gMDsKCQl9CgoJCWNhc2UgVlRYSU9DQ0xSUEFHRToKCQl7CgkJCXZ0eF9wYWdlcmVxX3QgKnJlcSA9IGFyZzsKCgkJCWlmIChyZXEtPnBnYnVmIDwgMCB8fCByZXEtPnBnYnVmID49IE5VTV9EQVVTKQoJCQkJcmV0dXJuIC1FSU5WQUw7CgkJCW1lbXNldCh0LT5wZ2J1ZltyZXEtPnBnYnVmXSwgJyAnLCBzaXplb2YodC0+cGdidWZbMF0pKTsKCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ0NMUkZPVU5EOgoJCXsKCQkJdnR4X3BhZ2VyZXFfdCAqcmVxID0gYXJnOwoKCQkJaWYgKHJlcS0+cGdidWYgPCAwIHx8IHJlcS0+cGdidWYgPj0gTlVNX0RBVVMpCgkJCQlyZXR1cm4gLUVJTlZBTDsKCQkJcmV0dXJuKHNhYTUyNDZhX2NsZWFyX2ZvdW5kX2JpdCh0LCByZXEtPnBnYnVmKSk7CgkJfQoKCQljYXNlIFZUWElPQ1BBR0VSRVE6CgkJewoJCQl2dHhfcGFnZXJlcV90ICpyZXEgPSBhcmc7CgoJCQlyZXR1cm4oc2FhNTI0NmFfcmVxdWVzdF9wYWdlKHQsIHJlcSkpOwoJCX0KCgkJY2FzZSBWVFhJT0NHRVRTVEFUOgoJCXsKCQkJdnR4X3BhZ2VyZXFfdCAqcmVxID0gYXJnOwoJCQl2dHhfcGFnZWluZm9fdCBpbmZvOwoJCQlpbnQgcnZhbDsKCgkJCWlmICgocnZhbCA9IHNhYTUyNDZhX2dldF9zdGF0dXModCwgJmluZm8sIHJlcS0+cGdidWYpKSkKCQkJCXJldHVybiBydmFsOwoJCQlpZihjb3B5X3RvX3VzZXIocmVxLT5idWZmZXIsICZpbmZvLAoJCQkJc2l6ZW9mKHZ0eF9wYWdlaW5mb190KSkpCgkJCQlyZXR1cm4gLUVGQVVMVDsKCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ0dFVFBBR0U6CgkJewoJCQl2dHhfcGFnZXJlcV90ICpyZXEgPSBhcmc7CgoJCQlyZXR1cm4oc2FhNTI0NmFfZ2V0X3BhZ2UodCwgcmVxKSk7CgkJfQoKCQljYXNlIFZUWElPQ1NUT1BEQVU6CgkJewoJCQl2dHhfcGFnZXJlcV90ICpyZXEgPSBhcmc7CgoJCQlyZXR1cm4oc2FhNTI0NmFfc3RvcF9kYXUodCwgcmVxLT5wZ2J1ZikpOwoJCX0KCgkJY2FzZSBWVFhJT0NQVVRQQUdFOgoJCWNhc2UgVlRYSU9DU0VURElTUDoKCQljYXNlIFZUWElPQ1BVVFNUQVQ6CgkJCXJldHVybiAwOwoKCQljYXNlIFZUWElPQ0NMUkNBQ0hFOgoJCXsKCQkJcmV0dXJuIDA7CgkJfQoKCQljYXNlIFZUWElPQ1NFVFZJUlQ6CgkJewoJCQkvKiBJIGRvIG5vdCBrbm93IHdoYXQgInZpcnR1YWwgbW9kZSIgbWVhbnMgKi8KCQkJcmV0dXJuIDA7CgkJfQoJfQoJcmV0dXJuIC1FSU5WQUw7Cn0KCi8qCiAqIFRyYW5zbGF0ZXMgb2xkIHZ0eCBJT0NUTHMgdG8gbmV3IG9uZXMKICoKICogVGhpcyBrZWVwcyBuZXcga2VybmVsIHZlcnNpb25zIGNvbXBhdGlibGUgd2l0aCBvbGQgdXNlcnNwYWNlIHByb2dyYW1zLgogKi8Kc3RhdGljIGlubGluZSB1bnNpZ25lZCBpbnQgdnR4X2ZpeF9jb21tYW5kKHVuc2lnbmVkIGludCBjbWQpCnsKCXN3aXRjaCAoY21kKSB7CgljYXNlIFZUWElPQ0dFVElORk9fT0xEOgoJCWNtZCA9IFZUWElPQ0dFVElORk87CgkJYnJlYWs7CgljYXNlIFZUWElPQ0NMUlBBR0VfT0xEOgoJCWNtZCA9IFZUWElPQ0NMUlBBR0U7CgkJYnJlYWs7CgljYXNlIFZUWElPQ0NMUkZPVU5EX09MRDoKCQljbWQgPSBWVFhJT0NDTFJGT1VORDsKCQlicmVhazsKCWNhc2UgVlRYSU9DUEFHRVJFUV9PTEQ6CgkJY21kID0gVlRYSU9DUEFHRVJFUTsKCQlicmVhazsKCWNhc2UgVlRYSU9DR0VUU1RBVF9PTEQ6CgkJY21kID0gVlRYSU9DR0VUU1RBVDsKCQlicmVhazsKCWNhc2UgVlRYSU9DR0VUUEFHRV9PTEQ6CgkJY21kID0gVlRYSU9DR0VUUEFHRTsKCQlicmVhazsKCWNhc2UgVlRYSU9DU1RPUERBVV9PTEQ6CgkJY21kID0gVlRYSU9DU1RPUERBVTsKCQlicmVhazsKCWNhc2UgVlRYSU9DUFVUUEFHRV9PTEQ6CgkJY21kID0gVlRYSU9DUFVUUEFHRTsKCQlicmVhazsKCWNhc2UgVlRYSU9DU0VURElTUF9PTEQ6CgkJY21kID0gVlRYSU9DU0VURElTUDsKCQlicmVhazsKCWNhc2UgVlRYSU9DUFVUU1RBVF9PTEQ6CgkJY21kID0gVlRYSU9DUFVUU1RBVDsKCQlicmVhazsKCWNhc2UgVlRYSU9DQ0xSQ0FDSEVfT0xEOgoJCWNtZCA9IFZUWElPQ0NMUkNBQ0hFOwoJCWJyZWFrOwoJY2FzZSBWVFhJT0NTRVRWSVJUX09MRDoKCQljbWQgPSBWVFhJT0NTRVRWSVJUOwoJCWJyZWFrOwoJfQoJcmV0dXJuIGNtZDsKfQoKLyoKICoJSGFuZGxlIHRoZSBsb2NraW5nCiAqLwpzdGF0aWMgaW50IHNhYTUyNDZhX2lvY3RsKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlLAoJCQkgdW5zaWduZWQgaW50IGNtZCwgdW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCB2aWRlb19kZXZpY2UgKnZkID0gdmlkZW9fZGV2ZGF0YShmaWxlKTsKCXN0cnVjdCBzYWE1MjQ2YV9kZXZpY2UgKnQgPSB2ZC0+cHJpdjsKCWludCBlcnI7CgoJY21kID0gdnR4X2ZpeF9jb21tYW5kKGNtZCk7Cglkb3duKCZ0LT5sb2NrKTsKCWVyciA9IHZpZGVvX3VzZXJjb3B5KGlub2RlLCBmaWxlLCBjbWQsIGFyZywgZG9fc2FhNTI0NmFfaW9jdGwpOwoJdXAoJnQtPmxvY2spOwoJcmV0dXJuIGVycjsKfQoKc3RhdGljIGludCBzYWE1MjQ2YV9vcGVuKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlKQp7CglzdHJ1Y3QgdmlkZW9fZGV2aWNlICp2ZCA9IHZpZGVvX2RldmRhdGEoZmlsZSk7CglzdHJ1Y3Qgc2FhNTI0NmFfZGV2aWNlICp0ID0gdmQtPnByaXY7CglpbnQgZXJyOwoKCWVyciA9IHZpZGVvX2V4Y2x1c2l2ZV9vcGVuKGlub2RlLGZpbGUpOwoJaWYgKGVyciA8IDApCgkJcmV0dXJuIGVycjsKCglpZiAodC0+Y2xpZW50PT1OVUxMKSB7CgkJZXJyID0gLUVOT0RFVjsKCQlnb3RvIGZhaWw7Cgl9CgoJaWYgKGkyY19zZW5kZGF0YSh0LCBTQUE1MjQ2QV9SRUdJU1RFUl9SMCwKCgkJUjBfU0VMRUNUX1IxMSB8CgkJUjBfUExMX1RJTUVfQ09OU1RBTlRfTE9ORyB8CgkJUjBfRU5BQkxFX25PRERfRVZFTl9PVVRQVVQgfAoJCVIwX0VOQUJMRV9IRFJfUE9MTCB8CgkJUjBfRE9fTk9UX0ZPUkNFX25PRERfRVZFTl9MT1dfSUZfUElDVFVSRV9ESVNQTEFZRUQgfAoJCVIwX05PX0ZSRUVfUlVOX1BMTCB8CgkJUjBfTk9fQVVUT01BVElDX0ZBU1RFWFRfUFJPTVBULAoKCQlSMV9OT05fSU5URVJMQUNFRF8zMTJfMzEyX0xJTkVTIHwKCQlSMV9ERVcgfAoJCVIxX0VYVEVOREVEX1BBQ0tFVF9ESVNBQkxFIHwKCQlSMV9EQVVTX0FMTF9PTiB8CgkJUjFfOF9CSVRTX05PX1BBUklUWSB8CgkJUjFfVkNTX1RPX1NDUywKCgkJQ09NTUFORF9FTkQpIHx8CgkJaTJjX3NlbmRkYXRhKHQsIFNBQTUyNDZBX1JFR0lTVEVSX1I0LAoKCQkvKiBXZSBkbyBub3QgY2FyZSBtdWNoIGZvciB0aGUgVFYgZGlzcGxheSBidXQgbmV2ZXJ0aGVsZXNzIHdlCgkJICogbmVlZCB0aGUgY3VycmVudGx5IGRpc3BsYXllZCBwYWdlIGxhdGVyIGJlY2F1c2Ugb25seSBvbiB0aGF0CgkJICogcGFnZSB0aGUgdGltZSBpcyB1cGRhdGVkLiAqLwoJCVI0X0RJU1BMQVlfUEFHRV80LAoKCQlDT01NQU5EX0VORCkpCgl7CgkJZXJyID0gLUVJTzsKCQlnb3RvIGZhaWw7Cgl9CgoJcmV0dXJuIDA7CgpmYWlsOgoJdmlkZW9fZXhjbHVzaXZlX3JlbGVhc2UoaW5vZGUsZmlsZSk7CglyZXR1cm4gZXJyOwp9CgpzdGF0aWMgaW50IHNhYTUyNDZhX3JlbGVhc2Uoc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUpCnsKCXN0cnVjdCB2aWRlb19kZXZpY2UgKnZkID0gdmlkZW9fZGV2ZGF0YShmaWxlKTsKCXN0cnVjdCBzYWE1MjQ2YV9kZXZpY2UgKnQgPSB2ZC0+cHJpdjsKCgkvKiBTdG9wIGFsbCBhY3F1aXNpdGlvbiBjaXJjdWl0cy4gKi8KCWkyY19zZW5kZGF0YSh0LCBTQUE1MjQ2QV9SRUdJU1RFUl9SMSwKCgkJUjFfSU5URVJMQUNFRF8zMTJfQU5EX0hBTEZfMzEyX0FORF9IQUxGX0xJTkVTIHwKCQlSMV9ERVcgfAoJCVIxX0VYVEVOREVEX1BBQ0tFVF9ESVNBQkxFIHwKCQlSMV9EQVVTX0FMTF9PRkYgfAoJCVIxXzhfQklUU19OT19QQVJJVFkgfAoJCVIxX1ZDU19UT19TQ1MsCgoJCUNPTU1BTkRfRU5EKTsKCXZpZGVvX2V4Y2x1c2l2ZV9yZWxlYXNlKGlub2RlLGZpbGUpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgX19pbml0IGluaXRfc2FhXzUyNDZhICh2b2lkKQp7CglwcmludGsoS0VSTl9JTkZPCgkJIlNBQTUyNDZBIChvciBjb21wYXRpYmxlKSBUZWxldGV4dCBkZWNvZGVyIGRyaXZlciB2ZXJzaW9uICVkLiVkXG4iLAoJCU1BSk9SX1ZFUlNJT04sIE1JTk9SX1ZFUlNJT04pOwoJcmV0dXJuIGkyY19hZGRfZHJpdmVyKCZpMmNfZHJpdmVyX3ZpZGVvdGV4dCk7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBjbGVhbnVwX3NhYV81MjQ2YSAodm9pZCkKewoJaTJjX2RlbF9kcml2ZXIoJmkyY19kcml2ZXJfdmlkZW90ZXh0KTsKfQoKbW9kdWxlX2luaXQoaW5pdF9zYWFfNTI0NmEpOwptb2R1bGVfZXhpdChjbGVhbnVwX3NhYV81MjQ2YSk7CgpzdGF0aWMgc3RydWN0IGZpbGVfb3BlcmF0aW9ucyBzYWFfZm9wcyA9IHsKCS5vd25lcgkgPSBUSElTX01PRFVMRSwKCS5vcGVuCSA9IHNhYTUyNDZhX29wZW4sCgkucmVsZWFzZSA9IHNhYTUyNDZhX3JlbGVhc2UsCgkuaW9jdGwJID0gc2FhNTI0NmFfaW9jdGwsCgkubGxzZWVrCSA9IG5vX2xsc2VlaywKfTsKCnN0YXRpYyBzdHJ1Y3QgdmlkZW9fZGV2aWNlIHNhYV90ZW1wbGF0ZSA9CnsKCS5vd25lcgkgID0gVEhJU19NT0RVTEUsCgkubmFtZQkgID0gSUZfTkFNRSwKCS50eXBlCSAgPSBWSURfVFlQRV9URUxFVEVYVCwKCS5oYXJkd2FyZSA9IFZJRF9IQVJEV0FSRV9TQUE1MjQ5LAoJLmZvcHMJICA9ICZzYWFfZm9wcywKCS5yZWxlYXNlICA9IHZpZGVvX2RldmljZV9yZWxlYXNlLAoJLm1pbm9yICAgID0gLTEsCn07Cg==