LyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAqLwovKiBpMmMtYWxnby1iaXQuYyBpMmMgZHJpdmVyIGFsZ29yaXRobXMgZm9yIGJpdC1zaGlmdCBhZGFwdGVycwkJICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCi8qICAgQ29weXJpZ2h0IChDKSAxOTk1LTIwMDAgU2ltb24gRy4gVm9nbAoKICAgIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAgICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICAgIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCgogICAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAgICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogICAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogICAgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICAgIEZvdW5kYXRpb24sIEluYy4sIDY3NSBNYXNzIEF2ZSwgQ2FtYnJpZGdlLCBNQSAwMjEzOSwgVVNBLgkJICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiBXaXRoIHNvbWUgY2hhbmdlcyBmcm9tIEZyb2RvIExvb2lqYWFyZCA8ZnJvZG9sQGRkcy5ubD4sIEt59nN0aSBN5Gxra2kKICAgPGttYWxra2lAY2MuaHV0LmZpPiBhbmQgSmVhbiBEZWx2YXJlIDxraGFsaUBsaW51eC1mci5vcmc+ICovCgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2RlbGF5Lmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9lcnJuby5oPgojaW5jbHVkZSA8bGludXgvc2NoZWQuaD4KI2luY2x1ZGUgPGxpbnV4L2kyYy5oPgojaW5jbHVkZSA8bGludXgvaTJjLWFsZ28tYml0Lmg+CgoKLyogLS0tLS0gZ2xvYmFsIGRlZmluZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KI2RlZmluZSBERUIoeCkgaWYgKGkyY19kZWJ1Zz49MSkgeDsKI2RlZmluZSBERUIyKHgpIGlmIChpMmNfZGVidWc+PTIpIHg7CiNkZWZpbmUgREVCU1RBVCh4KSBpZiAoaTJjX2RlYnVnPj0zKSB4OyAvKiBwcmludCBzZXZlcmFsIHN0YXRpc3RpY2FsIHZhbHVlcyovCiNkZWZpbmUgREVCUFJPVE8oeCkgaWYgKGkyY19kZWJ1Zz49OSkgeyB4OyB9CiAJLyogZGVidWcgdGhlIHByb3RvY29sIGJ5IHNob3dpbmcgdHJhbnNmZXJyZWQgYml0cyAqLwoKCi8qIC0tLS0tIGdsb2JhbCB2YXJpYWJsZXMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCSovCgovKiBtb2R1bGUgcGFyYW1ldGVyczoKICovCnN0YXRpYyBpbnQgaTJjX2RlYnVnOwpzdGF0aWMgaW50IGJpdF90ZXN0OwkvKiBzZWUgaWYgdGhlIGxpbmUtc2V0dGluZyBmdW5jdGlvbnMgd29yawkqLwoKLyogLS0tIHNldHRpbmcgc3RhdGVzIG9uIHRoZSBidXMgd2l0aCB0aGUgcmlnaHQgdGltaW5nOiAtLS0tLS0tLS0tLS0tLS0JKi8KCiNkZWZpbmUgc2V0c2RhKGFkYXAsdmFsKSBhZGFwLT5zZXRzZGEoYWRhcC0+ZGF0YSwgdmFsKQojZGVmaW5lIHNldHNjbChhZGFwLHZhbCkgYWRhcC0+c2V0c2NsKGFkYXAtPmRhdGEsIHZhbCkKI2RlZmluZSBnZXRzZGEoYWRhcCkgYWRhcC0+Z2V0c2RhKGFkYXAtPmRhdGEpCiNkZWZpbmUgZ2V0c2NsKGFkYXApIGFkYXAtPmdldHNjbChhZGFwLT5kYXRhKQoKc3RhdGljIGlubGluZSB2b2lkIHNkYWxvKHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkKewoJc2V0c2RhKGFkYXAsMCk7Cgl1ZGVsYXkoYWRhcC0+dWRlbGF5KTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNkYWhpKHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkKewoJc2V0c2RhKGFkYXAsMSk7Cgl1ZGVsYXkoYWRhcC0+dWRlbGF5KTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNjbGxvKHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkKewoJc2V0c2NsKGFkYXAsMCk7Cgl1ZGVsYXkoYWRhcC0+dWRlbGF5KTsKfQoKLyoKICogUmFpc2Ugc2NsIGxpbmUsIGFuZCBkbyBjaGVja2luZyBmb3IgZGVsYXlzLiBUaGlzIGlzIG5lY2Vzc2FyeSBmb3Igc2xvd2VyCiAqIGRldmljZXMuCiAqLwpzdGF0aWMgaW5saW5lIGludCBzY2xoaShzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXApCnsKCXVuc2lnbmVkIGxvbmcgc3RhcnQ7CgoJc2V0c2NsKGFkYXAsMSk7CgoJLyogTm90IGFsbCBhZGFwdGVycyBoYXZlIHNjbCBzZW5zZSBsaW5lLi4uICovCglpZiAoYWRhcC0+Z2V0c2NsID09IE5VTEwgKSB7CgkJdWRlbGF5KGFkYXAtPnVkZWxheSk7CgkJcmV0dXJuIDA7Cgl9CgoJc3RhcnQ9amlmZmllczsKCXdoaWxlICghIGdldHNjbChhZGFwKSApIHsJCiAJCS8qIHRoZSBodyBrbm93cyBob3cgdG8gcmVhZCB0aGUgY2xvY2sgbGluZSwKIAkJICogc28gd2Ugd2FpdCB1bnRpbCBpdCBhY3R1YWxseSBnZXRzIGhpZ2guCiAJCSAqIFRoaXMgaXMgc2FmZXIgYXMgc29tZSBjaGlwcyBtYXkgaG9sZCBpdCBsb3cKIAkJICogd2hpbGUgdGhleSBhcmUgcHJvY2Vzc2luZyBkYXRhIGludGVybmFsbHkuIAogCQkgKi8KCQlpZiAodGltZV9hZnRlcl9lcShqaWZmaWVzLCBzdGFydCthZGFwLT50aW1lb3V0KSkgewoJCQlyZXR1cm4gLUVUSU1FRE9VVDsKCQl9CgkJY29uZF9yZXNjaGVkKCk7Cgl9CglERUJTVEFUKHByaW50ayhLRVJOX0RFQlVHICJuZWVkZWQgJWxkIGppZmZpZXNcbiIsIGppZmZpZXMtc3RhcnQpKTsKCXVkZWxheShhZGFwLT51ZGVsYXkpOwoJcmV0dXJuIDA7Cn0gCgoKLyogLS0tIG90aGVyIGF1eGlsaWFyeSBmdW5jdGlvbnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0JKi8Kc3RhdGljIHZvaWQgaTJjX3N0YXJ0KHN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCkgCnsKCS8qIGFzc2VydDogc2NsLCBzZGEgYXJlIGhpZ2ggKi8KCURFQlBST1RPKHByaW50aygiUyAiKSk7CglzZGFsbyhhZGFwKTsKCXNjbGxvKGFkYXApOwp9CgpzdGF0aWMgdm9pZCBpMmNfcmVwc3RhcnQoc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwKSAKewoJLyogc2NsLCBzZGEgbWF5IG5vdCBiZSBoaWdoICovCglERUJQUk9UTyhwcmludGsoIiBTciAiKSk7CglzZXRzZGEoYWRhcCwxKTsKCXNjbGhpKGFkYXApOwoJdWRlbGF5KGFkYXAtPnVkZWxheSk7CgkKCXNkYWxvKGFkYXApOwoJc2NsbG8oYWRhcCk7Cn0KCgpzdGF0aWMgdm9pZCBpMmNfc3RvcChzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXApIAp7CglERUJQUk9UTyhwcmludGsoIlBcbiIpKTsKCS8qIGFzc2VydDogc2NsIGlzIGxvdyAqLwoJc2RhbG8oYWRhcCk7CglzY2xoaShhZGFwKTsgCglzZGFoaShhZGFwKTsKfQoKCgovKiBzZW5kIGEgYnl0ZSB3aXRob3V0IHN0YXJ0IGNvbmQuLCBsb29rIGZvciBhcmJpdHJhdGlvbiwgCiAgIGNoZWNrIGFja24uIGZyb20gc2xhdmUgKi8KLyogcmV0dXJuczoKICogMSBpZiB0aGUgZGV2aWNlIGFja25vd2xlZGdlZAogKiAwIGlmIHRoZSBkZXZpY2UgZGlkIG5vdCBhY2sKICogLUVUSU1FRE9VVCBpZiBhbiBlcnJvciBvY2N1cnJlZCAod2hpbGUgcmFpc2luZyB0aGUgc2NsIGxpbmUpCiAqLwpzdGF0aWMgaW50IGkyY19vdXRiKHN0cnVjdCBpMmNfYWRhcHRlciAqaTJjX2FkYXAsIGNoYXIgYykKewoJaW50IGk7CglpbnQgc2I7CglpbnQgYWNrOwoJc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwID0gaTJjX2FkYXAtPmFsZ29fZGF0YTsKCgkvKiBhc3NlcnQ6IHNjbCBpcyBsb3cgKi8KCWZvciAoIGk9NyA7IGk+PTAgOyBpLS0gKSB7CgkJc2IgPSBjICYgKCAxIDw8IGkgKTsKCQlzZXRzZGEoYWRhcCxzYik7CgkJdWRlbGF5KGFkYXAtPnVkZWxheSk7CgkJREVCUFJPVE8ocHJpbnRrKEtFUk5fREVCVUcgIiVkIixzYiE9MCkpOwoJCWlmIChzY2xoaShhZGFwKTwwKSB7IC8qIHRpbWVkIG91dCAqLwoJCQlzZGFoaShhZGFwKTsgLyogd2UgZG9uJ3Qgd2FudCB0byBibG9jayB0aGUgbmV0ICovCgkJCURFQjIocHJpbnRrKEtFUk5fREVCVUcgIiBpMmNfb3V0YjogMHglMDJ4LCB0aW1lb3V0IGF0IGJpdCAjJWRcbiIsIGMmMHhmZiwgaSkpOwoJCQlyZXR1cm4gLUVUSU1FRE9VVDsKCQl9OwoJCS8qIGRvIGFyYml0cmF0aW9uIGhlcmU6IAoJCSAqIGlmICggc2IgJiYgISBnZXRzZGEoYWRhcCkgKSAtPiBvdWNoISBHZXQgb3V0IG9mIGhlcmUuCgkJICovCgkJc2V0c2NsKGFkYXAsIDAgKTsKCQl1ZGVsYXkoYWRhcC0+dWRlbGF5KTsKCX0KCXNkYWhpKGFkYXApOwoJaWYgKHNjbGhpKGFkYXApPDApeyAvKiB0aW1lb3V0ICovCgkgICAgREVCMihwcmludGsoS0VSTl9ERUJVRyAiIGkyY19vdXRiOiAweCUwMngsIHRpbWVvdXQgYXQgYWNrXG4iLCBjJjB4ZmYpKTsKCSAgICByZXR1cm4gLUVUSU1FRE9VVDsKCX07CgkvKiByZWFkIGFjazogU0RBIHNob3VsZCBiZSBwdWxsZWQgZG93biBieSBzbGF2ZSAqLwoJYWNrPWdldHNkYShhZGFwKTsJLyogYWNrOiBzZGEgaXMgcHVsbGVkIGxvdyAtPnN1Y2Nlc3MuCSAqLwoJREVCMihwcmludGsoS0VSTl9ERUJVRyAiIGkyY19vdXRiOiAweCUwMnggLCBnZXRzZGEoKSA9ICVkXG4iLCBjICYgMHhmZiwgYWNrKSk7CgoJREVCUFJPVE8oIHByaW50ayhLRVJOX0RFQlVHICJbJTIuMnhdIixjJjB4ZmYpICk7CglERUJQUk9UTyhpZiAoMD09YWNrKXsgcHJpbnRrKEtFUk5fREVCVUcgIiBBICIpO30gZWxzZSBwcmludGsoS0VSTl9ERUJVRyAiIE5BICIpICk7CglzY2xsbyhhZGFwKTsKCXJldHVybiAwPT1hY2s7CQkvKiByZXR1cm4gMSBpZiBkZXZpY2UgYWNrZWQJICovCgkvKiBhc3NlcnQ6IHNjbCBpcyBsb3cgKHNkYSB1bmRlZikgKi8KfQoKCnN0YXRpYyBpbnQgaTJjX2luYihzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwKSAKewoJLyogcmVhZCBieXRlIHZpYSBpMmMgcG9ydCwgd2l0aG91dCBzdGFydC9zdG9wIHNlcXVlbmNlCSovCgkvKiBhY2tub3dsZWRnZSBpcyBzZW50IGluIGkyY19yZWFkLgkJCSovCglpbnQgaTsKCXVuc2lnbmVkIGNoYXIgaW5kYXRhPTA7CglzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwoKCS8qIGFzc2VydDogc2NsIGlzIGxvdyAqLwoJc2RhaGkoYWRhcCk7Cglmb3IgKGk9MDtpPDg7aSsrKSB7CgkJaWYgKHNjbGhpKGFkYXApPDApIHsgLyogdGltZW91dCAqLwoJCQlERUIyKHByaW50ayhLRVJOX0RFQlVHICIgaTJjX2luYjogdGltZW91dCBhdCBiaXQgIyVkXG4iLCA3LWkpKTsKCQkJcmV0dXJuIC1FVElNRURPVVQ7CgkJfTsKCQlpbmRhdGEgKj0gMjsKCQlpZiAoIGdldHNkYShhZGFwKSApIAoJCQlpbmRhdGEgfD0gMHgwMTsKCQlzY2xsbyhhZGFwKTsKCX0KCS8qIGFzc2VydDogc2NsIGlzIGxvdyAqLwoJREVCMihwcmludGsoS0VSTl9ERUJVRyAiaTJjX2luYjogMHglMDJ4XG4iLCBpbmRhdGEgJiAweGZmKSk7CgoJREVCUFJPVE8ocHJpbnRrKEtFUk5fREVCVUcgIiAweCUwMngiLCBpbmRhdGEgJiAweGZmKSk7CglyZXR1cm4gKGludCkgKGluZGF0YSAmIDB4ZmYpOwp9CgovKgogKiBTYW5pdHkgY2hlY2sgZm9yIHRoZSBhZGFwdGVyIGhhcmR3YXJlIC0gY2hlY2sgdGhlIHJlYWN0aW9uIG9mCiAqIHRoZSBidXMgbGluZXMgb25seSBpZiBpdCBzZWVtcyB0byBiZSBpZGxlLgogKi8Kc3RhdGljIGludCB0ZXN0X2J1cyhzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXAsIGNoYXIqIG5hbWUpIHsKCWludCBzY2wsc2RhOwoKCWlmIChhZGFwLT5nZXRzY2w9PU5VTEwpCgkJcHJpbnRrKEtFUk5fSU5GTyAiaTJjLWFsZ28tYml0Lm86IFRlc3RpbmcgU0RBIG9ubHksICIKCQkJIlNDTCBpcyBub3QgcmVhZGFibGUuXG4iKTsKCglzZGE9Z2V0c2RhKGFkYXApOwoJc2NsPShhZGFwLT5nZXRzY2w9PU5VTEw/MTpnZXRzY2woYWRhcCkpOwoJcHJpbnRrKEtFUk5fREVCVUcgImkyYy1hbGdvLWJpdC5vOiAoMCkgc2NsPSVkLCBzZGE9JWRcbiIsc2NsLHNkYSk7CglpZiAoIXNjbCB8fCAhc2RhICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkyYy1hbGdvLWJpdC5vOiAlcyBzZWVtcyB0byBiZSBidXN5LlxuIiwgbmFtZSk7CgkJZ290byBiYWlsb3V0OwoJfQoKCXNkYWxvKGFkYXApOwoJc2RhPWdldHNkYShhZGFwKTsKCXNjbD0oYWRhcC0+Z2V0c2NsPT1OVUxMPzE6Z2V0c2NsKGFkYXApKTsKCXByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1iaXQubzogKDEpIHNjbD0lZCwgc2RhPSVkXG4iLHNjbCxzZGEpOwoJaWYgKCAwICE9IHNkYSApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJpMmMtYWxnby1iaXQubzogU0RBIHN0dWNrIGhpZ2ghXG4iKTsKCQlnb3RvIGJhaWxvdXQ7Cgl9CglpZiAoIDAgPT0gc2NsICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkyYy1hbGdvLWJpdC5vOiBTQ0wgdW5leHBlY3RlZCBsb3cgIgoJCQkid2hpbGUgcHVsbGluZyBTREEgbG93IVxuIik7CgkJZ290byBiYWlsb3V0OwoJfQkJCgoJc2RhaGkoYWRhcCk7CglzZGE9Z2V0c2RhKGFkYXApOwoJc2NsPShhZGFwLT5nZXRzY2w9PU5VTEw/MTpnZXRzY2woYWRhcCkpOwoJcHJpbnRrKEtFUk5fREVCVUcgImkyYy1hbGdvLWJpdC5vOiAoMikgc2NsPSVkLCBzZGE9JWRcbiIsc2NsLHNkYSk7CglpZiAoIDAgPT0gc2RhICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkyYy1hbGdvLWJpdC5vOiBTREEgc3R1Y2sgbG93IVxuIik7CgkJZ290byBiYWlsb3V0OwoJfQoJaWYgKCAwID09IHNjbCApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJpMmMtYWxnby1iaXQubzogU0NMIHVuZXhwZWN0ZWQgbG93ICIKCQkJIndoaWxlIHB1bGxpbmcgU0RBIGhpZ2ghXG4iKTsKCQlnb3RvIGJhaWxvdXQ7Cgl9CgoJc2NsbG8oYWRhcCk7CglzZGE9Z2V0c2RhKGFkYXApOwoJc2NsPShhZGFwLT5nZXRzY2w9PU5VTEw/MDpnZXRzY2woYWRhcCkpOwoJcHJpbnRrKEtFUk5fREVCVUcgImkyYy1hbGdvLWJpdC5vOiAoMykgc2NsPSVkLCBzZGE9JWRcbiIsc2NsLHNkYSk7CglpZiAoIDAgIT0gc2NsICkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgImkyYy1hbGdvLWJpdC5vOiBTQ0wgc3R1Y2sgaGlnaCFcbiIpOwoJCWdvdG8gYmFpbG91dDsKCX0KCWlmICggMCA9PSBzZGEgKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiaTJjLWFsZ28tYml0Lm86IFNEQSB1bmV4cGVjdGVkIGxvdyAiCgkJCSJ3aGlsZSBwdWxsaW5nIFNDTCBsb3chXG4iKTsKCQlnb3RvIGJhaWxvdXQ7Cgl9CgkKCXNjbGhpKGFkYXApOwoJc2RhPWdldHNkYShhZGFwKTsKCXNjbD0oYWRhcC0+Z2V0c2NsPT1OVUxMPzE6Z2V0c2NsKGFkYXApKTsKCXByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1iaXQubzogKDQpIHNjbD0lZCwgc2RhPSVkXG4iLHNjbCxzZGEpOwoJaWYgKCAwID09IHNjbCApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJpMmMtYWxnby1iaXQubzogU0NMIHN0dWNrIGxvdyFcbiIpOwoJCWdvdG8gYmFpbG91dDsKCX0KCWlmICggMCA9PSBzZGEgKSB7CgkJcHJpbnRrKEtFUk5fV0FSTklORyAiaTJjLWFsZ28tYml0Lm86IFNEQSB1bmV4cGVjdGVkIGxvdyAiCgkJCSJ3aGlsZSBwdWxsaW5nIFNDTCBoaWdoIVxuIik7CgkJZ290byBiYWlsb3V0OwoJfQoJcHJpbnRrKEtFUk5fSU5GTyAiaTJjLWFsZ28tYml0Lm86ICVzIHBhc3NlZCB0ZXN0LlxuIixuYW1lKTsKCXJldHVybiAwOwpiYWlsb3V0OgoJc2RhaGkoYWRhcCk7CglzY2xoaShhZGFwKTsKCXJldHVybiAtRU5PREVWOwp9CgovKiAtLS0tLSBVdGlsaXR5IGZ1bmN0aW9ucwogKi8KCi8qIHRyeV9hZGRyZXNzIHRyaWVzIHRvIGNvbnRhY3QgYSBjaGlwIGZvciBhIG51bWJlciBvZgogKiB0aW1lcyBiZWZvcmUgaXQgZ2l2ZXMgdXAuCiAqIHJldHVybiB2YWx1ZXM6CiAqIDEgY2hpcCBhbnN3ZXJlZAogKiAwIGNoaXAgZGlkIG5vdCBhbnN3ZXIKICogLXggdHJhbnNtaXNzaW9uIGVycm9yCiAqLwpzdGF0aWMgaW5saW5lIGludCB0cnlfYWRkcmVzcyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLAoJCSAgICAgICB1bnNpZ25lZCBjaGFyIGFkZHIsIGludCByZXRyaWVzKQp7CglzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwoJaW50IGkscmV0ID0gLTE7Cglmb3IgKGk9MDtpPD1yZXRyaWVzO2krKykgewoJCXJldCA9IGkyY19vdXRiKGkyY19hZGFwLGFkZHIpOwoJCWlmIChyZXQ9PTEpCgkJCWJyZWFrOwkvKiBzdWNjZXNzISAqLwoJCWkyY19zdG9wKGFkYXApOwoJCXVkZWxheSg1LyphZGFwLT51ZGVsYXkqLyk7CgkJaWYgKGk9PXJldHJpZXMpICAvKiBubyBzdWNjZXNzICovCgkJCWJyZWFrOwoJCWkyY19zdGFydChhZGFwKTsKCQl1ZGVsYXkoYWRhcC0+dWRlbGF5KTsKCX0KCURFQjIoaWYgKGkpCgkgICAgIHByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1iaXQubzogVXNlZCAlZCB0cmllcyB0byAlcyBjbGllbnQgYXQgMHglMDJ4IDogJXNcbiIsCgkJICAgIGkrMSwgYWRkciAmIDEgPyAicmVhZCIgOiAid3JpdGUiLCBhZGRyPj4xLAoJCSAgICByZXQ9PTEgPyAic3VjY2VzcyIgOiByZXQ9PTAgPyAibm8gYWNrIiA6ICJmYWlsZWQsIHRpbWVvdXQ/IiApCgkgICAgKTsKCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgc2VuZGJ5dGVzKHN0cnVjdCBpMmNfYWRhcHRlciAqaTJjX2FkYXAsIHN0cnVjdCBpMmNfbXNnICptc2cpCnsKCXN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCA9IGkyY19hZGFwLT5hbGdvX2RhdGE7CgljaGFyIGM7Cgljb25zdCBjaGFyICp0ZW1wID0gbXNnLT5idWY7CglpbnQgY291bnQgPSBtc2ctPmxlbjsKCXVuc2lnbmVkIHNob3J0IG5ha19vayA9IG1zZy0+ZmxhZ3MgJiBJMkNfTV9JR05PUkVfTkFLOyAKCWludCByZXR2YWw7CglpbnQgd3Jjb3VudD0wOwoKCXdoaWxlIChjb3VudCA+IDApIHsKCQljID0gKnRlbXA7CgkJREVCMihkZXZfZGJnKCZpMmNfYWRhcC0+ZGV2LCAic2VuZGJ5dGVzOiB3cml0aW5nICUyLjJYXG4iLCBjJjB4ZmYpKTsKCQlyZXR2YWwgPSBpMmNfb3V0YihpMmNfYWRhcCxjKTsKCQlpZiAoKHJldHZhbD4wKSB8fCAobmFrX29rICYmIChyZXR2YWw9PTApKSkgIHsgLyogb2sgb3IgaWdub3JlZCBOQUsgKi8KCQkJY291bnQtLTsgCgkJCXRlbXArKzsKCQkJd3Jjb3VudCsrOwoJCX0gZWxzZSB7IC8qIGFyYml0cmF0aW9uIG9yIG5vIGFja25vd2xlZGdlICovCgkJCWRldl9lcnIoJmkyY19hZGFwLT5kZXYsICJzZW5kYnl0ZXM6IGVycm9yIC0gYmFpbG91dC5cbiIpOwoJCQlpMmNfc3RvcChhZGFwKTsKCQkJcmV0dXJuIChyZXR2YWw8MCk/IHJldHZhbCA6IC1FRkFVTFQ7CgkJCSAgICAgICAgLyogZ290IGEgYmV0dGVyIG9uZSA/PyAqLwoJCX0KI2lmIDAKCQkvKiBmcm9tIGFzbS9kZWxheS5oICovCgkJX19kZWxheShhZGFwLT5tZGVsYXkgKiAobG9vcHNfcGVyX3NlYyAvIDEwMDApICk7CiNlbmRpZgoJfQoJcmV0dXJuIHdyY291bnQ7Cn0KCnN0YXRpYyBpbmxpbmUgaW50IHJlYWRieXRlcyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmkyY19hZGFwLCBzdHJ1Y3QgaTJjX21zZyAqbXNnKQp7CglpbnQgaW52YWw7CglpbnQgcmRjb3VudD0wOyAgIAkvKiBjb3VudHMgYnl0ZXMgcmVhZCAqLwoJc3RydWN0IGkyY19hbGdvX2JpdF9kYXRhICphZGFwID0gaTJjX2FkYXAtPmFsZ29fZGF0YTsKCWNoYXIgKnRlbXAgPSBtc2ctPmJ1ZjsKCWludCBjb3VudCA9IG1zZy0+bGVuOwoKCXdoaWxlIChjb3VudCA+IDApIHsKCQlpbnZhbCA9IGkyY19pbmIoaTJjX2FkYXApOwoJCWlmIChpbnZhbD49MCkgewoJCQkqdGVtcCA9IGludmFsOwoJCQlyZGNvdW50Kys7CgkJfSBlbHNlIHsgICAvKiByZWFkIHRpbWVkIG91dCAqLwoJCQlwcmludGsoS0VSTl9FUlIgImkyYy1hbGdvLWJpdC5vOiByZWFkYnl0ZXM6IGkyY19pbmIgdGltZWQgb3V0LlxuIik7CgkJCWJyZWFrOwoJCX0KCgkJdGVtcCsrOwoJCWNvdW50LS07CgoJCWlmIChtc2ctPmZsYWdzICYgSTJDX01fTk9fUkRfQUNLKQoJCQljb250aW51ZTsKCgkJaWYgKCBjb3VudCA+IDAgKSB7CQkvKiBzZW5kIGFjayAqLwoJCQlzZGFsbyhhZGFwKTsKCQkJREVCUFJPVE8ocHJpbnRrKCIgQW0gIikpOwoJCX0gZWxzZSB7CgkJCXNkYWhpKGFkYXApOwkvKiBuZWcuIGFjayBvbiBsYXN0IGJ5dGUgKi8KCQkJREVCUFJPVE8ocHJpbnRrKCIgTkFtICIpKTsKCQl9CgkJaWYgKHNjbGhpKGFkYXApPDApIHsJLyogdGltZW91dCAqLwoJCQlzZGFoaShhZGFwKTsKCQkJcHJpbnRrKEtFUk5fRVJSICJpMmMtYWxnby1iaXQubzogcmVhZGJ5dGVzOiBUaW1lb3V0IGF0IGFja1xuIik7CgkJCXJldHVybiAtRVRJTUVET1VUOwoJCX07CgkJc2NsbG8oYWRhcCk7CgkJc2RhaGkoYWRhcCk7Cgl9CglyZXR1cm4gcmRjb3VudDsKfQoKLyogZG9BZGRyZXNzIGluaXRpYXRlcyB0aGUgdHJhbnNmZXIgYnkgZ2VuZXJhdGluZyB0aGUgc3RhcnQgY29uZGl0aW9uIChpbgogKiB0cnlfYWRkcmVzcykgYW5kIHRyYW5zbWl0cyB0aGUgYWRkcmVzcyBpbiB0aGUgbmVjZXNzYXJ5IGZvcm1hdCB0byBoYW5kbGUKICogcmVhZHMsIHdyaXRlcyBhcyB3ZWxsIGFzIDEwYml0LWFkZHJlc3Nlcy4KICogcmV0dXJuczoKICogIDAgZXZlcnl0aGluZyB3ZW50IG9rYXksIHRoZSBjaGlwIGFjaydlZCwgb3IgSUdOT1JFX05BSyBmbGFnIHdhcyBzZXQKICogLXggYW4gZXJyb3Igb2NjdXJyZWQgKGxpa2U6IC1FUkVNT1RFSU8gaWYgdGhlIGRldmljZSBkaWQgbm90IGFuc3dlciwgb3IKICoJLUVUSU1FRE9VVCwgZm9yIGV4YW1wbGUgaWYgdGhlIGxpbmVzIGFyZSBzdHVjay4uLikgCiAqLwpzdGF0aWMgaW5saW5lIGludCBiaXRfZG9BZGRyZXNzKHN0cnVjdCBpMmNfYWRhcHRlciAqaTJjX2FkYXAsIHN0cnVjdCBpMmNfbXNnICptc2cpIAp7Cgl1bnNpZ25lZCBzaG9ydCBmbGFncyA9IG1zZy0+ZmxhZ3M7Cgl1bnNpZ25lZCBzaG9ydCBuYWtfb2sgPSBtc2ctPmZsYWdzICYgSTJDX01fSUdOT1JFX05BSzsKCXN0cnVjdCBpMmNfYWxnb19iaXRfZGF0YSAqYWRhcCA9IGkyY19hZGFwLT5hbGdvX2RhdGE7CgoJdW5zaWduZWQgY2hhciBhZGRyOwoJaW50IHJldCwgcmV0cmllczsKCglyZXRyaWVzID0gbmFrX29rID8gMCA6IGkyY19hZGFwLT5yZXRyaWVzOwoJCglpZiAoIChmbGFncyAmIEkyQ19NX1RFTikgICkgeyAKCQkvKiBhIHRlbiBiaXQgYWRkcmVzcyAqLwoJCWFkZHIgPSAweGYwIHwgKCggbXNnLT5hZGRyID4+IDcpICYgMHgwMyk7CgkJREVCMihwcmludGsoS0VSTl9ERUJVRyAiYWRkcjA6ICVkXG4iLGFkZHIpKTsKCQkvKiB0cnkgZXh0ZW5kZWQgYWRkcmVzcyBjb2RlLi4uKi8KCQlyZXQgPSB0cnlfYWRkcmVzcyhpMmNfYWRhcCwgYWRkciwgcmV0cmllcyk7CgkJaWYgKChyZXQgIT0gMSkgJiYgIW5ha19vaykgIHsKCQkJcHJpbnRrKEtFUk5fRVJSICJkaWVkIGF0IGV4dGVuZGVkIGFkZHJlc3MgY29kZS5cbiIpOwoJCQlyZXR1cm4gLUVSRU1PVEVJTzsKCQl9CgkJLyogdGhlIHJlbWFpbmluZyA4IGJpdCBhZGRyZXNzICovCgkJcmV0ID0gaTJjX291dGIoaTJjX2FkYXAsbXNnLT5hZGRyICYgMHg3Zik7CgkJaWYgKChyZXQgIT0gMSkgJiYgIW5ha19vaykgewoJCQkvKiB0aGUgY2hpcCBkaWQgbm90IGFjayAvIHhtaXNzaW9uIGVycm9yIG9jY3VycmVkICovCgkJCXByaW50ayhLRVJOX0VSUiAiZGllZCBhdCAybmQgYWRkcmVzcyBjb2RlLlxuIik7CgkJCXJldHVybiAtRVJFTU9URUlPOwoJCX0KCQlpZiAoIGZsYWdzICYgSTJDX01fUkQgKSB7CgkJCWkyY19yZXBzdGFydChhZGFwKTsKCQkJLyogb2theSwgbm93IHN3aXRjaCBpbnRvIHJlYWRpbmcgbW9kZSAqLwoJCQlhZGRyIHw9IDB4MDE7CgkJCXJldCA9IHRyeV9hZGRyZXNzKGkyY19hZGFwLCBhZGRyLCByZXRyaWVzKTsKCQkJaWYgKChyZXQhPTEpICYmICFuYWtfb2spIHsKCQkJCXByaW50ayhLRVJOX0VSUiAiZGllZCBhdCBleHRlbmRlZCBhZGRyZXNzIGNvZGUuXG4iKTsKCQkJCXJldHVybiAtRVJFTU9URUlPOwoJCQl9CgkJfQoJfSBlbHNlIHsJCS8qIG5vcm1hbCA3Yml0IGFkZHJlc3MJKi8KCQlhZGRyID0gKCBtc2ctPmFkZHIgPDwgMSApOwoJCWlmIChmbGFncyAmIEkyQ19NX1JEICkKCQkJYWRkciB8PSAxOwoJCWlmIChmbGFncyAmIEkyQ19NX1JFVl9ESVJfQUREUiApCgkJCWFkZHIgXj0gMTsKCQlyZXQgPSB0cnlfYWRkcmVzcyhpMmNfYWRhcCwgYWRkciwgcmV0cmllcyk7CgkJaWYgKChyZXQhPTEpICYmICFuYWtfb2spCgkJCXJldHVybiAtRVJFTU9URUlPOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IGJpdF94ZmVyKHN0cnVjdCBpMmNfYWRhcHRlciAqaTJjX2FkYXAsCgkJICAgIHN0cnVjdCBpMmNfbXNnIG1zZ3NbXSwgaW50IG51bSkKewoJc3RydWN0IGkyY19tc2cgKnBtc2c7CglzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmFkYXAgPSBpMmNfYWRhcC0+YWxnb19kYXRhOwoJCglpbnQgaSxyZXQ7Cgl1bnNpZ25lZCBzaG9ydCBuYWtfb2s7CgoJaTJjX3N0YXJ0KGFkYXApOwoJZm9yIChpPTA7aTxudW07aSsrKSB7CgkJcG1zZyA9ICZtc2dzW2ldOwoJCW5ha19vayA9IHBtc2ctPmZsYWdzICYgSTJDX01fSUdOT1JFX05BSzsgCgkJaWYgKCEocG1zZy0+ZmxhZ3MgJiBJMkNfTV9OT1NUQVJUKSkgewoJCQlpZiAoaSkgewoJCQkJaTJjX3JlcHN0YXJ0KGFkYXApOwoJCQl9CgkJCXJldCA9IGJpdF9kb0FkZHJlc3MoaTJjX2FkYXAsIHBtc2cpOwoJCQlpZiAoKHJldCAhPSAwKSAmJiAhbmFrX29rKSB7CgkJCSAgICBERUIyKHByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1iaXQubzogTkFLIGZyb20gZGV2aWNlIGFkZHIgJTIuMnggbXNnICMlZFxuIgoJCQkJCSxtc2dzW2ldLmFkZHIsaSkpOwoJCQkgICAgcmV0dXJuIChyZXQ8MCkgPyByZXQgOiAtRVJFTU9URUlPOwoJCQl9CgkJfQoJCWlmIChwbXNnLT5mbGFncyAmIEkyQ19NX1JEICkgewoJCQkvKiByZWFkIGJ5dGVzIGludG8gYnVmZmVyKi8KCQkJcmV0ID0gcmVhZGJ5dGVzKGkyY19hZGFwLCBwbXNnKTsKCQkJREVCMihwcmludGsoS0VSTl9ERUJVRyAiaTJjLWFsZ28tYml0Lm86IHJlYWQgJWQgYnl0ZXMuXG4iLHJldCkpOwoJCQlpZiAocmV0IDwgcG1zZy0+bGVuICkgewoJCQkJcmV0dXJuIChyZXQ8MCk/IHJldCA6IC1FUkVNT1RFSU87CgkJCX0KCQl9IGVsc2UgewoJCQkvKiB3cml0ZSBieXRlcyBmcm9tIGJ1ZmZlciAqLwoJCQlyZXQgPSBzZW5kYnl0ZXMoaTJjX2FkYXAsIHBtc2cpOwoJCQlERUIyKHByaW50ayhLRVJOX0RFQlVHICJpMmMtYWxnby1iaXQubzogd3JvdGUgJWQgYnl0ZXMuXG4iLHJldCkpOwoJCQlpZiAocmV0IDwgcG1zZy0+bGVuICkgewoJCQkJcmV0dXJuIChyZXQ8MCkgPyByZXQgOiAtRVJFTU9URUlPOwoJCQl9CgkJfQoJfQoJaTJjX3N0b3AoYWRhcCk7CglyZXR1cm4gbnVtOwp9CgpzdGF0aWMgdTMyIGJpdF9mdW5jKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCkKewoJcmV0dXJuIEkyQ19GVU5DX0kyQyB8IEkyQ19GVU5DX1NNQlVTX0VNVUwgfCAKCSAgICAgICBJMkNfRlVOQ18xMEJJVF9BRERSIHwgSTJDX0ZVTkNfUFJPVE9DT0xfTUFOR0xJTkc7Cn0KCgovKiAtLS0tLWV4cG9ydGVkIGFsZ29yaXRobSBkYXRhOiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCSovCgpzdGF0aWMgc3RydWN0IGkyY19hbGdvcml0aG0gaTJjX2JpdF9hbGdvID0gewoJLm1hc3Rlcl94ZmVyCT0gYml0X3hmZXIsCgkuZnVuY3Rpb25hbGl0eQk9IGJpdF9mdW5jLAp9OwoKLyogCiAqIHJlZ2lzdGVyaW5nIGZ1bmN0aW9ucyB0byBsb2FkIGFsZ29yaXRobXMgYXQgcnVudGltZSAKICovCmludCBpMmNfYml0X2FkZF9idXMoc3RydWN0IGkyY19hZGFwdGVyICphZGFwKQp7CglzdHJ1Y3QgaTJjX2FsZ29fYml0X2RhdGEgKmJpdF9hZGFwID0gYWRhcC0+YWxnb19kYXRhOwoKCWlmIChiaXRfdGVzdCkgewoJCWludCByZXQgPSB0ZXN0X2J1cyhiaXRfYWRhcCwgYWRhcC0+bmFtZSk7CgkJaWYgKHJldDwwKQoJCQlyZXR1cm4gLUVOT0RFVjsKCX0KCglERUIyKGRldl9kYmcoJmFkYXAtPmRldiwgImh3IHJvdXRpbmVzIHJlZ2lzdGVyZWQuXG4iKSk7CgoJLyogcmVnaXN0ZXIgbmV3IGFkYXB0ZXIgdG8gaTJjIG1vZHVsZS4uLiAqLwoJYWRhcC0+YWxnbyA9ICZpMmNfYml0X2FsZ287CgoJYWRhcC0+dGltZW91dCA9IDEwMDsJLyogZGVmYXVsdCB2YWx1ZXMsIHNob3VsZAkqLwoJYWRhcC0+cmV0cmllcyA9IDM7CS8qIGJlIHJlcGxhY2VkIGJ5IGRlZmluZXMJKi8KCglyZXR1cm4gaTJjX2FkZF9hZGFwdGVyKGFkYXApOwp9CgoKaW50IGkyY19iaXRfZGVsX2J1cyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApCnsKCXJldHVybiBpMmNfZGVsX2FkYXB0ZXIoYWRhcCk7Cn0KCkVYUE9SVF9TWU1CT0woaTJjX2JpdF9hZGRfYnVzKTsKRVhQT1JUX1NZTUJPTChpMmNfYml0X2RlbF9idXMpOwoKTU9EVUxFX0FVVEhPUigiU2ltb24gRy4gVm9nbCA8c2ltb25AdGsudW5pLWxpbnouYWMuYXQ+Iik7Ck1PRFVMRV9ERVNDUklQVElPTigiSTJDLUJ1cyBiaXQtYmFuZ2luZyBhbGdvcml0aG0iKTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwoKbW9kdWxlX3BhcmFtKGJpdF90ZXN0LCBib29sLCAwKTsKbW9kdWxlX3BhcmFtKGkyY19kZWJ1ZywgaW50LCBTX0lSVUdPIHwgU19JV1VTUik7CgpNT0RVTEVfUEFSTV9ERVNDKGJpdF90ZXN0LCAiVGVzdCB0aGUgbGluZXMgb2YgdGhlIGJ1cyB0byBzZWUgaWYgaXQgaXMgc3R1Y2siKTsKTU9EVUxFX1BBUk1fREVTQyhpMmNfZGVidWcsCgkJICJkZWJ1ZyBsZXZlbCAtIDAgb2ZmOyAxIG5vcm1hbDsgMiwzIG1vcmUgdmVyYm9zZTsgOSBiaXQtcHJvdG9jb2wiKTsK