LyoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnkKICogdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogQ29weXJpZ2h0IChDKSBKb25hdGhhbiBOYXlsb3IgRzRLTFggKGc0a2x4QGc0a2x4LmRlbW9uLmNvLnVrKQogKiBDb3B5cmlnaHQgKEMpIEpvZXJnIFJldXRlciBETDFCS0UgKGpyZXV0ZXJAeWFpbmEuZGUpCiAqLwojaW5jbHVkZSA8bGludXgvZXJybm8uaD4KI2luY2x1ZGUgPGxpbnV4L3R5cGVzLmg+CiNpbmNsdWRlIDxsaW51eC9zb2NrZXQuaD4KI2luY2x1ZGUgPGxpbnV4L2luLmg+CiNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KI2luY2x1ZGUgPGxpbnV4L3NjaGVkLmg+CiNpbmNsdWRlIDxsaW51eC90aW1lci5oPgojaW5jbHVkZSA8bGludXgvc3RyaW5nLmg+CiNpbmNsdWRlIDxsaW51eC9zb2NraW9zLmg+CiNpbmNsdWRlIDxsaW51eC9zcGlubG9jay5oPgojaW5jbHVkZSA8bGludXgvbmV0Lmg+CiNpbmNsdWRlIDxuZXQvYXgyNS5oPgojaW5jbHVkZSA8bGludXgvaW5ldC5oPgojaW5jbHVkZSA8bGludXgvbmV0ZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9za2J1ZmYuaD4KI2luY2x1ZGUgPG5ldC9zb2NrLmg+CiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgojaW5jbHVkZSA8YXNtL3N5c3RlbS5oPgojaW5jbHVkZSA8bGludXgvZmNudGwuaD4KI2luY2x1ZGUgPGxpbnV4L21tLmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KCnZvaWQgYXgyNV9kc19ucl9lcnJvcl9yZWNvdmVyeShheDI1X2NiICpheDI1KQp7CglheDI1X2RzX2VzdGFibGlzaF9kYXRhX2xpbmsoYXgyNSk7Cn0KCi8qCiAqCWRsMWJrZSA5NjAxMTQ6IHRyYW5zbWl0IEkgZnJhbWVzIG9uIERBTUEgcG9sbAogKi8Kdm9pZCBheDI1X2RzX2VucXVpcnlfcmVzcG9uc2UoYXgyNV9jYiAqYXgyNSkKewoJYXgyNV9jYiAqYXgyNW87CglzdHJ1Y3QgaGxpc3Rfbm9kZSAqbm9kZTsKCgkvKiBQbGVhc2Ugbm90ZSB0aGF0IG5laXRoZXIgREs0RUe0cyBub3IgREcyRkVGtHMKCSAqIERBTUEgc3BlYyBtZW50aW9uIHRoZSBmb2xsb3dpbmcgYmVoYXZpb3VyIGFzIHNlZW4KCSAqIHdpdGggVGhlRmlybXdhcmU6CgkgKgoJICogCURCMEFDSC0+REwxQktFIDxSUiBDIFAgUjA+IFtEQU1BXQoJICoJREwxQktFLT5EQjBBQ0ggPEkgTlI9MCBOUz0wPgoJICoJREwxQktFLTctPkRCMFBSQS02IERCMEFDSCA8SSBDIFMzIFI1PgoJICoJREwxQktFLT5EQjBBQ0ggPFJSIFIgRiBSMD4KCSAqCgkgKiBUaGUgRmxleG5ldCBEQU1BIE1hc3RlciBpbXBsZW1lbnRhdGlvbiBhcHBhcmVudGx5CgkgKiBpbnNpc3RzIG9uIHRoZSAicHJvcGVyIiBBWC4yNSBiZWhhdmlvdXI6CgkgKgoJICogCURCMEFDSC0+REwxQktFIDxSUiBDIFAgUjA+IFtEQU1BXQoJICoJREwxQktFLT5EQjBBQ0ggPFJSIFIgRiBSMD4KCSAqCURMMUJLRS0+REIwQUNIIDxJIE5SPTAgTlM9MD4KCSAqCURMMUJLRS03LT5EQjBQUkEtNiBEQjBBQ0ggPEkgQyBTMyBSNT4KCSAqCgkgKiBGbGV4bmV0IHJlZnVzZXMgdG8gc2VuZCB1cyAqYW55KiBJIGZyYW1lIGlmIHdlIHNlbmQKCSAqIGEgUkVKIGluIGNhc2UgQVgyNV9DT05EX1JFSkVDVCBpcyBzZXQuIEl0IGlzIHN1cGVyZmx1b3VzIGluCgkgKiB0aGlzIG1vZGUgYW55d2F5IChhIFJSIG9yIFJOUiBpbnZva2VzIHRoZSByZXRyYW5zbWlzc2lvbikuCgkgKiBJcyB0aGlzIGEgRmxleG5ldCBidWc/CgkgKi8KCglheDI1X3N0ZF9lbnF1aXJ5X3Jlc3BvbnNlKGF4MjUpOwoKCWlmICghKGF4MjUtPmNvbmRpdGlvbiAmIEFYMjVfQ09ORF9QRUVSX1JYX0JVU1kpKSB7CgkJYXgyNV9yZXF1ZXVlX2ZyYW1lcyhheDI1KTsKCQlheDI1X2tpY2soYXgyNSk7Cgl9CgoJaWYgKGF4MjUtPnN0YXRlID09IEFYMjVfU1RBVEVfMSB8fCBheDI1LT5zdGF0ZSA9PSBBWDI1X1NUQVRFXzIgfHwgc2tiX3BlZWsoJmF4MjUtPmFja19xdWV1ZSkgIT0gTlVMTCkKCQlheDI1X2RzX3QxX3RpbWVvdXQoYXgyNSk7CgllbHNlCgkJYXgyNS0+bjJjb3VudCA9IDA7CgoJYXgyNV9zdGFydF90M3RpbWVyKGF4MjUpOwoJYXgyNV9kc19zZXRfdGltZXIoYXgyNS0+YXgyNV9kZXYpOwoKCXNwaW5fbG9ja19iaCgmYXgyNV9saXN0X2xvY2spOwoJYXgyNV9mb3JfZWFjaChheDI1bywgbm9kZSwgJmF4MjVfbGlzdCkgewoJCWlmIChheDI1byA9PSBheDI1KQoJCQljb250aW51ZTsKCgkJaWYgKGF4MjVvLT5heDI1X2RldiAhPSBheDI1LT5heDI1X2RldikKCQkJY29udGludWU7CgoJCWlmIChheDI1by0+c3RhdGUgPT0gQVgyNV9TVEFURV8xIHx8IGF4MjVvLT5zdGF0ZSA9PSBBWDI1X1NUQVRFXzIpIHsKCQkJYXgyNV9kc190MV90aW1lb3V0KGF4MjVvKTsKCQkJY29udGludWU7CgkJfQoKCQlpZiAoIShheDI1by0+Y29uZGl0aW9uICYgQVgyNV9DT05EX1BFRVJfUlhfQlVTWSkgJiYgYXgyNW8tPnN0YXRlID09IEFYMjVfU1RBVEVfMykgewoJCQlheDI1X3JlcXVldWVfZnJhbWVzKGF4MjVvKTsKCQkJYXgyNV9raWNrKGF4MjVvKTsKCQl9CgoJCWlmIChheDI1by0+c3RhdGUgPT0gQVgyNV9TVEFURV8xIHx8IGF4MjVvLT5zdGF0ZSA9PSBBWDI1X1NUQVRFXzIgfHwgc2tiX3BlZWsoJmF4MjVvLT5hY2tfcXVldWUpICE9IE5VTEwpCgkJCWF4MjVfZHNfdDFfdGltZW91dChheDI1byk7CgoJCS8qIGRvIG5vdCBzdGFydCBUMyBmb3IgbGlzdGVuaW5nIHNvY2tldHMgKHRueCBERDhORSkgKi8KCgkJaWYgKGF4MjVvLT5zdGF0ZSAhPSBBWDI1X1NUQVRFXzApCgkJCWF4MjVfc3RhcnRfdDN0aW1lcihheDI1byk7Cgl9CglzcGluX3VubG9ja19iaCgmYXgyNV9saXN0X2xvY2spOwp9Cgp2b2lkIGF4MjVfZHNfZXN0YWJsaXNoX2RhdGFfbGluayhheDI1X2NiICpheDI1KQp7CglheDI1LT5jb25kaXRpb24gJj0gQVgyNV9DT05EX0RBTUFfTU9ERTsKCWF4MjUtPm4yY291bnQgICAgPSAwOwoJYXgyNV9jYWxjdWxhdGVfdDEoYXgyNSk7CglheDI1X3N0YXJ0X3QxdGltZXIoYXgyNSk7CglheDI1X3N0b3BfdDJ0aW1lcihheDI1KTsKCWF4MjVfc3RhcnRfdDN0aW1lcihheDI1KTsKfQoKLyoKICoJOjo6RklYTUU6OjoKICoJVGhpcyBpcyBhIGtsdWRnZS4gTm90IGFsbCBkcml2ZXJzIHJlY29nbml6ZSBraXNzIGNvbW1hbmRzLgogKglXZSBuZWVkIGEgZHJpdmVyIGxldmVsICByZXF1ZXN0IHRvIHN3aXRjaCBkdXBsZXggbW9kZSwgdGhhdCBkb2VzCiAqCWVpdGhlciBTQ0MgY2hhbmdpbmcsIFBJIGNvbmZpZyBvciBLSVNTIGFzIHJlcXVpcmVkLiBDdXJyZW50bHkKICoJdGhpcyByZXF1ZXN0IGlzbid0IHJlbGlhYmxlLgogKi8Kc3RhdGljIHZvaWQgYXgyNV9raXNzX2NtZChheDI1X2RldiAqYXgyNV9kZXYsIHVuc2lnbmVkIGNoYXIgY21kLCB1bnNpZ25lZCBjaGFyIHBhcmFtKQp7CglzdHJ1Y3Qgc2tfYnVmZiAqc2tiOwoJdW5zaWduZWQgY2hhciAqcDsKCglpZiAoYXgyNV9kZXYtPmRldiA9PSBOVUxMKQoJCXJldHVybjsKCglpZiAoKHNrYiA9IGFsbG9jX3NrYigyLCBHRlBfQVRPTUlDKSkgPT0gTlVMTCkKCQlyZXR1cm47CgoJc2tiLT5uaC5yYXcgPSBza2ItPmRhdGE7CglwID0gc2tiX3B1dChza2IsIDIpOwoKCSpwKysgPSBjbWQ7CgkqcCsrID0gcGFyYW07CgoJc2tiLT5wcm90b2NvbCA9IGF4MjVfdHlwZV90cmFucyhza2IsIGF4MjVfZGV2LT5kZXYpOwoKCWRldl9xdWV1ZV94bWl0KHNrYik7Cn0KCi8qCiAqCUEgbmFzdHkgcHJvYmxlbSBhcmlzZXMgaWYgd2UgY291bnQgdGhlIG51bWJlciBvZiBEQU1BIGNvbm5lY3Rpb25zCiAqCXdyb25nLCBlc3BlY2lhbGx5IHdoZW4gY29ubmVjdGlvbnMgb24gdGhlIGRldmljZSBhbHJlYWR5IGV4aXN0ZWQKICoJYW5kIG91ciBuZXR3b3JrIG5vZGUgKG9yIHRoZSBzeXNvcCkgZGVjaWRlcyB0byB0dXJuIG9uIERBTUEgTWFzdGVyCiAqCW1vZGUuIFdlIHRodXMgZmxhZyB0aGUgJ3JlYWwnIHNsYXZlIGNvbm5lY3Rpb25zIHdpdGgKICoJYXgyNS0+ZGFtYV9zbGF2ZT0xIGFuZCBsb29rIG9uIGV2ZXJ5IGRpc2Nvbm5lY3QgaWYgc3RpbGwgc2xhdmUKICoJY29ubmVjdGlvbnMgZXhpc3QuCiAqLwpzdGF0aWMgaW50IGF4MjVfY2hlY2tfZGFtYV9zbGF2ZShheDI1X2RldiAqYXgyNV9kZXYpCnsKCWF4MjVfY2IgKmF4MjU7CglpbnQgcmVzID0gMDsKCXN0cnVjdCBobGlzdF9ub2RlICpub2RlOwoKCXNwaW5fbG9ja19iaCgmYXgyNV9saXN0X2xvY2spOwoJYXgyNV9mb3JfZWFjaChheDI1LCBub2RlLCAmYXgyNV9saXN0KQoJCWlmIChheDI1LT5heDI1X2RldiA9PSBheDI1X2RldiAmJiAoYXgyNS0+Y29uZGl0aW9uICYgQVgyNV9DT05EX0RBTUFfTU9ERSkgJiYgYXgyNS0+c3RhdGUgPiBBWDI1X1NUQVRFXzEpIHsKCQkJcmVzID0gMTsKCQkJYnJlYWs7CgkJfQoJc3Bpbl91bmxvY2tfYmgoJmF4MjVfbGlzdF9sb2NrKTsKCglyZXR1cm4gcmVzOwp9CgpzdGF0aWMgdm9pZCBheDI1X2Rldl9kYW1hX29uKGF4MjVfZGV2ICpheDI1X2RldikKewoJaWYgKGF4MjVfZGV2ID09IE5VTEwpCgkJcmV0dXJuOwoKCWlmIChheDI1X2Rldi0+ZGFtYS5zbGF2ZSA9PSAwKQoJCWF4MjVfa2lzc19jbWQoYXgyNV9kZXYsIDUsIDEpOwoKCWF4MjVfZGV2LT5kYW1hLnNsYXZlID0gMTsKCWF4MjVfZHNfc2V0X3RpbWVyKGF4MjVfZGV2KTsKfQoKdm9pZCBheDI1X2Rldl9kYW1hX29mZihheDI1X2RldiAqYXgyNV9kZXYpCnsKCWlmIChheDI1X2RldiA9PSBOVUxMKQoJCXJldHVybjsKCglpZiAoYXgyNV9kZXYtPmRhbWEuc2xhdmUgJiYgIWF4MjVfY2hlY2tfZGFtYV9zbGF2ZShheDI1X2RldikpIHsKCQlheDI1X2tpc3NfY21kKGF4MjVfZGV2LCA1LCAwKTsKCQlheDI1X2Rldi0+ZGFtYS5zbGF2ZSA9IDA7CgkJYXgyNV9kc19kZWxfdGltZXIoYXgyNV9kZXYpOwoJfQp9Cgp2b2lkIGF4MjVfZGFtYV9vbihheDI1X2NiICpheDI1KQp7CglheDI1X2Rldl9kYW1hX29uKGF4MjUtPmF4MjVfZGV2KTsKCWF4MjUtPmNvbmRpdGlvbiB8PSBBWDI1X0NPTkRfREFNQV9NT0RFOwp9Cgp2b2lkIGF4MjVfZGFtYV9vZmYoYXgyNV9jYiAqYXgyNSkKewoJYXgyNS0+Y29uZGl0aW9uICY9IH5BWDI1X0NPTkRfREFNQV9NT0RFOwoJYXgyNV9kZXZfZGFtYV9vZmYoYXgyNS0+YXgyNV9kZXYpOwp9Cgo=