LyogaTJjLWNvcmUuYyAtIGEgZGV2aWNlIGRyaXZlciBmb3IgdGhlIGlpYy1idXMgaW50ZXJmYWNlCQkgICAgICovCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gKi8KLyogICBDb3B5cmlnaHQgKEMpIDE5OTUtOTkgU2ltb24gRy4gVm9nbAoKICAgIFRoaXMgcHJvZ3JhbSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IgbW9kaWZ5CiAgICBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogICAgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24gMiBvZiB0aGUgTGljZW5zZSwgb3IKICAgIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCgogICAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAgICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogICAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KCiAgICBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogICAgYWxvbmcgd2l0aCB0aGlzIHByb2dyYW07IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICAgIEZvdW5kYXRpb24sIEluYy4sIDY3NSBNYXNzIEF2ZSwgQ2FtYnJpZGdlLCBNQSAwMjEzOSwgVVNBLgkJICAgICAqLwovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovCgovKiBXaXRoIHNvbWUgY2hhbmdlcyBmcm9tIEt59nN0aSBN5Gxra2kgPGttYWxra2lAY2MuaHV0LmZpPi4KICAgQWxsIFNNQnVzLXJlbGF0ZWQgdGhpbmdzIGFyZSB3cml0dGVuIGJ5IEZyb2RvIExvb2lqYWFyZCA8ZnJvZG9sQGRkcy5ubD4KICAgU01CdXMgMi4wIHN1cHBvcnQgYnkgTWFyayBTdHVkZWJha2VyIDxtZHN4eXoxMjNAeWFob28uY29tPiBhbmQKICAgSmVhbiBEZWx2YXJlIDxraGFsaUBsaW51eC1mci5vcmc+ICovCgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4KI2luY2x1ZGUgPGxpbnV4L2Vycm5vLmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9pMmMuaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L2lkci5oPgojaW5jbHVkZSA8bGludXgvc2VxX2ZpbGUuaD4KI2luY2x1ZGUgPGxpbnV4L3BsYXRmb3JtX2RldmljZS5oPgojaW5jbHVkZSA8bGludXgvbXV0ZXguaD4KI2luY2x1ZGUgPGFzbS91YWNjZXNzLmg+CgoKc3RhdGljIExJU1RfSEVBRChhZGFwdGVycyk7CnN0YXRpYyBMSVNUX0hFQUQoZHJpdmVycyk7CnN0YXRpYyBERUZJTkVfTVVURVgoY29yZV9saXN0cyk7CnN0YXRpYyBERUZJTkVfSURSKGkyY19hZGFwdGVyX2lkcik7CgovKiBtYXRjaCBhbHdheXMgc3VjY2VlZHMsIGFzIHdlIHdhbnQgdGhlIHByb2JlKCkgdG8gdGVsbCBpZiB3ZSByZWFsbHkgYWNjZXB0IHRoaXMgbWF0Y2ggKi8Kc3RhdGljIGludCBpMmNfZGV2aWNlX21hdGNoKHN0cnVjdCBkZXZpY2UgKmRldiwgc3RydWN0IGRldmljZV9kcml2ZXIgKmRydikKewoJcmV0dXJuIDE7Cn0KCnN0YXRpYyBpbnQgaTJjX2J1c19zdXNwZW5kKHN0cnVjdCBkZXZpY2UgKiBkZXYsIHBtX21lc3NhZ2VfdCBzdGF0ZSkKewoJaW50IHJjID0gMDsKCglpZiAoZGV2LT5kcml2ZXIgJiYgZGV2LT5kcml2ZXItPnN1c3BlbmQpCgkJcmMgPSBkZXYtPmRyaXZlci0+c3VzcGVuZChkZXYsIHN0YXRlKTsKCXJldHVybiByYzsKfQoKc3RhdGljIGludCBpMmNfYnVzX3Jlc3VtZShzdHJ1Y3QgZGV2aWNlICogZGV2KQp7CglpbnQgcmMgPSAwOwoJCglpZiAoZGV2LT5kcml2ZXIgJiYgZGV2LT5kcml2ZXItPnJlc3VtZSkKCQlyYyA9IGRldi0+ZHJpdmVyLT5yZXN1bWUoZGV2KTsKCXJldHVybiByYzsKfQoKc3RhdGljIGludCBpMmNfZGV2aWNlX3Byb2JlKHN0cnVjdCBkZXZpY2UgKmRldikKewoJcmV0dXJuIC1FTk9ERVY7Cn0KCnN0YXRpYyBpbnQgaTJjX2RldmljZV9yZW1vdmUoc3RydWN0IGRldmljZSAqZGV2KQp7CglyZXR1cm4gMDsKfQoKc3RydWN0IGJ1c190eXBlIGkyY19idXNfdHlwZSA9IHsKCS5uYW1lID0JCSJpMmMiLAoJLm1hdGNoID0JaTJjX2RldmljZV9tYXRjaCwKCS5wcm9iZSA9CWkyY19kZXZpY2VfcHJvYmUsCgkucmVtb3ZlID0JaTJjX2RldmljZV9yZW1vdmUsCgkuc3VzcGVuZCA9ICAgICAgaTJjX2J1c19zdXNwZW5kLAoJLnJlc3VtZSA9ICAgICAgIGkyY19idXNfcmVzdW1lLAp9OwoKdm9pZCBpMmNfYWRhcHRlcl9kZXZfcmVsZWFzZShzdHJ1Y3QgZGV2aWNlICpkZXYpCnsKCXN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCA9IGRldl90b19pMmNfYWRhcHRlcihkZXYpOwoJY29tcGxldGUoJmFkYXAtPmRldl9yZWxlYXNlZCk7Cn0KCnN0cnVjdCBkZXZpY2VfZHJpdmVyIGkyY19hZGFwdGVyX2RyaXZlciA9IHsKCS5vd25lciA9IFRISVNfTU9EVUxFLAoJLm5hbWUgPQkiaTJjX2FkYXB0ZXIiLAoJLmJ1cyA9ICZpMmNfYnVzX3R5cGUsCn07CgpzdGF0aWMgdm9pZCBpMmNfYWRhcHRlcl9jbGFzc19kZXZfcmVsZWFzZShzdHJ1Y3QgY2xhc3NfZGV2aWNlICpkZXYpCnsKCXN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCA9IGNsYXNzX2Rldl90b19pMmNfYWRhcHRlcihkZXYpOwoJY29tcGxldGUoJmFkYXAtPmNsYXNzX2Rldl9yZWxlYXNlZCk7Cn0KCnN0cnVjdCBjbGFzcyBpMmNfYWRhcHRlcl9jbGFzcyA9IHsKCS5vd25lciA9CVRISVNfTU9EVUxFLAoJLm5hbWUgPQkJImkyYy1hZGFwdGVyIiwKCS5yZWxlYXNlID0JJmkyY19hZGFwdGVyX2NsYXNzX2Rldl9yZWxlYXNlLAp9OwoKc3RhdGljIHNzaXplX3Qgc2hvd19hZGFwdGVyX25hbWUoc3RydWN0IGRldmljZSAqZGV2LCBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwgY2hhciAqYnVmKQp7CglzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXAgPSBkZXZfdG9faTJjX2FkYXB0ZXIoZGV2KTsKCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiVzXG4iLCBhZGFwLT5uYW1lKTsKfQpzdGF0aWMgREVWSUNFX0FUVFIobmFtZSwgU19JUlVHTywgc2hvd19hZGFwdGVyX25hbWUsIE5VTEwpOwoKCnN0YXRpYyB2b2lkIGkyY19jbGllbnRfcmVsZWFzZShzdHJ1Y3QgZGV2aWNlICpkZXYpCnsKCXN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQgPSB0b19pMmNfY2xpZW50KGRldik7Cgljb21wbGV0ZSgmY2xpZW50LT5yZWxlYXNlZCk7Cn0KCnN0YXRpYyBzc2l6ZV90IHNob3dfY2xpZW50X25hbWUoc3RydWN0IGRldmljZSAqZGV2LCBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwgY2hhciAqYnVmKQp7CglzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50ID0gdG9faTJjX2NsaWVudChkZXYpOwoJcmV0dXJuIHNwcmludGYoYnVmLCAiJXNcbiIsIGNsaWVudC0+bmFtZSk7Cn0KCi8qIAogKiBXZSBjYW4ndCB1c2UgdGhlIERFVklDRV9BVFRSKCkgbWFjcm8gaGVyZSBhcyB3ZSB3YW50IHRoZSBzYW1lIGZpbGVuYW1lIGZvciBhCiAqIGRpZmZlcmVudCB0eXBlIG9mIGEgZGV2aWNlLiAgU28gYmV3YXJlIGlmIHRoZSBERVZJQ0VfQVRUUigpIG1hY3JvIGV2ZXIKICogY2hhbmdlcywgdGhpcyBkZWZpbml0aW9uIHdpbGwgYWxzbyBoYXZlIHRvIGNoYW5nZS4KICovCnN0YXRpYyBzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSBkZXZfYXR0cl9jbGllbnRfbmFtZSA9IHsKCS5hdHRyCT0gey5uYW1lID0gIm5hbWUiLCAubW9kZSA9IFNfSVJVR08sIC5vd25lciA9IFRISVNfTU9EVUxFIH0sCgkuc2hvdwk9ICZzaG93X2NsaWVudF9uYW1lLAp9OwoKCi8qIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiByZWdpc3RlcmluZyBmdW5jdGlvbnMgCiAqIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSAKICovCgovKiAtLS0tLQogKiBpMmNfYWRkX2FkYXB0ZXIgaXMgY2FsbGVkIGZyb20gd2l0aGluIHRoZSBhbGdvcml0aG0gbGF5ZXIsCiAqIHdoZW4gYSBuZXcgaHcgYWRhcHRlciByZWdpc3RlcnMuIEEgbmV3IGRldmljZSBpcyByZWdpc3RlciB0byBiZQogKiBhdmFpbGFibGUgZm9yIGNsaWVudHMuCiAqLwppbnQgaTJjX2FkZF9hZGFwdGVyKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCkKewoJaW50IGlkLCByZXMgPSAwOwoJc3RydWN0IGxpc3RfaGVhZCAgICppdGVtOwoJc3RydWN0IGkyY19kcml2ZXIgICpkcml2ZXI7CgoJbXV0ZXhfbG9jaygmY29yZV9saXN0cyk7CgoJaWYgKGlkcl9wcmVfZ2V0KCZpMmNfYWRhcHRlcl9pZHIsIEdGUF9LRVJORUwpID09IDApIHsKCQlyZXMgPSAtRU5PTUVNOwoJCWdvdG8gb3V0X3VubG9jazsKCX0KCglyZXMgPSBpZHJfZ2V0X25ldygmaTJjX2FkYXB0ZXJfaWRyLCBhZGFwLCAmaWQpOwoJaWYgKHJlcyA8IDApIHsKCQlpZiAocmVzID09IC1FQUdBSU4pCgkJCXJlcyA9IC1FTk9NRU07CgkJZ290byBvdXRfdW5sb2NrOwoJfQoKCWFkYXAtPm5yID0gIGlkICYgTUFYX0lEX01BU0s7CgltdXRleF9pbml0KCZhZGFwLT5idXNfbG9jayk7CgltdXRleF9pbml0KCZhZGFwLT5jbGlzdF9sb2NrKTsKCWxpc3RfYWRkX3RhaWwoJmFkYXAtPmxpc3QsJmFkYXB0ZXJzKTsKCUlOSVRfTElTVF9IRUFEKCZhZGFwLT5jbGllbnRzKTsKCgkvKiBBZGQgdGhlIGFkYXB0ZXIgdG8gdGhlIGRyaXZlciBjb3JlLgoJICogSWYgdGhlIHBhcmVudCBwb2ludGVyIGlzIG5vdCBzZXQgdXAsCgkgKiB3ZSBhZGQgdGhpcyBhZGFwdGVyIHRvIHRoZSBob3N0IGJ1cy4KCSAqLwoJaWYgKGFkYXAtPmRldi5wYXJlbnQgPT0gTlVMTCkKCQlhZGFwLT5kZXYucGFyZW50ID0gJnBsYXRmb3JtX2J1czsKCXNwcmludGYoYWRhcC0+ZGV2LmJ1c19pZCwgImkyYy0lZCIsIGFkYXAtPm5yKTsKCWFkYXAtPmRldi5kcml2ZXIgPSAmaTJjX2FkYXB0ZXJfZHJpdmVyOwoJYWRhcC0+ZGV2LnJlbGVhc2UgPSAmaTJjX2FkYXB0ZXJfZGV2X3JlbGVhc2U7CglkZXZpY2VfcmVnaXN0ZXIoJmFkYXAtPmRldik7CglkZXZpY2VfY3JlYXRlX2ZpbGUoJmFkYXAtPmRldiwgJmRldl9hdHRyX25hbWUpOwoKCS8qIEFkZCB0aGlzIGFkYXB0ZXIgdG8gdGhlIGkyY19hZGFwdGVyIGNsYXNzICovCgltZW1zZXQoJmFkYXAtPmNsYXNzX2RldiwgMHgwMCwgc2l6ZW9mKHN0cnVjdCBjbGFzc19kZXZpY2UpKTsKCWFkYXAtPmNsYXNzX2Rldi5kZXYgPSAmYWRhcC0+ZGV2OwoJYWRhcC0+Y2xhc3NfZGV2LmNsYXNzID0gJmkyY19hZGFwdGVyX2NsYXNzOwoJc3RybGNweShhZGFwLT5jbGFzc19kZXYuY2xhc3NfaWQsIGFkYXAtPmRldi5idXNfaWQsIEJVU19JRF9TSVpFKTsKCWNsYXNzX2RldmljZV9yZWdpc3RlcigmYWRhcC0+Y2xhc3NfZGV2KTsKCglkZXZfZGJnKCZhZGFwLT5kZXYsICJhZGFwdGVyIFslc10gcmVnaXN0ZXJlZFxuIiwgYWRhcC0+bmFtZSk7CgoJLyogaW5mb3JtIGRyaXZlcnMgb2YgbmV3IGFkYXB0ZXJzICovCglsaXN0X2Zvcl9lYWNoKGl0ZW0sJmRyaXZlcnMpIHsKCQlkcml2ZXIgPSBsaXN0X2VudHJ5KGl0ZW0sIHN0cnVjdCBpMmNfZHJpdmVyLCBsaXN0KTsKCQlpZiAoZHJpdmVyLT5hdHRhY2hfYWRhcHRlcikKCQkJLyogV2UgaWdub3JlIHRoZSByZXR1cm4gY29kZTsgaWYgaXQgZmFpbHMsIHRvbyBiYWQgKi8KCQkJZHJpdmVyLT5hdHRhY2hfYWRhcHRlcihhZGFwKTsKCX0KCm91dF91bmxvY2s6CgltdXRleF91bmxvY2soJmNvcmVfbGlzdHMpOwoJcmV0dXJuIHJlczsKfQoKCmludCBpMmNfZGVsX2FkYXB0ZXIoc3RydWN0IGkyY19hZGFwdGVyICphZGFwKQp7CglzdHJ1Y3QgbGlzdF9oZWFkICAqaXRlbSwgKl9uOwoJc3RydWN0IGkyY19hZGFwdGVyICphZGFwX2Zyb21fbGlzdDsKCXN0cnVjdCBpMmNfZHJpdmVyICpkcml2ZXI7CglzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50OwoJaW50IHJlcyA9IDA7CgoJbXV0ZXhfbG9jaygmY29yZV9saXN0cyk7CgoJLyogRmlyc3QgbWFrZSBzdXJlIHRoYXQgdGhpcyBhZGFwdGVyIHdhcyBldmVyIGFkZGVkICovCglsaXN0X2Zvcl9lYWNoX2VudHJ5KGFkYXBfZnJvbV9saXN0LCAmYWRhcHRlcnMsIGxpc3QpIHsKCQlpZiAoYWRhcF9mcm9tX2xpc3QgPT0gYWRhcCkKCQkJYnJlYWs7Cgl9CglpZiAoYWRhcF9mcm9tX2xpc3QgIT0gYWRhcCkgewoJCXByX2RlYnVnKCJpMmMtY29yZTogYXR0ZW1wdGluZyB0byBkZWxldGUgdW5yZWdpc3RlcmVkICIKCQkJICJhZGFwdGVyIFslc11cbiIsIGFkYXAtPm5hbWUpOwoJCXJlcyA9IC1FSU5WQUw7CgkJZ290byBvdXRfdW5sb2NrOwoJfQoKCWxpc3RfZm9yX2VhY2goaXRlbSwmZHJpdmVycykgewoJCWRyaXZlciA9IGxpc3RfZW50cnkoaXRlbSwgc3RydWN0IGkyY19kcml2ZXIsIGxpc3QpOwoJCWlmIChkcml2ZXItPmRldGFjaF9hZGFwdGVyKQoJCQlpZiAoKHJlcyA9IGRyaXZlci0+ZGV0YWNoX2FkYXB0ZXIoYWRhcCkpKSB7CgkJCQlkZXZfZXJyKCZhZGFwLT5kZXYsICJkZXRhY2hfYWRhcHRlciBmYWlsZWQgIgoJCQkJCSJmb3IgZHJpdmVyIFslc11cbiIsCgkJCQkJZHJpdmVyLT5kcml2ZXIubmFtZSk7CgkJCQlnb3RvIG91dF91bmxvY2s7CgkJCX0KCX0KCgkvKiBkZXRhY2ggYW55IGFjdGl2ZSBjbGllbnRzLiBUaGlzIG11c3QgYmUgZG9uZSBmaXJzdCwgYmVjYXVzZQoJICogaXQgY2FuIGZhaWw7IGluIHdoaWNoIGNhc2Ugd2UgZ2l2ZSB1cC4gKi8KCWxpc3RfZm9yX2VhY2hfc2FmZShpdGVtLCBfbiwgJmFkYXAtPmNsaWVudHMpIHsKCQljbGllbnQgPSBsaXN0X2VudHJ5KGl0ZW0sIHN0cnVjdCBpMmNfY2xpZW50LCBsaXN0KTsKCgkJaWYgKChyZXM9Y2xpZW50LT5kcml2ZXItPmRldGFjaF9jbGllbnQoY2xpZW50KSkpIHsKCQkJZGV2X2VycigmYWRhcC0+ZGV2LCAiZGV0YWNoX2NsaWVudCBmYWlsZWQgZm9yIGNsaWVudCAiCgkJCQkiWyVzXSBhdCBhZGRyZXNzIDB4JTAyeFxuIiwgY2xpZW50LT5uYW1lLAoJCQkJY2xpZW50LT5hZGRyKTsKCQkJZ290byBvdXRfdW5sb2NrOwoJCX0KCX0KCgkvKiBjbGVhbiB1cCB0aGUgc3lzZnMgcmVwcmVzZW50YXRpb24gKi8KCWluaXRfY29tcGxldGlvbigmYWRhcC0+ZGV2X3JlbGVhc2VkKTsKCWluaXRfY29tcGxldGlvbigmYWRhcC0+Y2xhc3NfZGV2X3JlbGVhc2VkKTsKCWNsYXNzX2RldmljZV91bnJlZ2lzdGVyKCZhZGFwLT5jbGFzc19kZXYpOwoJZGV2aWNlX3JlbW92ZV9maWxlKCZhZGFwLT5kZXYsICZkZXZfYXR0cl9uYW1lKTsKCWRldmljZV91bnJlZ2lzdGVyKCZhZGFwLT5kZXYpOwoJbGlzdF9kZWwoJmFkYXAtPmxpc3QpOwoKCS8qIHdhaXQgZm9yIHN5c2ZzIHRvIGRyb3AgYWxsIHJlZmVyZW5jZXMgKi8KCXdhaXRfZm9yX2NvbXBsZXRpb24oJmFkYXAtPmRldl9yZWxlYXNlZCk7Cgl3YWl0X2Zvcl9jb21wbGV0aW9uKCZhZGFwLT5jbGFzc19kZXZfcmVsZWFzZWQpOwoKCS8qIGZyZWUgZHluYW1pY2FsbHkgYWxsb2NhdGVkIGJ1cyBpZCAqLwoJaWRyX3JlbW92ZSgmaTJjX2FkYXB0ZXJfaWRyLCBhZGFwLT5ucik7CgoJZGV2X2RiZygmYWRhcC0+ZGV2LCAiYWRhcHRlciBbJXNdIHVucmVnaXN0ZXJlZFxuIiwgYWRhcC0+bmFtZSk7Cgogb3V0X3VubG9jazoKCW11dGV4X3VubG9jaygmY29yZV9saXN0cyk7CglyZXR1cm4gcmVzOwp9CgoKLyogLS0tLS0KICogV2hhdCBmb2xsb3dzIGlzIHRoZSAidXB3YXJkcyIgaW50ZXJmYWNlOiBjb21tYW5kcyBmb3IgdGFsa2luZyB0byBjbGllbnRzLAogKiB3aGljaCBpbXBsZW1lbnQgdGhlIGZ1bmN0aW9ucyB0byBhY2Nlc3MgdGhlIHBoeXNpY2FsIGluZm9ybWF0aW9uIG9mIHRoZQogKiBjaGlwcy4KICovCgppbnQgaTJjX3JlZ2lzdGVyX2RyaXZlcihzdHJ1Y3QgbW9kdWxlICpvd25lciwgc3RydWN0IGkyY19kcml2ZXIgKmRyaXZlcikKewoJc3RydWN0IGxpc3RfaGVhZCAgICppdGVtOwoJc3RydWN0IGkyY19hZGFwdGVyICphZGFwdGVyOwoJaW50IHJlczsKCgkvKiBhZGQgdGhlIGRyaXZlciB0byB0aGUgbGlzdCBvZiBpMmMgZHJpdmVycyBpbiB0aGUgZHJpdmVyIGNvcmUgKi8KCWRyaXZlci0+ZHJpdmVyLm93bmVyID0gb3duZXI7Cglkcml2ZXItPmRyaXZlci5idXMgPSAmaTJjX2J1c190eXBlOwoKCXJlcyA9IGRyaXZlcl9yZWdpc3RlcigmZHJpdmVyLT5kcml2ZXIpOwoJaWYgKHJlcykKCQlyZXR1cm4gcmVzOwoJCgltdXRleF9sb2NrKCZjb3JlX2xpc3RzKTsKCglsaXN0X2FkZF90YWlsKCZkcml2ZXItPmxpc3QsJmRyaXZlcnMpOwoJcHJfZGVidWcoImkyYy1jb3JlOiBkcml2ZXIgWyVzXSByZWdpc3RlcmVkXG4iLCBkcml2ZXItPmRyaXZlci5uYW1lKTsKCgkvKiBub3cgbG9vayBmb3IgaW5zdGFuY2VzIG9mIGRyaXZlciBvbiBvdXIgYWRhcHRlcnMgKi8KCWlmIChkcml2ZXItPmF0dGFjaF9hZGFwdGVyKSB7CgkJbGlzdF9mb3JfZWFjaChpdGVtLCZhZGFwdGVycykgewoJCQlhZGFwdGVyID0gbGlzdF9lbnRyeShpdGVtLCBzdHJ1Y3QgaTJjX2FkYXB0ZXIsIGxpc3QpOwoJCQlkcml2ZXItPmF0dGFjaF9hZGFwdGVyKGFkYXB0ZXIpOwoJCX0KCX0KCgltdXRleF91bmxvY2soJmNvcmVfbGlzdHMpOwoJcmV0dXJuIDA7Cn0KRVhQT1JUX1NZTUJPTChpMmNfcmVnaXN0ZXJfZHJpdmVyKTsKCmludCBpMmNfZGVsX2RyaXZlcihzdHJ1Y3QgaTJjX2RyaXZlciAqZHJpdmVyKQp7CglzdHJ1Y3QgbGlzdF9oZWFkICAgKml0ZW0xLCAqaXRlbTIsICpfbjsKCXN0cnVjdCBpMmNfY2xpZW50ICAqY2xpZW50OwoJc3RydWN0IGkyY19hZGFwdGVyICphZGFwOwoJCglpbnQgcmVzID0gMDsKCgltdXRleF9sb2NrKCZjb3JlX2xpc3RzKTsKCgkvKiBIYXZlIGEgbG9vayBhdCBlYWNoIGFkYXB0ZXIsIGlmIGNsaWVudHMgb2YgdGhpcyBkcml2ZXIgYXJlIHN0aWxsCgkgKiBhdHRhY2hlZC4gSWYgc28sIGRldGFjaCB0aGVtIHRvIGJlIGFibGUgdG8ga2lsbCB0aGUgZHJpdmVyIAoJICogYWZ0ZXJ3YXJkcy4KCSAqLwoJbGlzdF9mb3JfZWFjaChpdGVtMSwmYWRhcHRlcnMpIHsKCQlhZGFwID0gbGlzdF9lbnRyeShpdGVtMSwgc3RydWN0IGkyY19hZGFwdGVyLCBsaXN0KTsKCQlpZiAoZHJpdmVyLT5kZXRhY2hfYWRhcHRlcikgewoJCQlpZiAoKHJlcyA9IGRyaXZlci0+ZGV0YWNoX2FkYXB0ZXIoYWRhcCkpKSB7CgkJCQlkZXZfZXJyKCZhZGFwLT5kZXYsICJkZXRhY2hfYWRhcHRlciBmYWlsZWQgIgoJCQkJCSJmb3IgZHJpdmVyIFslc11cbiIsCgkJCQkJZHJpdmVyLT5kcml2ZXIubmFtZSk7CgkJCQlnb3RvIG91dF91bmxvY2s7CgkJCX0KCQl9IGVsc2UgewoJCQlsaXN0X2Zvcl9lYWNoX3NhZmUoaXRlbTIsIF9uLCAmYWRhcC0+Y2xpZW50cykgewoJCQkJY2xpZW50ID0gbGlzdF9lbnRyeShpdGVtMiwgc3RydWN0IGkyY19jbGllbnQsIGxpc3QpOwoJCQkJaWYgKGNsaWVudC0+ZHJpdmVyICE9IGRyaXZlcikKCQkJCQljb250aW51ZTsKCQkJCWRldl9kYmcoJmFkYXAtPmRldiwgImRldGFjaGluZyBjbGllbnQgWyVzXSAiCgkJCQkJImF0IDB4JTAyeFxuIiwgY2xpZW50LT5uYW1lLAoJCQkJCWNsaWVudC0+YWRkcik7CgkJCQlpZiAoKHJlcyA9IGRyaXZlci0+ZGV0YWNoX2NsaWVudChjbGllbnQpKSkgewoJCQkJCWRldl9lcnIoJmFkYXAtPmRldiwgImRldGFjaF9jbGllbnQgIgoJCQkJCQkiZmFpbGVkIGZvciBjbGllbnQgWyVzXSBhdCAiCgkJCQkJCSIweCUwMnhcbiIsIGNsaWVudC0+bmFtZSwKCQkJCQkJY2xpZW50LT5hZGRyKTsKCQkJCQlnb3RvIG91dF91bmxvY2s7CgkJCQl9CgkJCX0KCQl9Cgl9CgoJZHJpdmVyX3VucmVnaXN0ZXIoJmRyaXZlci0+ZHJpdmVyKTsKCWxpc3RfZGVsKCZkcml2ZXItPmxpc3QpOwoJcHJfZGVidWcoImkyYy1jb3JlOiBkcml2ZXIgWyVzXSB1bnJlZ2lzdGVyZWRcbiIsIGRyaXZlci0+ZHJpdmVyLm5hbWUpOwoKIG91dF91bmxvY2s6CgltdXRleF91bmxvY2soJmNvcmVfbGlzdHMpOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgX19pMmNfY2hlY2tfYWRkcihzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXB0ZXIsIHVuc2lnbmVkIGludCBhZGRyKQp7CglzdHJ1Y3QgbGlzdF9oZWFkICAgKml0ZW07CglzdHJ1Y3QgaTJjX2NsaWVudCAgKmNsaWVudDsKCglsaXN0X2Zvcl9lYWNoKGl0ZW0sJmFkYXB0ZXItPmNsaWVudHMpIHsKCQljbGllbnQgPSBsaXN0X2VudHJ5KGl0ZW0sIHN0cnVjdCBpMmNfY2xpZW50LCBsaXN0KTsKCQlpZiAoY2xpZW50LT5hZGRyID09IGFkZHIpCgkJCXJldHVybiAtRUJVU1k7Cgl9CglyZXR1cm4gMDsKfQoKaW50IGkyY19jaGVja19hZGRyKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcHRlciwgaW50IGFkZHIpCnsKCWludCBydmFsOwoKCW11dGV4X2xvY2soJmFkYXB0ZXItPmNsaXN0X2xvY2spOwoJcnZhbCA9IF9faTJjX2NoZWNrX2FkZHIoYWRhcHRlciwgYWRkcik7CgltdXRleF91bmxvY2soJmFkYXB0ZXItPmNsaXN0X2xvY2spOwoKCXJldHVybiBydmFsOwp9CgppbnQgaTJjX2F0dGFjaF9jbGllbnQoc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCkKewoJc3RydWN0IGkyY19hZGFwdGVyICphZGFwdGVyID0gY2xpZW50LT5hZGFwdGVyOwoKCW11dGV4X2xvY2soJmFkYXB0ZXItPmNsaXN0X2xvY2spOwoJaWYgKF9faTJjX2NoZWNrX2FkZHIoY2xpZW50LT5hZGFwdGVyLCBjbGllbnQtPmFkZHIpKSB7CgkJbXV0ZXhfdW5sb2NrKCZhZGFwdGVyLT5jbGlzdF9sb2NrKTsKCQlyZXR1cm4gLUVCVVNZOwoJfQoJbGlzdF9hZGRfdGFpbCgmY2xpZW50LT5saXN0LCZhZGFwdGVyLT5jbGllbnRzKTsKCW11dGV4X3VubG9jaygmYWRhcHRlci0+Y2xpc3RfbG9jayk7CgkKCWlmIChhZGFwdGVyLT5jbGllbnRfcmVnaXN0ZXIpICB7CgkJaWYgKGFkYXB0ZXItPmNsaWVudF9yZWdpc3RlcihjbGllbnQpKSAgewoJCQlkZXZfZGJnKCZhZGFwdGVyLT5kZXYsICJjbGllbnRfcmVnaXN0ZXIgIgoJCQkJImZhaWxlZCBmb3IgY2xpZW50IFslc10gYXQgMHglMDJ4XG4iLAoJCQkJY2xpZW50LT5uYW1lLCBjbGllbnQtPmFkZHIpOwoJCX0KCX0KCgljbGllbnQtPnVzYWdlX2NvdW50ID0gMDsKCgljbGllbnQtPmRldi5wYXJlbnQgPSAmY2xpZW50LT5hZGFwdGVyLT5kZXY7CgljbGllbnQtPmRldi5kcml2ZXIgPSAmY2xpZW50LT5kcml2ZXItPmRyaXZlcjsKCWNsaWVudC0+ZGV2LmJ1cyA9ICZpMmNfYnVzX3R5cGU7CgljbGllbnQtPmRldi5yZWxlYXNlID0gJmkyY19jbGllbnRfcmVsZWFzZTsKCQoJc25wcmludGYoJmNsaWVudC0+ZGV2LmJ1c19pZFswXSwgc2l6ZW9mKGNsaWVudC0+ZGV2LmJ1c19pZCksCgkJIiVkLSUwNHgiLCBpMmNfYWRhcHRlcl9pZChhZGFwdGVyKSwgY2xpZW50LT5hZGRyKTsKCWRldl9kYmcoJmFkYXB0ZXItPmRldiwgImNsaWVudCBbJXNdIHJlZ2lzdGVyZWQgd2l0aCBidXMgaWQgJXNcbiIsCgkJY2xpZW50LT5uYW1lLCBjbGllbnQtPmRldi5idXNfaWQpOwoJZGV2aWNlX3JlZ2lzdGVyKCZjbGllbnQtPmRldik7CglkZXZpY2VfY3JlYXRlX2ZpbGUoJmNsaWVudC0+ZGV2LCAmZGV2X2F0dHJfY2xpZW50X25hbWUpOwoJCglyZXR1cm4gMDsKfQoKCmludCBpMmNfZGV0YWNoX2NsaWVudChzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50KQp7CglzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXB0ZXIgPSBjbGllbnQtPmFkYXB0ZXI7CglpbnQgcmVzID0gMDsKCQoJaWYgKGNsaWVudC0+dXNhZ2VfY291bnQgPiAwKSB7CgkJZGV2X3dhcm4oJmNsaWVudC0+ZGV2LCAiQ2xpZW50IFslc10gc3RpbGwgYnVzeSwgIgoJCQkgImNhbid0IGRldGFjaFxuIiwgY2xpZW50LT5uYW1lKTsKCQlyZXR1cm4gLUVCVVNZOwoJfQoKCWlmIChhZGFwdGVyLT5jbGllbnRfdW5yZWdpc3RlcikgIHsKCQlyZXMgPSBhZGFwdGVyLT5jbGllbnRfdW5yZWdpc3RlcihjbGllbnQpOwoJCWlmIChyZXMpIHsKCQkJZGV2X2VycigmY2xpZW50LT5kZXYsCgkJCQkiY2xpZW50X3VucmVnaXN0ZXIgWyVzXSBmYWlsZWQsICIKCQkJCSJjbGllbnQgbm90IGRldGFjaGVkXG4iLCBjbGllbnQtPm5hbWUpOwoJCQlnb3RvIG91dDsKCQl9Cgl9CgoJbXV0ZXhfbG9jaygmYWRhcHRlci0+Y2xpc3RfbG9jayk7CglsaXN0X2RlbCgmY2xpZW50LT5saXN0KTsKCWluaXRfY29tcGxldGlvbigmY2xpZW50LT5yZWxlYXNlZCk7CglkZXZpY2VfcmVtb3ZlX2ZpbGUoJmNsaWVudC0+ZGV2LCAmZGV2X2F0dHJfY2xpZW50X25hbWUpOwoJZGV2aWNlX3VucmVnaXN0ZXIoJmNsaWVudC0+ZGV2KTsKCW11dGV4X3VubG9jaygmYWRhcHRlci0+Y2xpc3RfbG9jayk7Cgl3YWl0X2Zvcl9jb21wbGV0aW9uKCZjbGllbnQtPnJlbGVhc2VkKTsKCiBvdXQ6CglyZXR1cm4gcmVzOwp9CgpzdGF0aWMgaW50IGkyY19pbmNfdXNlX2NsaWVudChzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50KQp7CgoJaWYgKCF0cnlfbW9kdWxlX2dldChjbGllbnQtPmRyaXZlci0+ZHJpdmVyLm93bmVyKSkKCQlyZXR1cm4gLUVOT0RFVjsKCWlmICghdHJ5X21vZHVsZV9nZXQoY2xpZW50LT5hZGFwdGVyLT5vd25lcikpIHsKCQltb2R1bGVfcHV0KGNsaWVudC0+ZHJpdmVyLT5kcml2ZXIub3duZXIpOwoJCXJldHVybiAtRU5PREVWOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBpMmNfZGVjX3VzZV9jbGllbnQoc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCkKewoJbW9kdWxlX3B1dChjbGllbnQtPmRyaXZlci0+ZHJpdmVyLm93bmVyKTsKCW1vZHVsZV9wdXQoY2xpZW50LT5hZGFwdGVyLT5vd25lcik7Cn0KCmludCBpMmNfdXNlX2NsaWVudChzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50KQp7CglpbnQgcmV0OwoKCXJldCA9IGkyY19pbmNfdXNlX2NsaWVudChjbGllbnQpOwoJaWYgKHJldCkKCQlyZXR1cm4gcmV0OwoKCWNsaWVudC0+dXNhZ2VfY291bnQrKzsKCglyZXR1cm4gMDsKfQoKaW50IGkyY19yZWxlYXNlX2NsaWVudChzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50KQp7CglpZiAoIWNsaWVudC0+dXNhZ2VfY291bnQpIHsKCQlwcl9kZWJ1ZygiaTJjLWNvcmU6ICVzIHVzZWQgb25lIHRvbyBtYW55IHRpbWVzXG4iLAoJCQkgX19GVU5DVElPTl9fKTsKCQlyZXR1cm4gLUVQRVJNOwoJfQoJCgljbGllbnQtPnVzYWdlX2NvdW50LS07CglpMmNfZGVjX3VzZV9jbGllbnQoY2xpZW50KTsKCQoJcmV0dXJuIDA7Cn0KCnZvaWQgaTJjX2NsaWVudHNfY29tbWFuZChzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXAsIHVuc2lnbmVkIGludCBjbWQsIHZvaWQgKmFyZykKewoJc3RydWN0IGxpc3RfaGVhZCAgKml0ZW07CglzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50OwoKCW11dGV4X2xvY2soJmFkYXAtPmNsaXN0X2xvY2spOwoJbGlzdF9mb3JfZWFjaChpdGVtLCZhZGFwLT5jbGllbnRzKSB7CgkJY2xpZW50ID0gbGlzdF9lbnRyeShpdGVtLCBzdHJ1Y3QgaTJjX2NsaWVudCwgbGlzdCk7CgkJaWYgKCF0cnlfbW9kdWxlX2dldChjbGllbnQtPmRyaXZlci0+ZHJpdmVyLm93bmVyKSkKCQkJY29udGludWU7CgkJaWYgKE5VTEwgIT0gY2xpZW50LT5kcml2ZXItPmNvbW1hbmQpIHsKCQkJbXV0ZXhfdW5sb2NrKCZhZGFwLT5jbGlzdF9sb2NrKTsKCQkJY2xpZW50LT5kcml2ZXItPmNvbW1hbmQoY2xpZW50LGNtZCxhcmcpOwoJCQltdXRleF9sb2NrKCZhZGFwLT5jbGlzdF9sb2NrKTsKCQl9CgkJbW9kdWxlX3B1dChjbGllbnQtPmRyaXZlci0+ZHJpdmVyLm93bmVyKTsKICAgICAgIH0KICAgICAgIG11dGV4X3VubG9jaygmYWRhcC0+Y2xpc3RfbG9jayk7Cn0KCnN0YXRpYyBpbnQgX19pbml0IGkyY19pbml0KHZvaWQpCnsKCWludCByZXR2YWw7CgoJcmV0dmFsID0gYnVzX3JlZ2lzdGVyKCZpMmNfYnVzX3R5cGUpOwoJaWYgKHJldHZhbCkKCQlyZXR1cm4gcmV0dmFsOwoJcmV0dmFsID0gZHJpdmVyX3JlZ2lzdGVyKCZpMmNfYWRhcHRlcl9kcml2ZXIpOwoJaWYgKHJldHZhbCkKCQlyZXR1cm4gcmV0dmFsOwoJcmV0dXJuIGNsYXNzX3JlZ2lzdGVyKCZpMmNfYWRhcHRlcl9jbGFzcyk7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBpMmNfZXhpdCh2b2lkKQp7CgljbGFzc191bnJlZ2lzdGVyKCZpMmNfYWRhcHRlcl9jbGFzcyk7Cglkcml2ZXJfdW5yZWdpc3RlcigmaTJjX2FkYXB0ZXJfZHJpdmVyKTsKCWJ1c191bnJlZ2lzdGVyKCZpMmNfYnVzX3R5cGUpOwp9CgpzdWJzeXNfaW5pdGNhbGwoaTJjX2luaXQpOwptb2R1bGVfZXhpdChpMmNfZXhpdCk7CgovKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIHRoZSBmdW5jdGlvbmFsIGludGVyZmFjZSB0byB0aGUgaTJjIGJ1c3Nlcy4KICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8KCmludCBpMmNfdHJhbnNmZXIoc3RydWN0IGkyY19hZGFwdGVyICogYWRhcCwgc3RydWN0IGkyY19tc2cgKm1zZ3MsIGludCBudW0pCnsKCWludCByZXQ7CgoJaWYgKGFkYXAtPmFsZ28tPm1hc3Rlcl94ZmVyKSB7CiNpZmRlZiBERUJVRwoJCWZvciAocmV0ID0gMDsgcmV0IDwgbnVtOyByZXQrKykgewoJCQlkZXZfZGJnKCZhZGFwLT5kZXYsICJtYXN0ZXJfeGZlclslZF0gJWMsIGFkZHI9MHglMDJ4LCAiCgkJCQkibGVuPSVkXG4iLCByZXQsIG1zZ3NbcmV0XS5mbGFncyAmIEkyQ19NX1JEID8KCQkJCSdSJyA6ICdXJywgbXNnc1tyZXRdLmFkZHIsIG1zZ3NbcmV0XS5sZW4pOwoJCX0KI2VuZGlmCgoJCW11dGV4X2xvY2soJmFkYXAtPmJ1c19sb2NrKTsKCQlyZXQgPSBhZGFwLT5hbGdvLT5tYXN0ZXJfeGZlcihhZGFwLG1zZ3MsbnVtKTsKCQltdXRleF91bmxvY2soJmFkYXAtPmJ1c19sb2NrKTsKCgkJcmV0dXJuIHJldDsKCX0gZWxzZSB7CgkJZGV2X2RiZygmYWRhcC0+ZGV2LCAiSTJDIGxldmVsIHRyYW5zZmVycyBub3Qgc3VwcG9ydGVkXG4iKTsKCQlyZXR1cm4gLUVOT1NZUzsKCX0KfQoKaW50IGkyY19tYXN0ZXJfc2VuZChzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LGNvbnN0IGNoYXIgKmJ1ZiAsaW50IGNvdW50KQp7CglpbnQgcmV0OwoJc3RydWN0IGkyY19hZGFwdGVyICphZGFwPWNsaWVudC0+YWRhcHRlcjsKCXN0cnVjdCBpMmNfbXNnIG1zZzsKCgltc2cuYWRkciA9IGNsaWVudC0+YWRkcjsKCW1zZy5mbGFncyA9IGNsaWVudC0+ZmxhZ3MgJiBJMkNfTV9URU47Cgltc2cubGVuID0gY291bnQ7Cgltc2cuYnVmID0gKGNoYXIgKilidWY7CgkKCXJldCA9IGkyY190cmFuc2ZlcihhZGFwLCAmbXNnLCAxKTsKCgkvKiBJZiBldmVyeXRoaW5nIHdlbnQgb2sgKGkuZS4gMSBtc2cgdHJhbnNtaXR0ZWQpLCByZXR1cm4gI2J5dGVzCgkgICB0cmFuc21pdHRlZCwgZWxzZSBlcnJvciBjb2RlLiAqLwoJcmV0dXJuIChyZXQgPT0gMSkgPyBjb3VudCA6IHJldDsKfQoKaW50IGkyY19tYXN0ZXJfcmVjdihzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LCBjaGFyICpidWYgLGludCBjb3VudCkKewoJc3RydWN0IGkyY19hZGFwdGVyICphZGFwPWNsaWVudC0+YWRhcHRlcjsKCXN0cnVjdCBpMmNfbXNnIG1zZzsKCWludCByZXQ7CgoJbXNnLmFkZHIgPSBjbGllbnQtPmFkZHI7Cgltc2cuZmxhZ3MgPSBjbGllbnQtPmZsYWdzICYgSTJDX01fVEVOOwoJbXNnLmZsYWdzIHw9IEkyQ19NX1JEOwoJbXNnLmxlbiA9IGNvdW50OwoJbXNnLmJ1ZiA9IGJ1ZjsKCglyZXQgPSBpMmNfdHJhbnNmZXIoYWRhcCwgJm1zZywgMSk7CgoJLyogSWYgZXZlcnl0aGluZyB3ZW50IG9rIChpLmUuIDEgbXNnIHRyYW5zbWl0dGVkKSwgcmV0dXJuICNieXRlcwoJICAgdHJhbnNtaXR0ZWQsIGVsc2UgZXJyb3IgY29kZS4gKi8KCXJldHVybiAocmV0ID09IDEpID8gY291bnQgOiByZXQ7Cn0KCgppbnQgaTJjX2NvbnRyb2woc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCwKCXVuc2lnbmVkIGludCBjbWQsIHVuc2lnbmVkIGxvbmcgYXJnKQp7CglpbnQgcmV0ID0gMDsKCXN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcCA9IGNsaWVudC0+YWRhcHRlcjsKCglkZXZfZGJnKCZjbGllbnQtPmFkYXB0ZXItPmRldiwgImkyYyBpb2N0bCwgY21kOiAweCV4LCBhcmc6ICUjbHhcbiIsIGNtZCwgYXJnKTsKCXN3aXRjaCAoY21kKSB7CgkJY2FzZSBJMkNfUkVUUklFUzoKCQkJYWRhcC0+cmV0cmllcyA9IGFyZzsKCQkJYnJlYWs7CgkJY2FzZSBJMkNfVElNRU9VVDoKCQkJYWRhcC0+dGltZW91dCA9IGFyZzsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJaWYgKGFkYXAtPmFsZ28tPmFsZ29fY29udHJvbCE9TlVMTCkKCQkJCXJldCA9IGFkYXAtPmFsZ28tPmFsZ29fY29udHJvbChhZGFwLGNtZCxhcmcpOwoJfQoJcmV0dXJuIHJldDsKfQoKLyogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKiB0aGUgaTJjIGFkZHJlc3Mgc2Nhbm5pbmcgZnVuY3Rpb24KICogV2lsbCBub3Qgd29yayBmb3IgMTAtYml0IGFkZHJlc3NlcyEKICogLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQogKi8Kc3RhdGljIGludCBpMmNfcHJvYmVfYWRkcmVzcyhzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXB0ZXIsIGludCBhZGRyLCBpbnQga2luZCwKCQkJICAgICBpbnQgKCpmb3VuZF9wcm9jKSAoc3RydWN0IGkyY19hZGFwdGVyICosIGludCwgaW50KSkKewoJaW50IGVycjsKCgkvKiBNYWtlIHN1cmUgdGhlIGFkZHJlc3MgaXMgdmFsaWQgKi8KCWlmIChhZGRyIDwgMHgwMyB8fCBhZGRyID4gMHg3NykgewoJCWRldl93YXJuKCZhZGFwdGVyLT5kZXYsICJJbnZhbGlkIHByb2JlIGFkZHJlc3MgMHglMDJ4XG4iLAoJCQkgYWRkcik7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9CgoJLyogU2tpcCBpZiBhbHJlYWR5IGluIHVzZSAqLwoJaWYgKGkyY19jaGVja19hZGRyKGFkYXB0ZXIsIGFkZHIpKQoJCXJldHVybiAwOwoKCS8qIE1ha2Ugc3VyZSB0aGVyZSBpcyBzb21ldGhpbmcgYXQgdGhpcyBhZGRyZXNzLCB1bmxlc3MgZm9yY2VkICovCglpZiAoa2luZCA8IDApIHsKCQlpZiAoaTJjX3NtYnVzX3hmZXIoYWRhcHRlciwgYWRkciwgMCwgMCwgMCwKCQkJCSAgIEkyQ19TTUJVU19RVUlDSywgTlVMTCkgPCAwKQoJCQlyZXR1cm4gMDsKCgkJLyogcHJldmVudCAyNFJGMDggY29ycnVwdGlvbiAqLwoJCWlmICgoYWRkciAmIH4weDBmKSA9PSAweDUwKQoJCQlpMmNfc21idXNfeGZlcihhZGFwdGVyLCBhZGRyLCAwLCAwLCAwLAoJCQkJICAgICAgIEkyQ19TTUJVU19RVUlDSywgTlVMTCk7Cgl9CgoJLyogRmluYWxseSBjYWxsIHRoZSBjdXN0b20gZGV0ZWN0aW9uIGZ1bmN0aW9uICovCgllcnIgPSBmb3VuZF9wcm9jKGFkYXB0ZXIsIGFkZHIsIGtpbmQpOwoKCS8qIC1FTk9ERVYgY2FuIGJlIHJldHVybmVkIGlmIHRoZXJlIGlzIGEgY2hpcCBhdCB0aGUgZ2l2ZW4gYWRkcmVzcwoJICAgYnV0IGl0IGlzbid0IHN1cHBvcnRlZCBieSB0aGlzIGNoaXAgZHJpdmVyLiBXZSBjYXRjaCBpdCBoZXJlIGFzCgkgICB0aGlzIGlzbid0IGFuIGVycm9yLiAqLwoJcmV0dXJuIChlcnIgPT0gLUVOT0RFVikgPyAwIDogZXJyOwp9CgppbnQgaTJjX3Byb2JlKHN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcHRlciwKCSAgICAgIHN0cnVjdCBpMmNfY2xpZW50X2FkZHJlc3NfZGF0YSAqYWRkcmVzc19kYXRhLAoJICAgICAgaW50ICgqZm91bmRfcHJvYykgKHN0cnVjdCBpMmNfYWRhcHRlciAqLCBpbnQsIGludCkpCnsKCWludCBpLCBlcnI7CglpbnQgYWRhcF9pZCA9IGkyY19hZGFwdGVyX2lkKGFkYXB0ZXIpOwoKCS8qIEZvcmNlIGVudHJpZXMgYXJlIGRvbmUgZmlyc3QsIGFuZCBhcmUgbm90IGFmZmVjdGVkIGJ5IGlnbm9yZQoJICAgZW50cmllcyAqLwoJaWYgKGFkZHJlc3NfZGF0YS0+Zm9yY2VzKSB7CgkJdW5zaWduZWQgc2hvcnQgKipmb3JjZXMgPSBhZGRyZXNzX2RhdGEtPmZvcmNlczsKCQlpbnQga2luZDsKCgkJZm9yIChraW5kID0gMDsgZm9yY2VzW2tpbmRdOyBraW5kKyspIHsKCQkJZm9yIChpID0gMDsgZm9yY2VzW2tpbmRdW2ldICE9IEkyQ19DTElFTlRfRU5EOwoJCQkgICAgIGkgKz0gMikgewoJCQkJaWYgKGZvcmNlc1traW5kXVtpXSA9PSBhZGFwX2lkCgkJCQkgfHwgZm9yY2VzW2tpbmRdW2ldID09IEFOWV9JMkNfQlVTKSB7CgkJCQkJZGV2X2RiZygmYWRhcHRlci0+ZGV2LCAiZm91bmQgZm9yY2UgIgoJCQkJCQkicGFyYW1ldGVyIGZvciBhZGFwdGVyICVkLCAiCgkJCQkJCSJhZGRyIDB4JTAyeCwga2luZCAlZFxuIiwKCQkJCQkJYWRhcF9pZCwgZm9yY2VzW2tpbmRdW2kgKyAxXSwKCQkJCQkJa2luZCk7CgkJCQkJZXJyID0gaTJjX3Byb2JlX2FkZHJlc3MoYWRhcHRlciwKCQkJCQkJZm9yY2VzW2tpbmRdW2kgKyAxXSwKCQkJCQkJa2luZCwgZm91bmRfcHJvYyk7CgkJCQkJaWYgKGVycikKCQkJCQkJcmV0dXJuIGVycjsKCQkJCX0KCQkJfQoJCX0KCX0KCgkvKiBTdG9wIGhlcmUgaWYgd2UgY2FuJ3QgdXNlIFNNQlVTX1FVSUNLICovCglpZiAoIWkyY19jaGVja19mdW5jdGlvbmFsaXR5KGFkYXB0ZXIsIEkyQ19GVU5DX1NNQlVTX1FVSUNLKSkgewoJCWlmIChhZGRyZXNzX2RhdGEtPnByb2JlWzBdID09IEkyQ19DTElFTlRfRU5ECgkJICYmIGFkZHJlc3NfZGF0YS0+bm9ybWFsX2kyY1swXSA9PSBJMkNfQ0xJRU5UX0VORCkKCQkgCXJldHVybiAwOwoKCQlkZXZfd2FybigmYWRhcHRlci0+ZGV2LCAiU01CdXMgUXVpY2sgY29tbWFuZCBub3Qgc3VwcG9ydGVkLCAiCgkJCSAiY2FuJ3QgcHJvYmUgZm9yIGNoaXBzXG4iKTsKCQlyZXR1cm4gLTE7Cgl9CgoJLyogUHJvYmUgZW50cmllcyBhcmUgZG9uZSBzZWNvbmQsIGFuZCBhcmUgbm90IGFmZmVjdGVkIGJ5IGlnbm9yZQoJICAgZW50cmllcyBlaXRoZXIgKi8KCWZvciAoaSA9IDA7IGFkZHJlc3NfZGF0YS0+cHJvYmVbaV0gIT0gSTJDX0NMSUVOVF9FTkQ7IGkgKz0gMikgewoJCWlmIChhZGRyZXNzX2RhdGEtPnByb2JlW2ldID09IGFkYXBfaWQKCQkgfHwgYWRkcmVzc19kYXRhLT5wcm9iZVtpXSA9PSBBTllfSTJDX0JVUykgewoJCQlkZXZfZGJnKCZhZGFwdGVyLT5kZXYsICJmb3VuZCBwcm9iZSBwYXJhbWV0ZXIgZm9yICIKCQkJCSJhZGFwdGVyICVkLCBhZGRyIDB4JTAyeFxuIiwgYWRhcF9pZCwKCQkJCWFkZHJlc3NfZGF0YS0+cHJvYmVbaSArIDFdKTsKCQkJZXJyID0gaTJjX3Byb2JlX2FkZHJlc3MoYWRhcHRlciwKCQkJCQkJYWRkcmVzc19kYXRhLT5wcm9iZVtpICsgMV0sCgkJCQkJCS0xLCBmb3VuZF9wcm9jKTsKCQkJaWYgKGVycikKCQkJCXJldHVybiBlcnI7CgkJfQoJfQoKCS8qIE5vcm1hbCBlbnRyaWVzIGFyZSBkb25lIGxhc3QsIHVubGVzcyBzaGFkb3dlZCBieSBhbiBpZ25vcmUgZW50cnkgKi8KCWZvciAoaSA9IDA7IGFkZHJlc3NfZGF0YS0+bm9ybWFsX2kyY1tpXSAhPSBJMkNfQ0xJRU5UX0VORDsgaSArPSAxKSB7CgkJaW50IGosIGlnbm9yZTsKCgkJaWdub3JlID0gMDsKCQlmb3IgKGogPSAwOyBhZGRyZXNzX2RhdGEtPmlnbm9yZVtqXSAhPSBJMkNfQ0xJRU5UX0VORDsKCQkgICAgIGogKz0gMikgewoJCQlpZiAoKGFkZHJlc3NfZGF0YS0+aWdub3JlW2pdID09IGFkYXBfaWQgfHwKCQkJICAgICBhZGRyZXNzX2RhdGEtPmlnbm9yZVtqXSA9PSBBTllfSTJDX0JVUykKCQkJICYmIGFkZHJlc3NfZGF0YS0+aWdub3JlW2ogKyAxXQoJCQkgICAgPT0gYWRkcmVzc19kYXRhLT5ub3JtYWxfaTJjW2ldKSB7CgkJCQlkZXZfZGJnKCZhZGFwdGVyLT5kZXYsICJmb3VuZCBpZ25vcmUgIgoJCQkJCSJwYXJhbWV0ZXIgZm9yIGFkYXB0ZXIgJWQsICIKCQkJCQkiYWRkciAweCUwMnhcbiIsIGFkYXBfaWQsCgkJCQkJYWRkcmVzc19kYXRhLT5pZ25vcmVbaiArIDFdKTsKCQkJfQoJCQlpZ25vcmUgPSAxOwoJCQlicmVhazsKCQl9CgkJaWYgKGlnbm9yZSkKCQkJY29udGludWU7CgoJCWRldl9kYmcoJmFkYXB0ZXItPmRldiwgImZvdW5kIG5vcm1hbCBlbnRyeSBmb3IgYWRhcHRlciAlZCwgIgoJCQkiYWRkciAweCUwMnhcbiIsIGFkYXBfaWQsCgkJCWFkZHJlc3NfZGF0YS0+bm9ybWFsX2kyY1tpXSk7CgkJZXJyID0gaTJjX3Byb2JlX2FkZHJlc3MoYWRhcHRlciwgYWRkcmVzc19kYXRhLT5ub3JtYWxfaTJjW2ldLAoJCQkJCS0xLCBmb3VuZF9wcm9jKTsKCQlpZiAoZXJyKQoJCQlyZXR1cm4gZXJyOwoJfQoKCXJldHVybiAwOwp9CgpzdHJ1Y3QgaTJjX2FkYXB0ZXIqIGkyY19nZXRfYWRhcHRlcihpbnQgaWQpCnsKCXN0cnVjdCBpMmNfYWRhcHRlciAqYWRhcHRlcjsKCQoJbXV0ZXhfbG9jaygmY29yZV9saXN0cyk7CglhZGFwdGVyID0gKHN0cnVjdCBpMmNfYWRhcHRlciAqKWlkcl9maW5kKCZpMmNfYWRhcHRlcl9pZHIsIGlkKTsKCWlmIChhZGFwdGVyICYmICF0cnlfbW9kdWxlX2dldChhZGFwdGVyLT5vd25lcikpCgkJYWRhcHRlciA9IE5VTEw7CgoJbXV0ZXhfdW5sb2NrKCZjb3JlX2xpc3RzKTsKCXJldHVybiBhZGFwdGVyOwp9Cgp2b2lkIGkyY19wdXRfYWRhcHRlcihzdHJ1Y3QgaTJjX2FkYXB0ZXIgKmFkYXApCnsKCW1vZHVsZV9wdXQoYWRhcC0+b3duZXIpOwp9CgovKiBUaGUgU01CdXMgcGFydHMgKi8KCiNkZWZpbmUgUE9MWSAgICAoMHgxMDcwVSA8PCAzKSAKc3RhdGljIHU4CmNyYzgodTE2IGRhdGEpCnsKCWludCBpOwogIAoJZm9yKGkgPSAwOyBpIDwgODsgaSsrKSB7CgkJaWYgKGRhdGEgJiAweDgwMDApIAoJCQlkYXRhID0gZGF0YSBeIFBPTFk7CgkJZGF0YSA9IGRhdGEgPDwgMTsKCX0KCXJldHVybiAodTgpKGRhdGEgPj4gOCk7Cn0KCi8qIEluY3JlbWVudGFsIENSQzggb3ZlciBjb3VudCBieXRlcyBpbiB0aGUgYXJyYXkgcG9pbnRlZCB0byBieSBwICovCnN0YXRpYyB1OCBpMmNfc21idXNfcGVjKHU4IGNyYywgdTggKnAsIHNpemVfdCBjb3VudCkKewoJaW50IGk7CgoJZm9yKGkgPSAwOyBpIDwgY291bnQ7IGkrKykKCQljcmMgPSBjcmM4KChjcmMgXiBwW2ldKSA8PCA4KTsKCXJldHVybiBjcmM7Cn0KCi8qIEFzc3VtZSBhIDctYml0IGFkZHJlc3MsIHdoaWNoIGlzIHJlYXNvbmFibGUgZm9yIFNNQnVzICovCnN0YXRpYyB1OCBpMmNfc21idXNfbXNnX3BlYyh1OCBwZWMsIHN0cnVjdCBpMmNfbXNnICptc2cpCnsKCS8qIFRoZSBhZGRyZXNzIHdpbGwgYmUgc2VudCBmaXJzdCAqLwoJdTggYWRkciA9IChtc2ctPmFkZHIgPDwgMSkgfCAhIShtc2ctPmZsYWdzICYgSTJDX01fUkQpOwoJcGVjID0gaTJjX3NtYnVzX3BlYyhwZWMsICZhZGRyLCAxKTsKCgkvKiBUaGUgZGF0YSBidWZmZXIgZm9sbG93cyAqLwoJcmV0dXJuIGkyY19zbWJ1c19wZWMocGVjLCBtc2ctPmJ1ZiwgbXNnLT5sZW4pOwp9CgovKiBVc2VkIGZvciB3cml0ZSBvbmx5IHRyYW5zYWN0aW9ucyAqLwpzdGF0aWMgaW5saW5lIHZvaWQgaTJjX3NtYnVzX2FkZF9wZWMoc3RydWN0IGkyY19tc2cgKm1zZykKewoJbXNnLT5idWZbbXNnLT5sZW5dID0gaTJjX3NtYnVzX21zZ19wZWMoMCwgbXNnKTsKCW1zZy0+bGVuKys7Cn0KCi8qIFJldHVybiA8MCBvbiBDUkMgZXJyb3IKICAgSWYgdGhlcmUgd2FzIGEgd3JpdGUgYmVmb3JlIHRoaXMgcmVhZCAobW9zdCBjYXNlcykgd2UgbmVlZCB0byB0YWtlIHRoZQogICBwYXJ0aWFsIENSQyBmcm9tIHRoZSB3cml0ZSBwYXJ0IGludG8gYWNjb3VudC4KICAgTm90ZSB0aGF0IHRoaXMgZnVuY3Rpb24gZG9lcyBtb2RpZnkgdGhlIG1lc3NhZ2UgKHdlIG5lZWQgdG8gZGVjcmVhc2UgdGhlCiAgIG1lc3NhZ2UgbGVuZ3RoIHRvIGhpZGUgdGhlIENSQyBieXRlIGZyb20gdGhlIGNhbGxlcikuICovCnN0YXRpYyBpbnQgaTJjX3NtYnVzX2NoZWNrX3BlYyh1OCBjcGVjLCBzdHJ1Y3QgaTJjX21zZyAqbXNnKQp7Cgl1OCBycGVjID0gbXNnLT5idWZbLS1tc2ctPmxlbl07CgljcGVjID0gaTJjX3NtYnVzX21zZ19wZWMoY3BlYywgbXNnKTsKCglpZiAocnBlYyAhPSBjcGVjKSB7CgkJcHJfZGVidWcoImkyYy1jb3JlOiBCYWQgUEVDIDB4JTAyeCB2cy4gMHglMDJ4XG4iLAoJCQlycGVjLCBjcGVjKTsKCQlyZXR1cm4gLTE7Cgl9CglyZXR1cm4gMDsJCn0KCnMzMiBpMmNfc21idXNfd3JpdGVfcXVpY2soc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCwgdTggdmFsdWUpCnsKCXJldHVybiBpMmNfc21idXNfeGZlcihjbGllbnQtPmFkYXB0ZXIsY2xpZW50LT5hZGRyLGNsaWVudC0+ZmxhZ3MsCiAJICAgICAgICAgICAgICAgICAgICAgIHZhbHVlLDAsSTJDX1NNQlVTX1FVSUNLLE5VTEwpOwp9CgpzMzIgaTJjX3NtYnVzX3JlYWRfYnl0ZShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50KQp7Cgl1bmlvbiBpMmNfc21idXNfZGF0YSBkYXRhOwoJaWYgKGkyY19zbWJ1c194ZmVyKGNsaWVudC0+YWRhcHRlcixjbGllbnQtPmFkZHIsY2xpZW50LT5mbGFncywKCSAgICAgICAgICAgICAgICAgICBJMkNfU01CVVNfUkVBRCwwLEkyQ19TTUJVU19CWVRFLCAmZGF0YSkpCgkJcmV0dXJuIC0xOwoJZWxzZQoJCXJldHVybiAweDBGRiAmIGRhdGEuYnl0ZTsKfQoKczMyIGkyY19zbWJ1c193cml0ZV9ieXRlKHN0cnVjdCBpMmNfY2xpZW50ICpjbGllbnQsIHU4IHZhbHVlKQp7CglyZXR1cm4gaTJjX3NtYnVzX3hmZXIoY2xpZW50LT5hZGFwdGVyLGNsaWVudC0+YWRkcixjbGllbnQtPmZsYWdzLAoJICAgICAgICAgICAgICAgICAgICAgIEkyQ19TTUJVU19XUklURSwgdmFsdWUsIEkyQ19TTUJVU19CWVRFLCBOVUxMKTsKfQoKczMyIGkyY19zbWJ1c19yZWFkX2J5dGVfZGF0YShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LCB1OCBjb21tYW5kKQp7Cgl1bmlvbiBpMmNfc21idXNfZGF0YSBkYXRhOwoJaWYgKGkyY19zbWJ1c194ZmVyKGNsaWVudC0+YWRhcHRlcixjbGllbnQtPmFkZHIsY2xpZW50LT5mbGFncywKCSAgICAgICAgICAgICAgICAgICBJMkNfU01CVVNfUkVBRCxjb21tYW5kLCBJMkNfU01CVVNfQllURV9EQVRBLCZkYXRhKSkKCQlyZXR1cm4gLTE7CgllbHNlCgkJcmV0dXJuIDB4MEZGICYgZGF0YS5ieXRlOwp9CgpzMzIgaTJjX3NtYnVzX3dyaXRlX2J5dGVfZGF0YShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LCB1OCBjb21tYW5kLCB1OCB2YWx1ZSkKewoJdW5pb24gaTJjX3NtYnVzX2RhdGEgZGF0YTsKCWRhdGEuYnl0ZSA9IHZhbHVlOwoJcmV0dXJuIGkyY19zbWJ1c194ZmVyKGNsaWVudC0+YWRhcHRlcixjbGllbnQtPmFkZHIsY2xpZW50LT5mbGFncywKCSAgICAgICAgICAgICAgICAgICAgICBJMkNfU01CVVNfV1JJVEUsY29tbWFuZCwKCSAgICAgICAgICAgICAgICAgICAgICBJMkNfU01CVVNfQllURV9EQVRBLCZkYXRhKTsKfQoKczMyIGkyY19zbWJ1c19yZWFkX3dvcmRfZGF0YShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LCB1OCBjb21tYW5kKQp7Cgl1bmlvbiBpMmNfc21idXNfZGF0YSBkYXRhOwoJaWYgKGkyY19zbWJ1c194ZmVyKGNsaWVudC0+YWRhcHRlcixjbGllbnQtPmFkZHIsY2xpZW50LT5mbGFncywKCSAgICAgICAgICAgICAgICAgICBJMkNfU01CVVNfUkVBRCxjb21tYW5kLCBJMkNfU01CVVNfV09SRF9EQVRBLCAmZGF0YSkpCgkJcmV0dXJuIC0xOwoJZWxzZQoJCXJldHVybiAweDBGRkZGICYgZGF0YS53b3JkOwp9CgpzMzIgaTJjX3NtYnVzX3dyaXRlX3dvcmRfZGF0YShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LCB1OCBjb21tYW5kLCB1MTYgdmFsdWUpCnsKCXVuaW9uIGkyY19zbWJ1c19kYXRhIGRhdGE7CglkYXRhLndvcmQgPSB2YWx1ZTsKCXJldHVybiBpMmNfc21idXNfeGZlcihjbGllbnQtPmFkYXB0ZXIsY2xpZW50LT5hZGRyLGNsaWVudC0+ZmxhZ3MsCgkgICAgICAgICAgICAgICAgICAgICAgSTJDX1NNQlVTX1dSSVRFLGNvbW1hbmQsCgkgICAgICAgICAgICAgICAgICAgICAgSTJDX1NNQlVTX1dPUkRfREFUQSwmZGF0YSk7Cn0KCnMzMiBpMmNfc21idXNfd3JpdGVfYmxvY2tfZGF0YShzdHJ1Y3QgaTJjX2NsaWVudCAqY2xpZW50LCB1OCBjb21tYW5kLAoJCQkgICAgICAgdTggbGVuZ3RoLCB1OCAqdmFsdWVzKQp7Cgl1bmlvbiBpMmNfc21idXNfZGF0YSBkYXRhOwoKCWlmIChsZW5ndGggPiBJMkNfU01CVVNfQkxPQ0tfTUFYKQoJCWxlbmd0aCA9IEkyQ19TTUJVU19CTE9DS19NQVg7CglkYXRhLmJsb2NrWzBdID0gbGVuZ3RoOwoJbWVtY3B5KCZkYXRhLmJsb2NrWzFdLCB2YWx1ZXMsIGxlbmd0aCk7CglyZXR1cm4gaTJjX3NtYnVzX3hmZXIoY2xpZW50LT5hZGFwdGVyLGNsaWVudC0+YWRkcixjbGllbnQtPmZsYWdzLAoJCQkgICAgICBJMkNfU01CVVNfV1JJVEUsY29tbWFuZCwKCQkJICAgICAgSTJDX1NNQlVTX0JMT0NLX0RBVEEsJmRhdGEpOwp9CgovKiBSZXR1cm5zIHRoZSBudW1iZXIgb2YgcmVhZCBieXRlcyAqLwpzMzIgaTJjX3NtYnVzX3JlYWRfaTJjX2Jsb2NrX2RhdGEoc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCwgdTggY29tbWFuZCwgdTggKnZhbHVlcykKewoJdW5pb24gaTJjX3NtYnVzX2RhdGEgZGF0YTsKCglpZiAoaTJjX3NtYnVzX3hmZXIoY2xpZW50LT5hZGFwdGVyLGNsaWVudC0+YWRkcixjbGllbnQtPmZsYWdzLAoJICAgICAgICAgICAgICAgICAgICAgIEkyQ19TTUJVU19SRUFELGNvbW1hbmQsCgkgICAgICAgICAgICAgICAgICAgICAgSTJDX1NNQlVTX0kyQ19CTE9DS19EQVRBLCZkYXRhKSkKCQlyZXR1cm4gLTE7CgoJbWVtY3B5KHZhbHVlcywgJmRhdGEuYmxvY2tbMV0sIGRhdGEuYmxvY2tbMF0pOwoJcmV0dXJuIGRhdGEuYmxvY2tbMF07Cn0KCnMzMiBpMmNfc21idXNfd3JpdGVfaTJjX2Jsb2NrX2RhdGEoc3RydWN0IGkyY19jbGllbnQgKmNsaWVudCwgdTggY29tbWFuZCwKCQkJCSAgIHU4IGxlbmd0aCwgdTggKnZhbHVlcykKewoJdW5pb24gaTJjX3NtYnVzX2RhdGEgZGF0YTsKCglpZiAobGVuZ3RoID4gSTJDX1NNQlVTX0JMT0NLX01BWCkKCQlsZW5ndGggPSBJMkNfU01CVVNfQkxPQ0tfTUFYOwoJZGF0YS5ibG9ja1swXSA9IGxlbmd0aDsKCW1lbWNweShkYXRhLmJsb2NrICsgMSwgdmFsdWVzLCBsZW5ndGgpOwoJcmV0dXJuIGkyY19zbWJ1c194ZmVyKGNsaWVudC0+YWRhcHRlciwgY2xpZW50LT5hZGRyLCBjbGllbnQtPmZsYWdzLAoJCQkgICAgICBJMkNfU01CVVNfV1JJVEUsIGNvbW1hbmQsCgkJCSAgICAgIEkyQ19TTUJVU19JMkNfQkxPQ0tfREFUQSwgJmRhdGEpOwp9CgovKiBTaW11bGF0ZSBhIFNNQnVzIGNvbW1hbmQgdXNpbmcgdGhlIGkyYyBwcm90b2NvbCAKICAgTm8gY2hlY2tpbmcgb2YgcGFyYW1ldGVycyBpcyBkb25lISAgKi8Kc3RhdGljIHMzMiBpMmNfc21idXNfeGZlcl9lbXVsYXRlZChzdHJ1Y3QgaTJjX2FkYXB0ZXIgKiBhZGFwdGVyLCB1MTYgYWRkciwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5zaWduZWQgc2hvcnQgZmxhZ3MsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY2hhciByZWFkX3dyaXRlLCB1OCBjb21tYW5kLCBpbnQgc2l6ZSwgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdW5pb24gaTJjX3NtYnVzX2RhdGEgKiBkYXRhKQp7CgkvKiBTbyB3ZSBuZWVkIHRvIGdlbmVyYXRlIGEgc2VyaWVzIG9mIG1zZ3MuIEluIHRoZSBjYXNlIG9mIHdyaXRpbmcsIHdlCgkgIG5lZWQgdG8gdXNlIG9ubHkgb25lIG1lc3NhZ2U7IHdoZW4gcmVhZGluZywgd2UgbmVlZCB0d28uIFdlIGluaXRpYWxpemUKCSAgbW9zdCB0aGluZ3Mgd2l0aCBzYW5lIGRlZmF1bHRzLCB0byBrZWVwIHRoZSBjb2RlIGJlbG93IHNvbWV3aGF0CgkgIHNpbXBsZXIuICovCgl1bnNpZ25lZCBjaGFyIG1zZ2J1ZjBbSTJDX1NNQlVTX0JMT0NLX01BWCszXTsKCXVuc2lnbmVkIGNoYXIgbXNnYnVmMVtJMkNfU01CVVNfQkxPQ0tfTUFYKzJdOwoJaW50IG51bSA9IHJlYWRfd3JpdGUgPT0gSTJDX1NNQlVTX1JFQUQ/MjoxOwoJc3RydWN0IGkyY19tc2cgbXNnWzJdID0geyB7IGFkZHIsIGZsYWdzLCAxLCBtc2didWYwIH0sIAoJICAgICAgICAgICAgICAgICAgICAgICAgICB7IGFkZHIsIGZsYWdzIHwgSTJDX01fUkQsIDAsIG1zZ2J1ZjEgfQoJICAgICAgICAgICAgICAgICAgICAgICAgfTsKCWludCBpOwoJdTggcGFydGlhbF9wZWMgPSAwOwoKCW1zZ2J1ZjBbMF0gPSBjb21tYW5kOwoJc3dpdGNoKHNpemUpIHsKCWNhc2UgSTJDX1NNQlVTX1FVSUNLOgoJCW1zZ1swXS5sZW4gPSAwOwoJCS8qIFNwZWNpYWwgY2FzZTogVGhlIHJlYWQvd3JpdGUgZmllbGQgaXMgdXNlZCBhcyBkYXRhICovCgkJbXNnWzBdLmZsYWdzID0gZmxhZ3MgfCAocmVhZF93cml0ZT09STJDX1NNQlVTX1JFQUQpP0kyQ19NX1JEOjA7CgkJbnVtID0gMTsKCQlicmVhazsKCWNhc2UgSTJDX1NNQlVTX0JZVEU6CgkJaWYgKHJlYWRfd3JpdGUgPT0gSTJDX1NNQlVTX1JFQUQpIHsKCQkJLyogU3BlY2lhbCBjYXNlOiBvbmx5IGEgcmVhZCEgKi8KCQkJbXNnWzBdLmZsYWdzID0gSTJDX01fUkQgfCBmbGFnczsKCQkJbnVtID0gMTsKCQl9CgkJYnJlYWs7CgljYXNlIEkyQ19TTUJVU19CWVRFX0RBVEE6CgkJaWYgKHJlYWRfd3JpdGUgPT0gSTJDX1NNQlVTX1JFQUQpCgkJCW1zZ1sxXS5sZW4gPSAxOwoJCWVsc2UgewoJCQltc2dbMF0ubGVuID0gMjsKCQkJbXNnYnVmMFsxXSA9IGRhdGEtPmJ5dGU7CgkJfQoJCWJyZWFrOwoJY2FzZSBJMkNfU01CVVNfV09SRF9EQVRBOgoJCWlmIChyZWFkX3dyaXRlID09IEkyQ19TTUJVU19SRUFEKQoJCQltc2dbMV0ubGVuID0gMjsKCQllbHNlIHsKCQkJbXNnWzBdLmxlbj0zOwoJCQltc2didWYwWzFdID0gZGF0YS0+d29yZCAmIDB4ZmY7CgkJCW1zZ2J1ZjBbMl0gPSAoZGF0YS0+d29yZCA+PiA4KSAmIDB4ZmY7CgkJfQoJCWJyZWFrOwoJY2FzZSBJMkNfU01CVVNfUFJPQ19DQUxMOgoJCW51bSA9IDI7IC8qIFNwZWNpYWwgY2FzZSAqLwoJCXJlYWRfd3JpdGUgPSBJMkNfU01CVVNfUkVBRDsKCQltc2dbMF0ubGVuID0gMzsKCQltc2dbMV0ubGVuID0gMjsKCQltc2didWYwWzFdID0gZGF0YS0+d29yZCAmIDB4ZmY7CgkJbXNnYnVmMFsyXSA9IChkYXRhLT53b3JkID4+IDgpICYgMHhmZjsKCQlicmVhazsKCWNhc2UgSTJDX1NNQlVTX0JMT0NLX0RBVEE6CgkJaWYgKHJlYWRfd3JpdGUgPT0gSTJDX1NNQlVTX1JFQUQpIHsKCQkJZGV2X2VycigmYWRhcHRlci0+ZGV2LCAiQmxvY2sgcmVhZCBub3Qgc3VwcG9ydGVkICIKCQkJICAgICAgICJ1bmRlciBJMkMgZW11bGF0aW9uIVxuIik7CgkJCXJldHVybiAtMTsKCQl9IGVsc2UgewoJCQltc2dbMF0ubGVuID0gZGF0YS0+YmxvY2tbMF0gKyAyOwoJCQlpZiAobXNnWzBdLmxlbiA+IEkyQ19TTUJVU19CTE9DS19NQVggKyAyKSB7CgkJCQlkZXZfZXJyKCZhZGFwdGVyLT5kZXYsICJzbWJ1c19hY2Nlc3MgY2FsbGVkIHdpdGggIgoJCQkJICAgICAgICJpbnZhbGlkIGJsb2NrIHdyaXRlIHNpemUgKCVkKVxuIiwKCQkJCSAgICAgICBkYXRhLT5ibG9ja1swXSk7CgkJCQlyZXR1cm4gLTE7CgkJCX0KCQkJZm9yIChpID0gMTsgaSA8IG1zZ1swXS5sZW47IGkrKykKCQkJCW1zZ2J1ZjBbaV0gPSBkYXRhLT5ibG9ja1tpLTFdOwoJCX0KCQlicmVhazsKCWNhc2UgSTJDX1NNQlVTX0JMT0NLX1BST0NfQ0FMTDoKCQlkZXZfZGJnKCZhZGFwdGVyLT5kZXYsICJCbG9jayBwcm9jZXNzIGNhbGwgbm90IHN1cHBvcnRlZCAiCgkJICAgICAgICJ1bmRlciBJMkMgZW11bGF0aW9uIVxuIik7CgkJcmV0dXJuIC0xOwoJY2FzZSBJMkNfU01CVVNfSTJDX0JMT0NLX0RBVEE6CgkJaWYgKHJlYWRfd3JpdGUgPT0gSTJDX1NNQlVTX1JFQUQpIHsKCQkJbXNnWzFdLmxlbiA9IEkyQ19TTUJVU19CTE9DS19NQVg7CgkJfSBlbHNlIHsKCQkJbXNnWzBdLmxlbiA9IGRhdGEtPmJsb2NrWzBdICsgMTsKCQkJaWYgKG1zZ1swXS5sZW4gPiBJMkNfU01CVVNfQkxPQ0tfTUFYICsgMSkgewoJCQkJZGV2X2VycigmYWRhcHRlci0+ZGV2LCAiaTJjX3NtYnVzX3hmZXJfZW11bGF0ZWQgY2FsbGVkIHdpdGggIgoJCQkJICAgICAgICJpbnZhbGlkIGJsb2NrIHdyaXRlIHNpemUgKCVkKVxuIiwKCQkJCSAgICAgICBkYXRhLT5ibG9ja1swXSk7CgkJCQlyZXR1cm4gLTE7CgkJCX0KCQkJZm9yIChpID0gMTsgaSA8PSBkYXRhLT5ibG9ja1swXTsgaSsrKQoJCQkJbXNnYnVmMFtpXSA9IGRhdGEtPmJsb2NrW2ldOwoJCX0KCQlicmVhazsKCWRlZmF1bHQ6CgkJZGV2X2VycigmYWRhcHRlci0+ZGV2LCAic21idXNfYWNjZXNzIGNhbGxlZCB3aXRoIGludmFsaWQgc2l6ZSAoJWQpXG4iLAoJCSAgICAgICBzaXplKTsKCQlyZXR1cm4gLTE7Cgl9CgoJaSA9ICgoZmxhZ3MgJiBJMkNfQ0xJRU5UX1BFQykgJiYgc2l6ZSAhPSBJMkNfU01CVVNfUVVJQ0sKCQkJCSAgICAgICYmIHNpemUgIT0gSTJDX1NNQlVTX0kyQ19CTE9DS19EQVRBKTsKCWlmIChpKSB7CgkJLyogQ29tcHV0ZSBQRUMgaWYgZmlyc3QgbWVzc2FnZSBpcyBhIHdyaXRlICovCgkJaWYgKCEobXNnWzBdLmZsYWdzICYgSTJDX01fUkQpKSB7CgkJIAlpZiAobnVtID09IDEpIC8qIFdyaXRlIG9ubHkgKi8KCQkJCWkyY19zbWJ1c19hZGRfcGVjKCZtc2dbMF0pOwoJCQllbHNlIC8qIFdyaXRlIGZvbGxvd2VkIGJ5IHJlYWQgKi8KCQkJCXBhcnRpYWxfcGVjID0gaTJjX3NtYnVzX21zZ19wZWMoMCwgJm1zZ1swXSk7CgkJfQoJCS8qIEFzayBmb3IgUEVDIGlmIGxhc3QgbWVzc2FnZSBpcyBhIHJlYWQgKi8KCQlpZiAobXNnW251bS0xXS5mbGFncyAmIEkyQ19NX1JEKQoJCSAJbXNnW251bS0xXS5sZW4rKzsKCX0KCglpZiAoaTJjX3RyYW5zZmVyKGFkYXB0ZXIsIG1zZywgbnVtKSA8IDApCgkJcmV0dXJuIC0xOwoKCS8qIENoZWNrIFBFQyBpZiBsYXN0IG1lc3NhZ2UgaXMgYSByZWFkICovCglpZiAoaSAmJiAobXNnW251bS0xXS5mbGFncyAmIEkyQ19NX1JEKSkgewoJCWlmIChpMmNfc21idXNfY2hlY2tfcGVjKHBhcnRpYWxfcGVjLCAmbXNnW251bS0xXSkgPCAwKQoJCQlyZXR1cm4gLTE7Cgl9CgoJaWYgKHJlYWRfd3JpdGUgPT0gSTJDX1NNQlVTX1JFQUQpCgkJc3dpdGNoKHNpemUpIHsKCQkJY2FzZSBJMkNfU01CVVNfQllURToKCQkJCWRhdGEtPmJ5dGUgPSBtc2didWYwWzBdOwoJCQkJYnJlYWs7CgkJCWNhc2UgSTJDX1NNQlVTX0JZVEVfREFUQToKCQkJCWRhdGEtPmJ5dGUgPSBtc2didWYxWzBdOwoJCQkJYnJlYWs7CgkJCWNhc2UgSTJDX1NNQlVTX1dPUkRfREFUQTogCgkJCWNhc2UgSTJDX1NNQlVTX1BST0NfQ0FMTDoKCQkJCWRhdGEtPndvcmQgPSBtc2didWYxWzBdIHwgKG1zZ2J1ZjFbMV0gPDwgOCk7CgkJCQlicmVhazsKCQkJY2FzZSBJMkNfU01CVVNfSTJDX0JMT0NLX0RBVEE6CgkJCQkvKiBmaXhlZCBhdCAzMiBmb3Igbm93ICovCgkJCQlkYXRhLT5ibG9ja1swXSA9IEkyQ19TTUJVU19CTE9DS19NQVg7CgkJCQlmb3IgKGkgPSAwOyBpIDwgSTJDX1NNQlVTX0JMT0NLX01BWDsgaSsrKQoJCQkJCWRhdGEtPmJsb2NrW2krMV0gPSBtc2didWYxW2ldOwoJCQkJYnJlYWs7CgkJfQoJcmV0dXJuIDA7Cn0KCgpzMzIgaTJjX3NtYnVzX3hmZXIoc3RydWN0IGkyY19hZGFwdGVyICogYWRhcHRlciwgdTE2IGFkZHIsIHVuc2lnbmVkIHNob3J0IGZsYWdzLAogICAgICAgICAgICAgICAgICAgY2hhciByZWFkX3dyaXRlLCB1OCBjb21tYW5kLCBpbnQgc2l6ZSwgCiAgICAgICAgICAgICAgICAgICB1bmlvbiBpMmNfc21idXNfZGF0YSAqIGRhdGEpCnsKCXMzMiByZXM7CgoJZmxhZ3MgJj0gSTJDX01fVEVOIHwgSTJDX0NMSUVOVF9QRUM7CgoJaWYgKGFkYXB0ZXItPmFsZ28tPnNtYnVzX3hmZXIpIHsKCQltdXRleF9sb2NrKCZhZGFwdGVyLT5idXNfbG9jayk7CgkJcmVzID0gYWRhcHRlci0+YWxnby0+c21idXNfeGZlcihhZGFwdGVyLGFkZHIsZmxhZ3MscmVhZF93cml0ZSwKCQkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbW1hbmQsc2l6ZSxkYXRhKTsKCQltdXRleF91bmxvY2soJmFkYXB0ZXItPmJ1c19sb2NrKTsKCX0gZWxzZQoJCXJlcyA9IGkyY19zbWJ1c194ZmVyX2VtdWxhdGVkKGFkYXB0ZXIsYWRkcixmbGFncyxyZWFkX3dyaXRlLAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb21tYW5kLHNpemUsZGF0YSk7CgoJcmV0dXJuIHJlczsKfQoKCi8qIE5leHQgZm91ciBhcmUgbmVlZGVkIGJ5IGkyYy1pc2EgKi8KRVhQT1JUX1NZTUJPTF9HUEwoaTJjX2FkYXB0ZXJfZGV2X3JlbGVhc2UpOwpFWFBPUlRfU1lNQk9MX0dQTChpMmNfYWRhcHRlcl9kcml2ZXIpOwpFWFBPUlRfU1lNQk9MX0dQTChpMmNfYWRhcHRlcl9jbGFzcyk7CkVYUE9SVF9TWU1CT0xfR1BMKGkyY19idXNfdHlwZSk7CgpFWFBPUlRfU1lNQk9MKGkyY19hZGRfYWRhcHRlcik7CkVYUE9SVF9TWU1CT0woaTJjX2RlbF9hZGFwdGVyKTsKRVhQT1JUX1NZTUJPTChpMmNfZGVsX2RyaXZlcik7CkVYUE9SVF9TWU1CT0woaTJjX2F0dGFjaF9jbGllbnQpOwpFWFBPUlRfU1lNQk9MKGkyY19kZXRhY2hfY2xpZW50KTsKRVhQT1JUX1NZTUJPTChpMmNfdXNlX2NsaWVudCk7CkVYUE9SVF9TWU1CT0woaTJjX3JlbGVhc2VfY2xpZW50KTsKRVhQT1JUX1NZTUJPTChpMmNfY2xpZW50c19jb21tYW5kKTsKRVhQT1JUX1NZTUJPTChpMmNfY2hlY2tfYWRkcik7CgpFWFBPUlRfU1lNQk9MKGkyY19tYXN0ZXJfc2VuZCk7CkVYUE9SVF9TWU1CT0woaTJjX21hc3Rlcl9yZWN2KTsKRVhQT1JUX1NZTUJPTChpMmNfY29udHJvbCk7CkVYUE9SVF9TWU1CT0woaTJjX3RyYW5zZmVyKTsKRVhQT1JUX1NZTUJPTChpMmNfZ2V0X2FkYXB0ZXIpOwpFWFBPUlRfU1lNQk9MKGkyY19wdXRfYWRhcHRlcik7CkVYUE9SVF9TWU1CT0woaTJjX3Byb2JlKTsKCkVYUE9SVF9TWU1CT0woaTJjX3NtYnVzX3hmZXIpOwpFWFBPUlRfU1lNQk9MKGkyY19zbWJ1c193cml0ZV9xdWljayk7CkVYUE9SVF9TWU1CT0woaTJjX3NtYnVzX3JlYWRfYnl0ZSk7CkVYUE9SVF9TWU1CT0woaTJjX3NtYnVzX3dyaXRlX2J5dGUpOwpFWFBPUlRfU1lNQk9MKGkyY19zbWJ1c19yZWFkX2J5dGVfZGF0YSk7CkVYUE9SVF9TWU1CT0woaTJjX3NtYnVzX3dyaXRlX2J5dGVfZGF0YSk7CkVYUE9SVF9TWU1CT0woaTJjX3NtYnVzX3JlYWRfd29yZF9kYXRhKTsKRVhQT1JUX1NZTUJPTChpMmNfc21idXNfd3JpdGVfd29yZF9kYXRhKTsKRVhQT1JUX1NZTUJPTChpMmNfc21idXNfd3JpdGVfYmxvY2tfZGF0YSk7CkVYUE9SVF9TWU1CT0woaTJjX3NtYnVzX3JlYWRfaTJjX2Jsb2NrX2RhdGEpOwpFWFBPUlRfU1lNQk9MKGkyY19zbWJ1c193cml0ZV9pMmNfYmxvY2tfZGF0YSk7CgpNT0RVTEVfQVVUSE9SKCJTaW1vbiBHLiBWb2dsIDxzaW1vbkB0ay51bmktbGluei5hYy5hdD4iKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJJMkMtQnVzIG1haW4gbW9kdWxlIik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsK