LyoKICogIGxpbnV4L2RyaXZlcnMvbWVkaWEvbW1jL29tYXAuYwogKgogKiAgQ29weXJpZ2h0IChDKSAyMDA0IE5va2lhIENvcnBvcmF0aW9uCiAqICBXcml0dGVuIGJ5IFR1dWtrYSBUaWtrYW5lbiBhbmQgSnVoYSBZcmr2bOQ8anVoYS55cmpvbGFAbm9raWEuY29tPgogKiAgTWlzYyBoYWNrcyBoZXJlIGFuZCB0aGVyZSBieSBUb255IExpbmRncmVuIDx0b255QGF0b21pZGUuY29tPgogKiAgT3RoZXIgaGFja3MgKERNQSwgU0QsIGV0YykgYnkgRGF2aWQgQnJvd25lbGwKICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlcGFyYW0uaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L2lvcG9ydC5oPgojaW5jbHVkZSA8bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L2RtYS1tYXBwaW5nLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvc3BpbmxvY2suaD4KI2luY2x1ZGUgPGxpbnV4L3RpbWVyLmg+CiNpbmNsdWRlIDxsaW51eC9tbWMvaG9zdC5oPgojaW5jbHVkZSA8bGludXgvbW1jL3Byb3RvY29sLmg+CiNpbmNsdWRlIDxsaW51eC9tbWMvY2FyZC5oPgojaW5jbHVkZSA8bGludXgvY2xrLmg+CgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vaXJxLmg+CiNpbmNsdWRlIDxhc20vc2NhdHRlcmxpc3QuaD4KI2luY2x1ZGUgPGFzbS9tYWNoLXR5cGVzLmg+CgojaW5jbHVkZSA8YXNtL2FyY2gvYm9hcmQuaD4KI2luY2x1ZGUgPGFzbS9hcmNoL2dwaW8uaD4KI2luY2x1ZGUgPGFzbS9hcmNoL2RtYS5oPgojaW5jbHVkZSA8YXNtL2FyY2gvbXV4Lmg+CiNpbmNsdWRlIDxhc20vYXJjaC9mcGdhLmg+CiNpbmNsdWRlIDxhc20vYXJjaC90cHM2NTAxMC5oPgoKI2luY2x1ZGUgIm9tYXAuaCIKCiNkZWZpbmUgRFJJVkVSX05BTUUgIm1tY2ktb21hcCIKI2RlZmluZSBSU1BfVFlQRSh4KQkoKHgpICYgfihNTUNfUlNQX0JVU1l8TU1DX1JTUF9PUENPREUpKQoKLyogU3BlY2lmaWVzIGhvdyBvZnRlbiBpbiBtaWxsaXNlY3MgdG8gcG9sbCBmb3IgY2FyZCBzdGF0dXMgY2hhbmdlcwogKiB3aGVuIHRoZSBjb3ZlciBzd2l0Y2ggaXMgb3BlbiAqLwojZGVmaW5lIE9NQVBfTU1DX1NXSVRDSF9QT0xMX0RFTEFZCTUwMAoKc3RhdGljIGludCBtbWNfb21hcF9lbmFibGVfcG9sbCA9IDE7CgpzdHJ1Y3QgbW1jX29tYXBfaG9zdCB7CglpbnQJCQlpbml0aWFsaXplZDsKCWludAkJCXN1c3BlbmRlZDsKCXN0cnVjdCBtbWNfcmVxdWVzdCAqCW1ycTsKCXN0cnVjdCBtbWNfY29tbWFuZCAqCWNtZDsKCXN0cnVjdCBtbWNfZGF0YSAqCWRhdGE7CglzdHJ1Y3QgbW1jX2hvc3QgKgltbWM7CglzdHJ1Y3QgZGV2aWNlICoJCWRldjsKCXVuc2lnbmVkIGNoYXIJCWlkOyAvKiAxNnh4IGNoaXBzIGhhdmUgMiBNTUMgYmxvY2tzICovCglzdHJ1Y3QgY2xrICoJCWljbGs7CglzdHJ1Y3QgY2xrICoJCWZjbGs7Cgl2b2lkIF9faW9tZW0JCSpiYXNlOwoJaW50CQkJaXJxOwoJdW5zaWduZWQgY2hhcgkJYnVzX21vZGU7Cgl1bnNpZ25lZCBjaGFyCQlod19idXNfbW9kZTsKCgl1bnNpZ25lZCBpbnQJCXNnX2xlbjsKCWludAkJCXNnX2lkeDsKCXUxNiAqCQkJYnVmZmVyOwoJdTMyCQkJYnVmZmVyX2J5dGVzX2xlZnQ7Cgl1MzIJCQl0b3RhbF9ieXRlc19sZWZ0OwoKCXVuc2lnbmVkCQl1c2VfZG1hOjE7Cgl1bnNpZ25lZAkJYnJzX3JlY2VpdmVkOjEsIGRtYV9kb25lOjE7Cgl1bnNpZ25lZAkJZG1hX2lzX3JlYWQ6MTsKCXVuc2lnbmVkCQlkbWFfaW5fdXNlOjE7CglpbnQJCQlkbWFfY2g7CglzcGlubG9ja190CQlkbWFfbG9jazsKCXN0cnVjdCB0aW1lcl9saXN0CWRtYV90aW1lcjsKCXVuc2lnbmVkCQlkbWFfbGVuOwoKCXNob3J0CQkJcG93ZXJfcGluOwoJc2hvcnQJCQl3cF9waW47CgoJaW50CQkJc3dpdGNoX3BpbjsKCXN0cnVjdCB3b3JrX3N0cnVjdAlzd2l0Y2hfd29yazsKCXN0cnVjdCB0aW1lcl9saXN0CXN3aXRjaF90aW1lcjsKCWludAkJCXN3aXRjaF9sYXN0X3N0YXRlOwp9OwoKc3RhdGljIGlubGluZSBpbnQKbW1jX29tYXBfY292ZXJfaXNfb3BlbihzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCkKewoJaWYgKGhvc3QtPnN3aXRjaF9waW4gPCAwKQoJCXJldHVybiAwOwoJcmV0dXJuIG9tYXBfZ2V0X2dwaW9fZGF0YWluKGhvc3QtPnN3aXRjaF9waW4pOwp9CgpzdGF0aWMgc3NpemVfdAptbWNfb21hcF9zaG93X2NvdmVyX3N3aXRjaChzdHJ1Y3QgZGV2aWNlICpkZXYsCglzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwgY2hhciAqYnVmKQp7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwoKCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiVzXG4iLCBtbWNfb21hcF9jb3Zlcl9pc19vcGVuKGhvc3QpID8gIm9wZW4iIDoKCQkJImNsb3NlZCIpOwp9CgpzdGF0aWMgREVWSUNFX0FUVFIoY292ZXJfc3dpdGNoLCBTX0lSVUdPLCBtbWNfb21hcF9zaG93X2NvdmVyX3N3aXRjaCwgTlVMTCk7CgpzdGF0aWMgc3NpemVfdAptbWNfb21hcF9zaG93X2VuYWJsZV9wb2xsKHN0cnVjdCBkZXZpY2UgKmRldiwKCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjaGFyICpidWYpCnsKCXJldHVybiBzbnByaW50ZihidWYsIFBBR0VfU0laRSwgIiVkXG4iLCBtbWNfb21hcF9lbmFibGVfcG9sbCk7Cn0KCnN0YXRpYyBzc2l6ZV90Cm1tY19vbWFwX3N0b3JlX2VuYWJsZV9wb2xsKHN0cnVjdCBkZXZpY2UgKmRldiwKCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjb25zdCBjaGFyICpidWYsCglzaXplX3Qgc2l6ZSkKewoJaW50IGVuYWJsZV9wb2xsOwoKCWlmIChzc2NhbmYoYnVmLCAiJTEwZCIsICZlbmFibGVfcG9sbCkgIT0gMSkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAoZW5hYmxlX3BvbGwgIT0gbW1jX29tYXBfZW5hYmxlX3BvbGwpIHsKCQlzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwoKCQltbWNfb21hcF9lbmFibGVfcG9sbCA9IGVuYWJsZV9wb2xsOwoJCWlmIChlbmFibGVfcG9sbCAmJiBob3N0LT5zd2l0Y2hfcGluID49IDApCgkJCXNjaGVkdWxlX3dvcmsoJmhvc3QtPnN3aXRjaF93b3JrKTsKCX0KCXJldHVybiBzaXplOwp9CgpzdGF0aWMgREVWSUNFX0FUVFIoZW5hYmxlX3BvbGwsIDA2NjQsCgkJICAgbW1jX29tYXBfc2hvd19lbmFibGVfcG9sbCwgbW1jX29tYXBfc3RvcmVfZW5hYmxlX3BvbGwpOwoKc3RhdGljIHZvaWQKbW1jX29tYXBfc3RhcnRfY29tbWFuZChzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19jb21tYW5kICpjbWQpCnsKCXUzMiBjbWRyZWc7Cgl1MzIgcmVzcHR5cGU7Cgl1MzIgY21kdHlwZTsKCglob3N0LT5jbWQgPSBjbWQ7CgoJcmVzcHR5cGUgPSAwOwoJY21kdHlwZSA9IDA7CgoJLyogT3VyIGhhcmR3YXJlIG5lZWRzIHRvIGtub3cgZXhhY3QgdHlwZSAqLwoJc3dpdGNoIChSU1BfVFlQRShtbWNfcmVzcF90eXBlKGNtZCkpKSB7CgljYXNlIFJTUF9UWVBFKE1NQ19SU1BfUjEpOgoJCS8qIHJlc3AgMSwgcmVzcCAxYiAqLwoJCXJlc3B0eXBlID0gMTsKCQlicmVhazsKCWNhc2UgUlNQX1RZUEUoTU1DX1JTUF9SMik6CgkJcmVzcHR5cGUgPSAyOwoJCWJyZWFrOwoJY2FzZSBSU1BfVFlQRShNTUNfUlNQX1IzKToKCQlyZXNwdHlwZSA9IDM7CgkJYnJlYWs7CglkZWZhdWx0OgoJCWJyZWFrOwoJfQoKCWlmIChtbWNfY21kX3R5cGUoY21kKSA9PSBNTUNfQ01EX0FEVEMpIHsKCQljbWR0eXBlID0gT01BUF9NTUNfQ01EVFlQRV9BRFRDOwoJfSBlbHNlIGlmIChtbWNfY21kX3R5cGUoY21kKSA9PSBNTUNfQ01EX0JDKSB7CgkJY21kdHlwZSA9IE9NQVBfTU1DX0NNRFRZUEVfQkM7Cgl9IGVsc2UgaWYgKG1tY19jbWRfdHlwZShjbWQpID09IE1NQ19DTURfQkNSKSB7CgkJY21kdHlwZSA9IE9NQVBfTU1DX0NNRFRZUEVfQkNSOwoJfSBlbHNlIHsKCQljbWR0eXBlID0gT01BUF9NTUNfQ01EVFlQRV9BQzsKCX0KCgljbWRyZWcgPSBjbWQtPm9wY29kZSB8IChyZXNwdHlwZSA8PCA4KSB8IChjbWR0eXBlIDw8IDEyKTsKCglpZiAoaG9zdC0+YnVzX21vZGUgPT0gTU1DX0JVU01PREVfT1BFTkRSQUlOKQoJCWNtZHJlZyB8PSAxIDw8IDY7CgoJaWYgKGNtZC0+ZmxhZ3MgJiBNTUNfUlNQX0JVU1kpCgkJY21kcmVnIHw9IDEgPDwgMTE7CgoJaWYgKGhvc3QtPmRhdGEgJiYgIShob3N0LT5kYXRhLT5mbGFncyAmIE1NQ19EQVRBX1dSSVRFKSkKCQljbWRyZWcgfD0gMSA8PCAxNTsKCgljbGtfZW5hYmxlKGhvc3QtPmZjbGspOwoKCU9NQVBfTU1DX1dSSVRFKGhvc3QtPmJhc2UsIENUTywgMjAwKTsKCU9NQVBfTU1DX1dSSVRFKGhvc3QtPmJhc2UsIEFSR0wsIGNtZC0+YXJnICYgMHhmZmZmKTsKCU9NQVBfTU1DX1dSSVRFKGhvc3QtPmJhc2UsIEFSR0gsIGNtZC0+YXJnID4+IDE2KTsKCU9NQVBfTU1DX1dSSVRFKGhvc3QtPmJhc2UsIElFLAoJCSAgICAgICBPTUFQX01NQ19TVEFUX0FfRU1QVFkgICAgfCBPTUFQX01NQ19TVEFUX0FfRlVMTCAgICB8CgkJICAgICAgIE9NQVBfTU1DX1NUQVRfQ01EX0NSQyAgICB8IE9NQVBfTU1DX1NUQVRfQ01EX1RPVVQgIHwKCQkgICAgICAgT01BUF9NTUNfU1RBVF9EQVRBX0NSQyAgIHwgT01BUF9NTUNfU1RBVF9EQVRBX1RPVVQgfAoJCSAgICAgICBPTUFQX01NQ19TVEFUX0VORF9PRl9DTUQgfCBPTUFQX01NQ19TVEFUX0NBUkRfRVJSICB8CgkJICAgICAgIE9NQVBfTU1DX1NUQVRfRU5EX09GX0RBVEEpOwoJT01BUF9NTUNfV1JJVEUoaG9zdC0+YmFzZSwgQ01ELCBjbWRyZWcpOwp9CgpzdGF0aWMgdm9pZAptbWNfb21hcF94ZmVyX2RvbmUoc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QsIHN0cnVjdCBtbWNfZGF0YSAqZGF0YSkKewoJaWYgKGhvc3QtPmRtYV9pbl91c2UpIHsKCQllbnVtIGRtYV9kYXRhX2RpcmVjdGlvbiBkbWFfZGF0YV9kaXI7CgoJCUJVR19PTihob3N0LT5kbWFfY2ggPCAwKTsKCQlpZiAoZGF0YS0+ZXJyb3IgIT0gTU1DX0VSUl9OT05FKQoJCQlvbWFwX3N0b3BfZG1hKGhvc3QtPmRtYV9jaCk7CgkJLyogUmVsZWFzZSBETUEgY2hhbm5lbCBsYXppbHkgKi8KCQltb2RfdGltZXIoJmhvc3QtPmRtYV90aW1lciwgamlmZmllcyArIEhaKTsKCQlpZiAoZGF0YS0+ZmxhZ3MgJiBNTUNfREFUQV9XUklURSkKCQkJZG1hX2RhdGFfZGlyID0gRE1BX1RPX0RFVklDRTsKCQllbHNlCgkJCWRtYV9kYXRhX2RpciA9IERNQV9GUk9NX0RFVklDRTsKCQlkbWFfdW5tYXBfc2cobW1jX2Rldihob3N0LT5tbWMpLCBkYXRhLT5zZywgaG9zdC0+c2dfbGVuLAoJCQkgICAgIGRtYV9kYXRhX2Rpcik7Cgl9Cglob3N0LT5kYXRhID0gTlVMTDsKCWhvc3QtPnNnX2xlbiA9IDA7CgljbGtfZGlzYWJsZShob3N0LT5mY2xrKTsKCgkvKiBOT1RFOiAgTU1DIGxheWVyIHdpbGwgc29tZXRpbWVzIHBvbGwtd2FpdCBDTUQxMyBuZXh0LCBpc3N1aW5nCgkgKiBkb3plbnMgb2YgcmVxdWVzdHMgdW50aWwgdGhlIGNhcmQgZmluaXNoZXMgd3JpdGluZyBkYXRhLgoJICogSXQnZCBiZSBjaGVhcGVyIHRvIGp1c3Qgd2FpdCB0aWxsIGFuIEVPRkIgaW50ZXJydXB0IGFycml2ZXMuLi4KCSAqLwoKCWlmICghZGF0YS0+c3RvcCkgewoJCWhvc3QtPm1ycSA9IE5VTEw7CgkJbW1jX3JlcXVlc3RfZG9uZShob3N0LT5tbWMsIGRhdGEtPm1ycSk7CgkJcmV0dXJuOwoJfQoKCW1tY19vbWFwX3N0YXJ0X2NvbW1hbmQoaG9zdCwgZGF0YS0+c3RvcCk7Cn0KCnN0YXRpYyB2b2lkCm1tY19vbWFwX2VuZF9vZl9kYXRhKHN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0LCBzdHJ1Y3QgbW1jX2RhdGEgKmRhdGEpCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CglpbnQgZG9uZTsKCglpZiAoIWhvc3QtPmRtYV9pbl91c2UpIHsKCQltbWNfb21hcF94ZmVyX2RvbmUoaG9zdCwgZGF0YSk7CgkJcmV0dXJuOwoJfQoJZG9uZSA9IDA7CglzcGluX2xvY2tfaXJxc2F2ZSgmaG9zdC0+ZG1hX2xvY2ssIGZsYWdzKTsKCWlmIChob3N0LT5kbWFfZG9uZSkKCQlkb25lID0gMTsKCWVsc2UKCQlob3N0LT5icnNfcmVjZWl2ZWQgPSAxOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmaG9zdC0+ZG1hX2xvY2ssIGZsYWdzKTsKCWlmIChkb25lKQoJCW1tY19vbWFwX3hmZXJfZG9uZShob3N0LCBkYXRhKTsKfQoKc3RhdGljIHZvaWQKbW1jX29tYXBfZG1hX3RpbWVyKHVuc2lnbmVkIGxvbmcgZGF0YSkKewoJc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QgPSAoc3RydWN0IG1tY19vbWFwX2hvc3QgKikgZGF0YTsKCglCVUdfT04oaG9zdC0+ZG1hX2NoIDwgMCk7CglvbWFwX2ZyZWVfZG1hKGhvc3QtPmRtYV9jaCk7Cglob3N0LT5kbWFfY2ggPSAtMTsKfQoKc3RhdGljIHZvaWQKbW1jX29tYXBfZG1hX2RvbmUoc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QsIHN0cnVjdCBtbWNfZGF0YSAqZGF0YSkKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCWludCBkb25lOwoKCWRvbmUgPSAwOwoJc3Bpbl9sb2NrX2lycXNhdmUoJmhvc3QtPmRtYV9sb2NrLCBmbGFncyk7CglpZiAoaG9zdC0+YnJzX3JlY2VpdmVkKQoJCWRvbmUgPSAxOwoJZWxzZQoJCWhvc3QtPmRtYV9kb25lID0gMTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmhvc3QtPmRtYV9sb2NrLCBmbGFncyk7CglpZiAoZG9uZSkKCQltbWNfb21hcF94ZmVyX2RvbmUoaG9zdCwgZGF0YSk7Cn0KCnN0YXRpYyB2b2lkCm1tY19vbWFwX2NtZF9kb25lKHN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0LCBzdHJ1Y3QgbW1jX2NvbW1hbmQgKmNtZCkKewoJaG9zdC0+Y21kID0gTlVMTDsKCglpZiAoY21kLT5mbGFncyAmIE1NQ19SU1BfUFJFU0VOVCkgewoJCWlmIChjbWQtPmZsYWdzICYgTU1DX1JTUF8xMzYpIHsKCQkJLyogcmVzcG9uc2UgdHlwZSAyICovCgkJCWNtZC0+cmVzcFszXSA9CgkJCQlPTUFQX01NQ19SRUFEKGhvc3QtPmJhc2UsIFJTUDApIHwKCQkJCShPTUFQX01NQ19SRUFEKGhvc3QtPmJhc2UsIFJTUDEpIDw8IDE2KTsKCQkJY21kLT5yZXNwWzJdID0KCQkJCU9NQVBfTU1DX1JFQUQoaG9zdC0+YmFzZSwgUlNQMikgfAoJCQkJKE9NQVBfTU1DX1JFQUQoaG9zdC0+YmFzZSwgUlNQMykgPDwgMTYpOwoJCQljbWQtPnJlc3BbMV0gPQoJCQkJT01BUF9NTUNfUkVBRChob3N0LT5iYXNlLCBSU1A0KSB8CgkJCQkoT01BUF9NTUNfUkVBRChob3N0LT5iYXNlLCBSU1A1KSA8PCAxNik7CgkJCWNtZC0+cmVzcFswXSA9CgkJCQlPTUFQX01NQ19SRUFEKGhvc3QtPmJhc2UsIFJTUDYpIHwKCQkJCShPTUFQX01NQ19SRUFEKGhvc3QtPmJhc2UsIFJTUDcpIDw8IDE2KTsKCQl9IGVsc2UgewoJCQkvKiByZXNwb25zZSB0eXBlcyAxLCAxYiwgMywgNCwgNSwgNiAqLwoJCQljbWQtPnJlc3BbMF0gPQoJCQkJT01BUF9NTUNfUkVBRChob3N0LT5iYXNlLCBSU1A2KSB8CgkJCQkoT01BUF9NTUNfUkVBRChob3N0LT5iYXNlLCBSU1A3KSA8PCAxNik7CgkJfQoJfQoKCWlmIChob3N0LT5kYXRhID09IE5VTEwgfHwgY21kLT5lcnJvciAhPSBNTUNfRVJSX05PTkUpIHsKCQlob3N0LT5tcnEgPSBOVUxMOwoJCWNsa19kaXNhYmxlKGhvc3QtPmZjbGspOwoJCW1tY19yZXF1ZXN0X2RvbmUoaG9zdC0+bW1jLCBjbWQtPm1ycSk7Cgl9Cn0KCi8qIFBJTyBvbmx5ICovCnN0YXRpYyB2b2lkCm1tY19vbWFwX3NnX3RvX2J1ZihzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCkKewoJc3RydWN0IHNjYXR0ZXJsaXN0ICpzZzsKCglzZyA9IGhvc3QtPmRhdGEtPnNnICsgaG9zdC0+c2dfaWR4OwoJaG9zdC0+YnVmZmVyX2J5dGVzX2xlZnQgPSBzZy0+bGVuZ3RoOwoJaG9zdC0+YnVmZmVyID0gcGFnZV9hZGRyZXNzKHNnLT5wYWdlKSArIHNnLT5vZmZzZXQ7CglpZiAoaG9zdC0+YnVmZmVyX2J5dGVzX2xlZnQgPiBob3N0LT50b3RhbF9ieXRlc19sZWZ0KQoJCWhvc3QtPmJ1ZmZlcl9ieXRlc19sZWZ0ID0gaG9zdC0+dG90YWxfYnl0ZXNfbGVmdDsKfQoKLyogUElPIG9ubHkgKi8Kc3RhdGljIHZvaWQKbW1jX29tYXBfeGZlcl9kYXRhKHN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0LCBpbnQgd3JpdGUpCnsKCWludCBuOwoJdm9pZCBfX2lvbWVtICpyZWc7Cgl1MTYgKnA7CgoJaWYgKGhvc3QtPmJ1ZmZlcl9ieXRlc19sZWZ0ID09IDApIHsKCQlob3N0LT5zZ19pZHgrKzsKCQlCVUdfT04oaG9zdC0+c2dfaWR4ID09IGhvc3QtPnNnX2xlbik7CgkJbW1jX29tYXBfc2dfdG9fYnVmKGhvc3QpOwoJfQoJbiA9IDY0OwoJaWYgKG4gPiBob3N0LT5idWZmZXJfYnl0ZXNfbGVmdCkKCQluID0gaG9zdC0+YnVmZmVyX2J5dGVzX2xlZnQ7Cglob3N0LT5idWZmZXJfYnl0ZXNfbGVmdCAtPSBuOwoJaG9zdC0+dG90YWxfYnl0ZXNfbGVmdCAtPSBuOwoJaG9zdC0+ZGF0YS0+Ynl0ZXNfeGZlcmVkICs9IG47CgoJaWYgKHdyaXRlKSB7CgkJX19yYXdfd3JpdGVzdyhob3N0LT5iYXNlICsgT01BUF9NTUNfUkVHX0RBVEEsIGhvc3QtPmJ1ZmZlciwgbik7Cgl9IGVsc2UgewoJCV9fcmF3X3JlYWRzdyhob3N0LT5iYXNlICsgT01BUF9NTUNfUkVHX0RBVEEsIGhvc3QtPmJ1ZmZlciwgbik7Cgl9Cn0KCnN0YXRpYyBpbmxpbmUgdm9pZCBtbWNfb21hcF9yZXBvcnRfaXJxKHUxNiBzdGF0dXMpCnsKCXN0YXRpYyBjb25zdCBjaGFyICptbWNfb21hcF9zdGF0dXNfYml0c1tdID0gewoJCSJFT0MiLCAiQ0QiLCAiQ0IiLCAiQlJTIiwgIkVPRkIiLCAiRFRPIiwgIkRDUkMiLCAiQ1RPIiwKCQkiQ0NSQyIsICJDUlciLCAiQUYiLCAiQUUiLCAiT0NSQiIsICJDSVJRIiwgIkNFUlIiCgl9OwoJaW50IGksIGMgPSAwOwoKCWZvciAoaSA9IDA7IGkgPCBBUlJBWV9TSVpFKG1tY19vbWFwX3N0YXR1c19iaXRzKTsgaSsrKQoJCWlmIChzdGF0dXMgJiAoMSA8PCBpKSkgewoJCQlpZiAoYykKCQkJCXByaW50aygiICIpOwoJCQlwcmludGsoIiVzIiwgbW1jX29tYXBfc3RhdHVzX2JpdHNbaV0pOwoJCQljKys7CgkJfQp9CgpzdGF0aWMgaXJxcmV0dXJuX3QgbW1jX29tYXBfaXJxKGludCBpcnEsIHZvaWQgKmRldl9pZCwgc3RydWN0IHB0X3JlZ3MgKnJlZ3MpCnsKCXN0cnVjdCBtbWNfb21hcF9ob3N0ICogaG9zdCA9IChzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqKWRldl9pZDsKCXUxNiBzdGF0dXM7CglpbnQgZW5kX2NvbW1hbmQ7CglpbnQgZW5kX3RyYW5zZmVyOwoJaW50IHRyYW5zZmVyX2Vycm9yOwoKCWlmIChob3N0LT5jbWQgPT0gTlVMTCAmJiBob3N0LT5kYXRhID09IE5VTEwpIHsKCQlzdGF0dXMgPSBPTUFQX01NQ19SRUFEKGhvc3QtPmJhc2UsIFNUQVQpOwoJCWRldl9pbmZvKG1tY19kZXYoaG9zdC0+bW1jKSwic3B1cmlvdXMgaXJxIDB4JTA0eFxuIiwgc3RhdHVzKTsKCQlpZiAoc3RhdHVzICE9IDApIHsKCQkJT01BUF9NTUNfV1JJVEUoaG9zdC0+YmFzZSwgU1RBVCwgc3RhdHVzKTsKCQkJT01BUF9NTUNfV1JJVEUoaG9zdC0+YmFzZSwgSUUsIDApOwoJCX0KCQlyZXR1cm4gSVJRX0hBTkRMRUQ7Cgl9CgoJZW5kX2NvbW1hbmQgPSAwOwoJZW5kX3RyYW5zZmVyID0gMDsKCXRyYW5zZmVyX2Vycm9yID0gMDsKCgl3aGlsZSAoKHN0YXR1cyA9IE9NQVBfTU1DX1JFQUQoaG9zdC0+YmFzZSwgU1RBVCkpICE9IDApIHsKCQlPTUFQX01NQ19XUklURShob3N0LT5iYXNlLCBTVEFULCBzdGF0dXMpOwojaWZkZWYgQ09ORklHX01NQ19ERUJVRwoJCWRldl9kYmcobW1jX2Rldihob3N0LT5tbWMpLCAiTU1DIElSUSAlMDR4IChDTUQgJWQpOiAiLAoJCQlzdGF0dXMsIGhvc3QtPmNtZCAhPSBOVUxMID8gaG9zdC0+Y21kLT5vcGNvZGUgOiAtMSk7CgkJbW1jX29tYXBfcmVwb3J0X2lycShzdGF0dXMpOwoJCXByaW50aygiXG4iKTsKI2VuZGlmCgkJaWYgKGhvc3QtPnRvdGFsX2J5dGVzX2xlZnQpIHsKCQkJaWYgKChzdGF0dXMgJiBPTUFQX01NQ19TVEFUX0FfRlVMTCkgfHwKCQkJICAgIChzdGF0dXMgJiBPTUFQX01NQ19TVEFUX0VORF9PRl9EQVRBKSkKCQkJCW1tY19vbWFwX3hmZXJfZGF0YShob3N0LCAwKTsKCQkJaWYgKHN0YXR1cyAmIE9NQVBfTU1DX1NUQVRfQV9FTVBUWSkKCQkJCW1tY19vbWFwX3hmZXJfZGF0YShob3N0LCAxKTsKCQl9CgoJCWlmIChzdGF0dXMgJiBPTUFQX01NQ19TVEFUX0VORF9PRl9EQVRBKSB7CgkJCWVuZF90cmFuc2ZlciA9IDE7CgkJfQoKCQlpZiAoc3RhdHVzICYgT01BUF9NTUNfU1RBVF9EQVRBX1RPVVQpIHsKCQkJZGV2X2RiZyhtbWNfZGV2KGhvc3QtPm1tYyksICJkYXRhIHRpbWVvdXRcbiIpOwoJCQlpZiAoaG9zdC0+ZGF0YSkgewoJCQkJaG9zdC0+ZGF0YS0+ZXJyb3IgfD0gTU1DX0VSUl9USU1FT1VUOwoJCQkJdHJhbnNmZXJfZXJyb3IgPSAxOwoJCQl9CgkJfQoKCQlpZiAoc3RhdHVzICYgT01BUF9NTUNfU1RBVF9EQVRBX0NSQykgewoJCQlpZiAoaG9zdC0+ZGF0YSkgewoJCQkJaG9zdC0+ZGF0YS0+ZXJyb3IgfD0gTU1DX0VSUl9CQURDUkM7CgkJCQlkZXZfZGJnKG1tY19kZXYoaG9zdC0+bW1jKSwKCQkJCQkgImRhdGEgQ1JDIGVycm9yLCBieXRlcyBsZWZ0ICVkXG4iLAoJCQkJCWhvc3QtPnRvdGFsX2J5dGVzX2xlZnQpOwoJCQkJdHJhbnNmZXJfZXJyb3IgPSAxOwoJCQl9IGVsc2UgewoJCQkJZGV2X2RiZyhtbWNfZGV2KGhvc3QtPm1tYyksICJkYXRhIENSQyBlcnJvclxuIik7CgkJCX0KCQl9CgoJCWlmIChzdGF0dXMgJiBPTUFQX01NQ19TVEFUX0NNRF9UT1VUKSB7CgkJCS8qIFRpbWVvdXRzIGFyZSByb3V0aW5lIHdpdGggc29tZSBjb21tYW5kcyAqLwoJCQlpZiAoaG9zdC0+Y21kKSB7CgkJCQlpZiAoaG9zdC0+Y21kLT5vcGNvZGUgIT0gTU1DX0FMTF9TRU5EX0NJRCAmJgoJCQkJCQlob3N0LT5jbWQtPm9wY29kZSAhPQoJCQkJCQlNTUNfU0VORF9PUF9DT05EICYmCgkJCQkJCWhvc3QtPmNtZC0+b3Bjb2RlICE9CgkJCQkJCU1NQ19BUFBfQ01EICYmCgkJCQkJCSFtbWNfb21hcF9jb3Zlcl9pc19vcGVuKGhvc3QpKQoJCQkJCWRldl9lcnIobW1jX2Rldihob3N0LT5tbWMpLAoJCQkJCQkiY29tbWFuZCB0aW1lb3V0LCBDTUQgJWRcbiIsCgkJCQkJCWhvc3QtPmNtZC0+b3Bjb2RlKTsKCQkJCWhvc3QtPmNtZC0+ZXJyb3IgPSBNTUNfRVJSX1RJTUVPVVQ7CgkJCQllbmRfY29tbWFuZCA9IDE7CgkJCX0KCQl9CgoJCWlmIChzdGF0dXMgJiBPTUFQX01NQ19TVEFUX0NNRF9DUkMpIHsKCQkJaWYgKGhvc3QtPmNtZCkgewoJCQkJZGV2X2VycihtbWNfZGV2KGhvc3QtPm1tYyksCgkJCQkJImNvbW1hbmQgQ1JDIGVycm9yIChDTUQlZCwgYXJnIDB4JTA4eClcbiIsCgkJCQkJaG9zdC0+Y21kLT5vcGNvZGUsIGhvc3QtPmNtZC0+YXJnKTsKCQkJCWhvc3QtPmNtZC0+ZXJyb3IgPSBNTUNfRVJSX0JBRENSQzsKCQkJCWVuZF9jb21tYW5kID0gMTsKCQkJfSBlbHNlCgkJCQlkZXZfZXJyKG1tY19kZXYoaG9zdC0+bW1jKSwKCQkJCQkiY29tbWFuZCBDUkMgZXJyb3Igd2l0aG91dCBjbWQ/XG4iKTsKCQl9CgoJCWlmIChzdGF0dXMgJiBPTUFQX01NQ19TVEFUX0NBUkRfRVJSKSB7CgkJCWlmIChob3N0LT5jbWQgJiYgaG9zdC0+Y21kLT5vcGNvZGUgPT0gTU1DX1NUT1BfVFJBTlNNSVNTSU9OKSB7CgkJCQl1MzIgcmVzcG9uc2UgPSBPTUFQX01NQ19SRUFEKGhvc3QtPmJhc2UsIFJTUDYpCgkJCQkJfCAoT01BUF9NTUNfUkVBRChob3N0LT5iYXNlLCBSU1A3KSA8PCAxNik7CgkJCQkvKiBTVE9QIHNvbWV0aW1lcyBzZXRzIG11c3QtaWdub3JlIGJpdHMgKi8KCQkJCWlmICghKHJlc3BvbnNlICYgKFIxX0NDX0VSUk9SCgkJCQkJCQkJfCBSMV9JTExFR0FMX0NPTU1BTkQKCQkJCQkJCQl8IFIxX0NPTV9DUkNfRVJST1IpKSkgewoJCQkJCWVuZF9jb21tYW5kID0gMTsKCQkJCQljb250aW51ZTsKCQkJCX0KCQkJfQoKCQkJZGV2X2RiZyhtbWNfZGV2KGhvc3QtPm1tYyksICJjYXJkIHN0YXR1cyBlcnJvciAoQ01EJWQpXG4iLAoJCQkJaG9zdC0+Y21kLT5vcGNvZGUpOwoJCQlpZiAoaG9zdC0+Y21kKSB7CgkJCQlob3N0LT5jbWQtPmVycm9yID0gTU1DX0VSUl9GQUlMRUQ7CgkJCQllbmRfY29tbWFuZCA9IDE7CgkJCX0KCQkJaWYgKGhvc3QtPmRhdGEpIHsKCQkJCWhvc3QtPmRhdGEtPmVycm9yID0gTU1DX0VSUl9GQUlMRUQ7CgkJCQl0cmFuc2Zlcl9lcnJvciA9IDE7CgkJCX0KCQl9CgoJCS8qCgkJICogTk9URTogT24gMTYxMCB0aGUgRU5EX09GX0NNRCBtYXkgY29tZSB0b28gZWFybHkgd2hlbgoJCSAqIHN0YXJ0aW5nIGEgd3JpdGUgCgkJICovCgkJaWYgKChzdGF0dXMgJiBPTUFQX01NQ19TVEFUX0VORF9PRl9DTUQpICYmCgkJICAgICghKHN0YXR1cyAmIE9NQVBfTU1DX1NUQVRfQV9FTVBUWSkpKSB7CgkJCWVuZF9jb21tYW5kID0gMTsKCQl9Cgl9CgoJaWYgKGVuZF9jb21tYW5kKSB7CgkJbW1jX29tYXBfY21kX2RvbmUoaG9zdCwgaG9zdC0+Y21kKTsKCX0KCWlmICh0cmFuc2Zlcl9lcnJvcikKCQltbWNfb21hcF94ZmVyX2RvbmUoaG9zdCwgaG9zdC0+ZGF0YSk7CgllbHNlIGlmIChlbmRfdHJhbnNmZXIpCgkJbW1jX29tYXBfZW5kX29mX2RhdGEoaG9zdCwgaG9zdC0+ZGF0YSk7CgoJcmV0dXJuIElSUV9IQU5ETEVEOwp9CgpzdGF0aWMgaXJxcmV0dXJuX3QgbW1jX29tYXBfc3dpdGNoX2lycShpbnQgaXJxLCB2b2lkICpkZXZfaWQsIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IChzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqKSBkZXZfaWQ7CgoJc2NoZWR1bGVfd29yaygmaG9zdC0+c3dpdGNoX3dvcmspOwoKCXJldHVybiBJUlFfSEFORExFRDsKfQoKc3RhdGljIHZvaWQgbW1jX29tYXBfc3dpdGNoX3RpbWVyKHVuc2lnbmVkIGxvbmcgYXJnKQp7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IChzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqKSBhcmc7CgoJc2NoZWR1bGVfd29yaygmaG9zdC0+c3dpdGNoX3dvcmspOwp9CgovKiBGSVhNRTogSGFuZGxlIGNhcmQgaW5zZXJ0aW9uIGFuZCByZW1vdmFsIHByb3Blcmx5LiBNYXliZSB1c2UgYSBtYXNrCiAqIGZvciBNTUMgc3RhdGU/ICovCnN0YXRpYyB2b2lkIG1tY19vbWFwX3N3aXRjaF9jYWxsYmFjayh1bnNpZ25lZCBsb25nIGRhdGEsIHU4IG1tY19tYXNrKQp7Cn0KCnN0YXRpYyB2b2lkIG1tY19vbWFwX3N3aXRjaF9oYW5kbGVyKHZvaWQgKmRhdGEpCnsKCXN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0ID0gKHN0cnVjdCBtbWNfb21hcF9ob3N0ICopIGRhdGE7CglzdHJ1Y3QgbW1jX2NhcmQgKmNhcmQ7CglzdGF0aWMgaW50IGNvbXBsYWluZWQgPSAwOwoJaW50IGNhcmRzID0gMCwgY292ZXJfb3BlbjsKCglpZiAoaG9zdC0+c3dpdGNoX3BpbiA9PSAtMSkKCQlyZXR1cm47Cgljb3Zlcl9vcGVuID0gbW1jX29tYXBfY292ZXJfaXNfb3Blbihob3N0KTsKCWlmIChjb3Zlcl9vcGVuICE9IGhvc3QtPnN3aXRjaF9sYXN0X3N0YXRlKSB7CgkJa29iamVjdF91ZXZlbnQoJmhvc3QtPmRldi0+a29iaiwgS09CSl9DSEFOR0UpOwoJCWhvc3QtPnN3aXRjaF9sYXN0X3N0YXRlID0gY292ZXJfb3BlbjsKCX0KCW1tY19kZXRlY3RfY2hhbmdlKGhvc3QtPm1tYywgMCk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KGNhcmQsICZob3N0LT5tbWMtPmNhcmRzLCBub2RlKSB7CgkJaWYgKG1tY19jYXJkX3ByZXNlbnQoY2FyZCkpCgkJCWNhcmRzKys7Cgl9CglpZiAobW1jX29tYXBfY292ZXJfaXNfb3Blbihob3N0KSkgewoJCWlmICghY29tcGxhaW5lZCkgewoJCQlkZXZfaW5mbyhtbWNfZGV2KGhvc3QtPm1tYyksICJjb3ZlciBpcyBvcGVuIik7CgkJCWNvbXBsYWluZWQgPSAxOwoJCX0KCQlpZiAobW1jX29tYXBfZW5hYmxlX3BvbGwpCgkJCW1vZF90aW1lcigmaG9zdC0+c3dpdGNoX3RpbWVyLCBqaWZmaWVzICsKCQkJCW1zZWNzX3RvX2ppZmZpZXMoT01BUF9NTUNfU1dJVENIX1BPTExfREVMQVkpKTsKCX0gZWxzZSB7CgkJY29tcGxhaW5lZCA9IDA7Cgl9Cn0KCi8qIFByZXBhcmUgdG8gdHJhbnNmZXIgdGhlIG5leHQgc2VnbWVudCBvZiBhIHNjYXR0ZXJsaXN0ICovCnN0YXRpYyB2b2lkCm1tY19vbWFwX3ByZXBhcmVfZG1hKHN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0LCBzdHJ1Y3QgbW1jX2RhdGEgKmRhdGEpCnsKCWludCBkbWFfY2ggPSBob3N0LT5kbWFfY2g7Cgl1bnNpZ25lZCBsb25nIGRhdGFfYWRkcjsKCXUxNiBidWYsIGZyYW1lOwoJdTMyIGNvdW50OwoJc3RydWN0IHNjYXR0ZXJsaXN0ICpzZyA9ICZkYXRhLT5zZ1tob3N0LT5zZ19pZHhdOwoJaW50IHNyY19wb3J0ID0gMDsKCWludCBkc3RfcG9ydCA9IDA7CglpbnQgc3luY19kZXYgPSAwOwoKCWRhdGFfYWRkciA9IGlvX3YycCgodTMyKSBob3N0LT5iYXNlKSArIE9NQVBfTU1DX1JFR19EQVRBOwoJZnJhbWUgPSBkYXRhLT5ibGtzejsKCWNvdW50ID0gc2dfZG1hX2xlbihzZyk7CgoJaWYgKChkYXRhLT5ibG9ja3MgPT0gMSkgJiYgKGNvdW50ID4gZGF0YS0+Ymxrc3opKQoJCWNvdW50ID0gZnJhbWU7CgoJaG9zdC0+ZG1hX2xlbiA9IGNvdW50OwoKCS8qIEZJRk8gaXMgMTZ4MiBieXRlcyBvbiAxNXh4LCBhbmQgMzJ4MiBieXRlcyBvbiAxNnh4IGFuZCAyNHh4LgoJICogVXNlIDE2IG9yIDMyIHdvcmQgZnJhbWVzIHdoZW4gdGhlIGJsb2Nrc2l6ZSBpcyBhdCBsZWFzdCB0aGF0IGxhcmdlLgoJICogQmxvY2tzaXplIGlzIHVzdWFsbHkgNTEyIGJ5dGVzOyBidXQgbm90IGZvciBzb21lIFNEIHJlYWRzLgoJICovCglpZiAoY3B1X2lzX29tYXAxNXh4KCkgJiYgZnJhbWUgPiAzMikKCQlmcmFtZSA9IDMyOwoJZWxzZSBpZiAoZnJhbWUgPiA2NCkKCQlmcmFtZSA9IDY0OwoJY291bnQgLz0gZnJhbWU7CglmcmFtZSA+Pj0gMTsKCglpZiAoIShkYXRhLT5mbGFncyAmIE1NQ19EQVRBX1dSSVRFKSkgewoJCWJ1ZiA9IDB4ODAwZiB8ICgoZnJhbWUgLSAxKSA8PCA4KTsKCgkJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKSB7CgkJCXNyY19wb3J0ID0gT01BUF9ETUFfUE9SVF9USVBCOwoJCQlkc3RfcG9ydCA9IE9NQVBfRE1BX1BPUlRfRU1JRkY7CgkJfQoJCWlmIChjcHVfaXNfb21hcDI0eHgoKSkKCQkJc3luY19kZXYgPSBPTUFQMjRYWF9ETUFfTU1DMV9SWDsKCgkJb21hcF9zZXRfZG1hX3NyY19wYXJhbXMoZG1hX2NoLCBzcmNfcG9ydCwKCQkJCQlPTUFQX0RNQV9BTU9ERV9DT05TVEFOVCwKCQkJCQlkYXRhX2FkZHIsIDAsIDApOwoJCW9tYXBfc2V0X2RtYV9kZXN0X3BhcmFtcyhkbWFfY2gsIGRzdF9wb3J0LAoJCQkJCSBPTUFQX0RNQV9BTU9ERV9QT1NUX0lOQywKCQkJCQkgc2dfZG1hX2FkZHJlc3Moc2cpLCAwLCAwKTsKCQlvbWFwX3NldF9kbWFfZGVzdF9kYXRhX3BhY2soZG1hX2NoLCAxKTsKCQlvbWFwX3NldF9kbWFfZGVzdF9idXJzdF9tb2RlKGRtYV9jaCwgT01BUF9ETUFfREFUQV9CVVJTVF80KTsKCX0gZWxzZSB7CgkJYnVmID0gMHgwZjgwIHwgKChmcmFtZSAtIDEpIDw8IDApOwoKCQlpZiAoY3B1X2NsYXNzX2lzX29tYXAxKCkpIHsKCQkJc3JjX3BvcnQgPSBPTUFQX0RNQV9QT1JUX0VNSUZGOwoJCQlkc3RfcG9ydCA9IE9NQVBfRE1BX1BPUlRfVElQQjsKCQl9CgkJaWYgKGNwdV9pc19vbWFwMjR4eCgpKQoJCQlzeW5jX2RldiA9IE9NQVAyNFhYX0RNQV9NTUMxX1RYOwoKCQlvbWFwX3NldF9kbWFfZGVzdF9wYXJhbXMoZG1hX2NoLCBkc3RfcG9ydCwKCQkJCQkgT01BUF9ETUFfQU1PREVfQ09OU1RBTlQsCgkJCQkJIGRhdGFfYWRkciwgMCwgMCk7CgkJb21hcF9zZXRfZG1hX3NyY19wYXJhbXMoZG1hX2NoLCBzcmNfcG9ydCwKCQkJCQlPTUFQX0RNQV9BTU9ERV9QT1NUX0lOQywKCQkJCQlzZ19kbWFfYWRkcmVzcyhzZyksIDAsIDApOwoJCW9tYXBfc2V0X2RtYV9zcmNfZGF0YV9wYWNrKGRtYV9jaCwgMSk7CgkJb21hcF9zZXRfZG1hX3NyY19idXJzdF9tb2RlKGRtYV9jaCwgT01BUF9ETUFfREFUQV9CVVJTVF80KTsKCX0KCgkvKiBNYXggbGltaXQgZm9yIERNQSBmcmFtZSBjb3VudCBpcyAweGZmZmYgKi8KCWlmICh1bmxpa2VseShjb3VudCA+IDB4ZmZmZikpCgkJQlVHKCk7CgoJT01BUF9NTUNfV1JJVEUoaG9zdC0+YmFzZSwgQlVGLCBidWYpOwoJb21hcF9zZXRfZG1hX3RyYW5zZmVyX3BhcmFtcyhkbWFfY2gsIE9NQVBfRE1BX0RBVEFfVFlQRV9TMTYsCgkJCQkgICAgIGZyYW1lLCBjb3VudCwgT01BUF9ETUFfU1lOQ19GUkFNRSwKCQkJCSAgICAgc3luY19kZXYsIDApOwp9CgovKiBBIHNjYXR0ZXJsaXN0IHNlZ21lbnQgY29tcGxldGVkICovCnN0YXRpYyB2b2lkIG1tY19vbWFwX2RtYV9jYihpbnQgbGNoLCB1MTYgY2hfc3RhdHVzLCB2b2lkICpkYXRhKQp7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IChzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqKSBkYXRhOwoJc3RydWN0IG1tY19kYXRhICptbWNkYXQgPSBob3N0LT5kYXRhOwoKCWlmICh1bmxpa2VseShob3N0LT5kbWFfY2ggPCAwKSkgewoJCWRldl9lcnIobW1jX2Rldihob3N0LT5tbWMpLCAiRE1BIGNhbGxiYWNrIHdoaWxlIERNQSBub3QKCQkJCWVuYWJsZWRcbiIpOwoJCXJldHVybjsKCX0KCS8qIEZJWE1FOiBXZSByZWFsbHkgc2hvdWxkIGRvIHNvbWV0aGluZyB0byBfaGFuZGxlXyB0aGUgZXJyb3JzICovCglpZiAoY2hfc3RhdHVzICYgT01BUF9ETUFfVE9VVF9JUlEpIHsKCQlkZXZfZXJyKG1tY19kZXYoaG9zdC0+bW1jKSwiRE1BIHRpbWVvdXRcbiIpOwoJCXJldHVybjsKCX0KCWlmIChjaF9zdGF0dXMgJiBPTUFQX0RNQV9EUk9QX0lSUSkgewoJCWRldl9lcnIobW1jX2Rldihob3N0LT5tbWMpLCAiRE1BIHN5bmMgZXJyb3JcbiIpOwoJCXJldHVybjsKCX0KCWlmICghKGNoX3N0YXR1cyAmIE9NQVBfRE1BX0JMT0NLX0lSUSkpIHsKCQlyZXR1cm47Cgl9CgltbWNkYXQtPmJ5dGVzX3hmZXJlZCArPSBob3N0LT5kbWFfbGVuOwoJaG9zdC0+c2dfaWR4Kys7CglpZiAoaG9zdC0+c2dfaWR4IDwgaG9zdC0+c2dfbGVuKSB7CgkJbW1jX29tYXBfcHJlcGFyZV9kbWEoaG9zdCwgaG9zdC0+ZGF0YSk7CgkJb21hcF9zdGFydF9kbWEoaG9zdC0+ZG1hX2NoKTsKCX0gZWxzZQoJCW1tY19vbWFwX2RtYV9kb25lKGhvc3QsIGhvc3QtPmRhdGEpOwp9CgpzdGF0aWMgaW50IG1tY19vbWFwX2dldF9kbWFfY2hhbm5lbChzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19kYXRhICpkYXRhKQp7Cgljb25zdCBjaGFyICpkZXZfbmFtZTsKCWludCBzeW5jX2RldiwgZG1hX2NoLCBpc19yZWFkLCByOwoKCWlzX3JlYWQgPSAhKGRhdGEtPmZsYWdzICYgTU1DX0RBVEFfV1JJVEUpOwoJZGVsX3RpbWVyX3N5bmMoJmhvc3QtPmRtYV90aW1lcik7CglpZiAoaG9zdC0+ZG1hX2NoID49IDApIHsKCQlpZiAoaXNfcmVhZCA9PSBob3N0LT5kbWFfaXNfcmVhZCkKCQkJcmV0dXJuIDA7CgkJb21hcF9mcmVlX2RtYShob3N0LT5kbWFfY2gpOwoJCWhvc3QtPmRtYV9jaCA9IC0xOwoJfQoKCWlmIChpc19yZWFkKSB7CgkJaWYgKGhvc3QtPmlkID09IDEpIHsKCQkJc3luY19kZXYgPSBPTUFQX0RNQV9NTUNfUlg7CgkJCWRldl9uYW1lID0gIk1NQzEgcmVhZCI7CgkJfSBlbHNlIHsKCQkJc3luY19kZXYgPSBPTUFQX0RNQV9NTUMyX1JYOwoJCQlkZXZfbmFtZSA9ICJNTUMyIHJlYWQiOwoJCX0KCX0gZWxzZSB7CgkJaWYgKGhvc3QtPmlkID09IDEpIHsKCQkJc3luY19kZXYgPSBPTUFQX0RNQV9NTUNfVFg7CgkJCWRldl9uYW1lID0gIk1NQzEgd3JpdGUiOwoJCX0gZWxzZSB7CgkJCXN5bmNfZGV2ID0gT01BUF9ETUFfTU1DMl9UWDsKCQkJZGV2X25hbWUgPSAiTU1DMiB3cml0ZSI7CgkJfQoJfQoJciA9IG9tYXBfcmVxdWVzdF9kbWEoc3luY19kZXYsIGRldl9uYW1lLCBtbWNfb21hcF9kbWFfY2IsCgkJCSAgICAgaG9zdCwgJmRtYV9jaCk7CglpZiAociAhPSAwKSB7CgkJZGV2X2RiZyhtbWNfZGV2KGhvc3QtPm1tYyksICJvbWFwX3JlcXVlc3RfZG1hKCkgZmFpbGVkIHdpdGggJWRcbiIsIHIpOwoJCXJldHVybiByOwoJfQoJaG9zdC0+ZG1hX2NoID0gZG1hX2NoOwoJaG9zdC0+ZG1hX2lzX3JlYWQgPSBpc19yZWFkOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgc2V0X2NtZF90aW1lb3V0KHN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0LCBzdHJ1Y3QgbW1jX3JlcXVlc3QgKnJlcSkKewoJdTE2IHJlZzsKCglyZWcgPSBPTUFQX01NQ19SRUFEKGhvc3QtPmJhc2UsIFNESU8pOwoJcmVnICY9IH4oMSA8PCA1KTsKCU9NQVBfTU1DX1dSSVRFKGhvc3QtPmJhc2UsIFNESU8sIHJlZyk7CgkvKiBTZXQgbWF4aW11bSB0aW1lb3V0ICovCglPTUFQX01NQ19XUklURShob3N0LT5iYXNlLCBDVE8sIDB4ZmYpOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQgc2V0X2RhdGFfdGltZW91dChzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19yZXF1ZXN0ICpyZXEpCnsKCWludCB0aW1lb3V0OwoJdTE2IHJlZzsKCgkvKiBDb252ZXJ0IG5zIHRvIGNsb2NrIGN5Y2xlcyBieSBhc3N1bWluZyAyME1IeiBmcmVxdWVuY3kKCSAqIDEgY3ljbGUgYXQgMjBNSHogPSA1MDAgbnMKCSAqLwoJdGltZW91dCA9IHJlcS0+ZGF0YS0+dGltZW91dF9jbGtzICsgcmVxLT5kYXRhLT50aW1lb3V0X25zIC8gNTAwOwoKCS8qIENoZWNrIGlmIHdlIG5lZWQgdG8gdXNlIHRpbWVvdXQgbXVsdGlwbGllciByZWdpc3RlciAqLwoJcmVnID0gT01BUF9NTUNfUkVBRChob3N0LT5iYXNlLCBTRElPKTsKCWlmICh0aW1lb3V0ID4gMHhmZmZmKSB7CgkJcmVnIHw9ICgxIDw8IDUpOwoJCXRpbWVvdXQgLz0gMTAyNDsKCX0gZWxzZQoJCXJlZyAmPSB+KDEgPDwgNSk7CglPTUFQX01NQ19XUklURShob3N0LT5iYXNlLCBTRElPLCByZWcpOwoJT01BUF9NTUNfV1JJVEUoaG9zdC0+YmFzZSwgRFRPLCB0aW1lb3V0KTsKfQoKc3RhdGljIHZvaWQKbW1jX29tYXBfcHJlcGFyZV9kYXRhKHN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0LCBzdHJ1Y3QgbW1jX3JlcXVlc3QgKnJlcSkKewoJc3RydWN0IG1tY19kYXRhICpkYXRhID0gcmVxLT5kYXRhOwoJaW50IGksIHVzZV9kbWEsIGJsb2NrX3NpemU7Cgl1bnNpZ25lZCBzZ19sZW47CgoJaG9zdC0+ZGF0YSA9IGRhdGE7CglpZiAoZGF0YSA9PSBOVUxMKSB7CgkJT01BUF9NTUNfV1JJVEUoaG9zdC0+YmFzZSwgQkxFTiwgMCk7CgkJT01BUF9NTUNfV1JJVEUoaG9zdC0+YmFzZSwgTkJMSywgMCk7CgkJT01BUF9NTUNfV1JJVEUoaG9zdC0+YmFzZSwgQlVGLCAwKTsKCQlob3N0LT5kbWFfaW5fdXNlID0gMDsKCQlzZXRfY21kX3RpbWVvdXQoaG9zdCwgcmVxKTsKCQlyZXR1cm47Cgl9CgoKCWJsb2NrX3NpemUgPSBkYXRhLT5ibGtzejsKCglPTUFQX01NQ19XUklURShob3N0LT5iYXNlLCBOQkxLLCBkYXRhLT5ibG9ja3MgLSAxKTsKCU9NQVBfTU1DX1dSSVRFKGhvc3QtPmJhc2UsIEJMRU4sIGJsb2NrX3NpemUgLSAxKTsKCXNldF9kYXRhX3RpbWVvdXQoaG9zdCwgcmVxKTsKCgkvKiBjb3BlIHdpdGggY2FsbGluZyBsYXllciBjb25mdXNpb247IGl0IGlzc3VlcyAic2luZ2xlCgkgKiBibG9jayIgd3JpdGVzIHVzaW5nIG11bHRpLWJsb2NrIHNjYXR0ZXJsaXN0cy4KCSAqLwoJc2dfbGVuID0gKGRhdGEtPmJsb2NrcyA9PSAxKSA/IDEgOiBkYXRhLT5zZ19sZW47CgoJLyogT25seSBkbyBETUEgZm9yIGVudGlyZSBibG9ja3MgKi8KCXVzZV9kbWEgPSBob3N0LT51c2VfZG1hOwoJaWYgKHVzZV9kbWEpIHsKCQlmb3IgKGkgPSAwOyBpIDwgc2dfbGVuOyBpKyspIHsKCQkJaWYgKChkYXRhLT5zZ1tpXS5sZW5ndGggJSBibG9ja19zaXplKSAhPSAwKSB7CgkJCQl1c2VfZG1hID0gMDsKCQkJCWJyZWFrOwoJCQl9CgkJfQoJfQoKCWhvc3QtPnNnX2lkeCA9IDA7CglpZiAodXNlX2RtYSkgewoJCWlmIChtbWNfb21hcF9nZXRfZG1hX2NoYW5uZWwoaG9zdCwgZGF0YSkgPT0gMCkgewoJCQllbnVtIGRtYV9kYXRhX2RpcmVjdGlvbiBkbWFfZGF0YV9kaXI7CgoJCQlpZiAoZGF0YS0+ZmxhZ3MgJiBNTUNfREFUQV9XUklURSkKCQkJCWRtYV9kYXRhX2RpciA9IERNQV9UT19ERVZJQ0U7CgkJCWVsc2UKCQkJCWRtYV9kYXRhX2RpciA9IERNQV9GUk9NX0RFVklDRTsKCgkJCWhvc3QtPnNnX2xlbiA9IGRtYV9tYXBfc2cobW1jX2Rldihob3N0LT5tbWMpLCBkYXRhLT5zZywKCQkJCQkJc2dfbGVuLCBkbWFfZGF0YV9kaXIpOwoJCQlob3N0LT50b3RhbF9ieXRlc19sZWZ0ID0gMDsKCQkJbW1jX29tYXBfcHJlcGFyZV9kbWEoaG9zdCwgcmVxLT5kYXRhKTsKCQkJaG9zdC0+YnJzX3JlY2VpdmVkID0gMDsKCQkJaG9zdC0+ZG1hX2RvbmUgPSAwOwoJCQlob3N0LT5kbWFfaW5fdXNlID0gMTsKCQl9IGVsc2UKCQkJdXNlX2RtYSA9IDA7Cgl9CgoJLyogUmV2ZXJ0IHRvIFBJTz8gKi8KCWlmICghdXNlX2RtYSkgewoJCU9NQVBfTU1DX1dSSVRFKGhvc3QtPmJhc2UsIEJVRiwgMHgxZjFmKTsKCQlob3N0LT50b3RhbF9ieXRlc19sZWZ0ID0gZGF0YS0+YmxvY2tzICogYmxvY2tfc2l6ZTsKCQlob3N0LT5zZ19sZW4gPSBzZ19sZW47CgkJbW1jX29tYXBfc2dfdG9fYnVmKGhvc3QpOwoJCWhvc3QtPmRtYV9pbl91c2UgPSAwOwoJfQp9CgpzdGF0aWMgdm9pZCBtbWNfb21hcF9yZXF1ZXN0KHN0cnVjdCBtbWNfaG9zdCAqbW1jLCBzdHJ1Y3QgbW1jX3JlcXVlc3QgKnJlcSkKewoJc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QgPSBtbWNfcHJpdihtbWMpOwoKCVdBUk5fT04oaG9zdC0+bXJxICE9IE5VTEwpOwoKCWhvc3QtPm1ycSA9IHJlcTsKCgkvKiBvbmx5IHRvdWNoIGZpZm8gQUZURVIgdGhlIGNvbnRyb2xsZXIgcmVhZGllcyBpdCAqLwoJbW1jX29tYXBfcHJlcGFyZV9kYXRhKGhvc3QsIHJlcSk7CgltbWNfb21hcF9zdGFydF9jb21tYW5kKGhvc3QsIHJlcS0+Y21kKTsKCWlmIChob3N0LT5kbWFfaW5fdXNlKQoJCW9tYXBfc3RhcnRfZG1hKGhvc3QtPmRtYV9jaCk7Cn0KCnN0YXRpYyB2b2lkIGlubm92YXRvcl9mcGdhX3NvY2tldF9wb3dlcihpbnQgb24pCnsKI2lmIGRlZmluZWQoQ09ORklHX01BQ0hfT01BUF9JTk5PVkFUT1IpICYmIGRlZmluZWQoQ09ORklHX0FSQ0hfT01BUDE1WFgpCgoJaWYgKG9uKSB7CgkJZnBnYV93cml0ZShmcGdhX3JlYWQoT01BUDE1MTBfRlBHQV9QT1dFUikgfCAoMSA8PCAzKSwKCQkgICAgIE9NQVAxNTEwX0ZQR0FfUE9XRVIpOwoJfSBlbHNlIHsKCQlmcGdhX3dyaXRlKGZwZ2FfcmVhZChPTUFQMTUxMF9GUEdBX1BPV0VSKSAmIH4oMSA8PCAzKSwKCQkgICAgIE9NQVAxNTEwX0ZQR0FfUE9XRVIpOwoJfQojZW5kaWYKfQoKLyoKICogVHVybiB0aGUgc29ja2V0IHBvd2VyIG9uL29mZi4gSW5ub3ZhdG9yIHVzZXMgRlBHQSwgbW9zdCBib2FyZHMKICogcHJvYmFibHkgdXNlIEdQSU8uCiAqLwpzdGF0aWMgdm9pZCBtbWNfb21hcF9wb3dlcihzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgaW50IG9uKQp7CglpZiAob24pIHsKCQlpZiAobWFjaGluZV9pc19vbWFwX2lubm92YXRvcigpKQoJCQlpbm5vdmF0b3JfZnBnYV9zb2NrZXRfcG93ZXIoMSk7CgkJZWxzZSBpZiAobWFjaGluZV9pc19vbWFwX2gyKCkpCgkJCXRwczY1MDEwX3NldF9ncGlvX291dF92YWx1ZShHUElPMywgSElHSCk7CgkJZWxzZSBpZiAobWFjaGluZV9pc19vbWFwX2gzKCkpCgkJCS8qIEdQSU8gNCBvZiBUUFM2NTAxMCBzZW5kcyBTRF9FTiBzaWduYWwgKi8KCQkJdHBzNjUwMTBfc2V0X2dwaW9fb3V0X3ZhbHVlKEdQSU80LCBISUdIKTsKCQllbHNlIGlmIChjcHVfaXNfb21hcDI0eHgoKSkgewoJCQl1MTYgcmVnID0gT01BUF9NTUNfUkVBRChob3N0LT5iYXNlLCBDT04pOwoJCQlPTUFQX01NQ19XUklURShob3N0LT5iYXNlLCBDT04sIHJlZyB8ICgxIDw8IDExKSk7CgkJfSBlbHNlCgkJCWlmIChob3N0LT5wb3dlcl9waW4gPj0gMCkKCQkJCW9tYXBfc2V0X2dwaW9fZGF0YW91dChob3N0LT5wb3dlcl9waW4sIDEpOwoJfSBlbHNlIHsKCQlpZiAobWFjaGluZV9pc19vbWFwX2lubm92YXRvcigpKQoJCQlpbm5vdmF0b3JfZnBnYV9zb2NrZXRfcG93ZXIoMCk7CgkJZWxzZSBpZiAobWFjaGluZV9pc19vbWFwX2gyKCkpCgkJCXRwczY1MDEwX3NldF9ncGlvX291dF92YWx1ZShHUElPMywgTE9XKTsKCQllbHNlIGlmIChtYWNoaW5lX2lzX29tYXBfaDMoKSkKCQkJdHBzNjUwMTBfc2V0X2dwaW9fb3V0X3ZhbHVlKEdQSU80LCBMT1cpOwoJCWVsc2UgaWYgKGNwdV9pc19vbWFwMjR4eCgpKSB7CgkJCXUxNiByZWcgPSBPTUFQX01NQ19SRUFEKGhvc3QtPmJhc2UsIENPTik7CgkJCU9NQVBfTU1DX1dSSVRFKGhvc3QtPmJhc2UsIENPTiwgcmVnICYgfigxIDw8IDExKSk7CgkJfSBlbHNlCgkJCWlmIChob3N0LT5wb3dlcl9waW4gPj0gMCkKCQkJCW9tYXBfc2V0X2dwaW9fZGF0YW91dChob3N0LT5wb3dlcl9waW4sIDApOwoJfQp9CgpzdGF0aWMgdm9pZCBtbWNfb21hcF9zZXRfaW9zKHN0cnVjdCBtbWNfaG9zdCAqbW1jLCBzdHJ1Y3QgbW1jX2lvcyAqaW9zKQp7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IG1tY19wcml2KG1tYyk7CglpbnQgZHNvcjsKCWludCByZWFsY2xvY2ssIGk7CgoJcmVhbGNsb2NrID0gaW9zLT5jbG9jazsKCglpZiAoaW9zLT5jbG9jayA9PSAwKQoJCWRzb3IgPSAwOwoJZWxzZSB7CgkJaW50IGZ1bmNfY2xrX3JhdGUgPSBjbGtfZ2V0X3JhdGUoaG9zdC0+ZmNsayk7CgoJCWRzb3IgPSBmdW5jX2Nsa19yYXRlIC8gcmVhbGNsb2NrOwoJCWlmIChkc29yIDwgMSkKCQkJZHNvciA9IDE7CgoJCWlmIChmdW5jX2Nsa19yYXRlIC8gZHNvciA+IHJlYWxjbG9jaykKCQkJZHNvcisrOwoKCQlpZiAoZHNvciA+IDI1MCkKCQkJZHNvciA9IDI1MDsKCQlkc29yKys7CgoJCWlmIChpb3MtPmJ1c193aWR0aCA9PSBNTUNfQlVTX1dJRFRIXzQpCgkJCWRzb3IgfD0gMSA8PCAxNTsKCX0KCglzd2l0Y2ggKGlvcy0+cG93ZXJfbW9kZSkgewoJY2FzZSBNTUNfUE9XRVJfT0ZGOgoJCW1tY19vbWFwX3Bvd2VyKGhvc3QsIDApOwoJCWJyZWFrOwoJY2FzZSBNTUNfUE9XRVJfVVA6CgljYXNlIE1NQ19QT1dFUl9PTjoKCQltbWNfb21hcF9wb3dlcihob3N0LCAxKTsKCQlkc29yIHw9IDE8PDExOwoJCWJyZWFrOwoJfQoKCWhvc3QtPmJ1c19tb2RlID0gaW9zLT5idXNfbW9kZTsKCWhvc3QtPmh3X2J1c19tb2RlID0gaG9zdC0+YnVzX21vZGU7CgoJY2xrX2VuYWJsZShob3N0LT5mY2xrKTsKCgkvKiBPbiBpbnNhbmVseSBoaWdoIGFybV9wZXIgZnJlcXVlbmNpZXMgc29tZXRoaW5nIHNvbWV0aW1lcwoJICogZ29lcyBzb21laG93IG91dCBvZiBzeW5jLCBhbmQgdGhlIFBPVyBiaXQgaXMgbm90IGJlaW5nIHNldCwKCSAqIHdoaWNoIHJlc3VsdHMgaW4gdGhlIHdoaWxlIGxvb3AgYmVsb3cgZ2V0dGluZyBzdHVjay4KCSAqIFdyaXRpbmcgdG8gdGhlIENPTiByZWdpc3RlciB0d2ljZSBzZWVtcyB0byBkbyB0aGUgdHJpY2suICovCglmb3IgKGkgPSAwOyBpIDwgMjsgaSsrKQoJCU9NQVBfTU1DX1dSSVRFKGhvc3QtPmJhc2UsIENPTiwgZHNvcik7CglpZiAoaW9zLT5wb3dlcl9tb2RlID09IE1NQ19QT1dFUl9VUCkgewoJCS8qIFNlbmQgY2xvY2sgY3ljbGVzLCBwb2xsIGNvbXBsZXRpb24gKi8KCQlPTUFQX01NQ19XUklURShob3N0LT5iYXNlLCBJRSwgMCk7CgkJT01BUF9NTUNfV1JJVEUoaG9zdC0+YmFzZSwgU1RBVCwgMHhmZmZmKTsKCQlPTUFQX01NQ19XUklURShob3N0LT5iYXNlLCBDTUQsIDE8PDcpOwoJCXdoaWxlICgwID09IChPTUFQX01NQ19SRUFEKGhvc3QtPmJhc2UsIFNUQVQpICYgMSkpOwoJCU9NQVBfTU1DX1dSSVRFKGhvc3QtPmJhc2UsIFNUQVQsIDEpOwoJfQoJY2xrX2Rpc2FibGUoaG9zdC0+ZmNsayk7Cn0KCnN0YXRpYyBpbnQgbW1jX29tYXBfZ2V0X3JvKHN0cnVjdCBtbWNfaG9zdCAqbW1jKQp7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IG1tY19wcml2KG1tYyk7CgoJcmV0dXJuIGhvc3QtPndwX3BpbiAmJiBvbWFwX2dldF9ncGlvX2RhdGFpbihob3N0LT53cF9waW4pOwp9CgpzdGF0aWMgc3RydWN0IG1tY19ob3N0X29wcyBtbWNfb21hcF9vcHMgPSB7CgkucmVxdWVzdAk9IG1tY19vbWFwX3JlcXVlc3QsCgkuc2V0X2lvcwk9IG1tY19vbWFwX3NldF9pb3MsCgkuZ2V0X3JvCQk9IG1tY19vbWFwX2dldF9ybywKfTsKCnN0YXRpYyBpbnQgX19pbml0IG1tY19vbWFwX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCnsKCXN0cnVjdCBvbWFwX21tY19jb25mICptaW5mbyA9IHBkZXYtPmRldi5wbGF0Zm9ybV9kYXRhOwoJc3RydWN0IG1tY19ob3N0ICptbWM7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IE5VTEw7CglpbnQgcmV0ID0gMDsKCQoJaWYgKHBsYXRmb3JtX2dldF9yZXNvdXJjZShwZGV2LCBJT1JFU09VUkNFX01FTSwgMCkgfHwKCQkJcGxhdGZvcm1fZ2V0X2lycShwZGV2LCBJT1JFU09VUkNFX0lSUSwgMCkpIHsKCQlkZXZfZXJyKCZwZGV2LT5kZXYsICJtbWNfb21hcF9wcm9iZTogaW52YWxpZCByZXNvdXJjZSB0eXBlXG4iKTsKCQlyZXR1cm4gLUVOT0RFVjsKCX0KCglpZiAoIXJlcXVlc3RfbWVtX3JlZ2lvbihwZGV2LT5yZXNvdXJjZVswXS5zdGFydCwKCQkJCXBkZXYtPnJlc291cmNlWzBdLmVuZCAtIHBkZXYtPnJlc291cmNlWzBdLnN0YXJ0ICsgMSwKCQkJCXBkZXYtPm5hbWUpKSB7CgkJZGV2X2RiZygmcGRldi0+ZGV2LCAicmVxdWVzdF9tZW1fcmVnaW9uIGZhaWxlZFxuIik7CgkJcmV0dXJuIC1FQlVTWTsKCX0KCgltbWMgPSBtbWNfYWxsb2NfaG9zdChzaXplb2Yoc3RydWN0IG1tY19vbWFwX2hvc3QpLCAmcGRldi0+ZGV2KTsKCWlmICghbW1jKSB7CgkJcmV0ID0gLUVOT01FTTsKCQlnb3RvIG91dDsKCX0KCglob3N0ID0gbW1jX3ByaXYobW1jKTsKCWhvc3QtPm1tYyA9IG1tYzsKCglzcGluX2xvY2tfaW5pdCgmaG9zdC0+ZG1hX2xvY2spOwoJaW5pdF90aW1lcigmaG9zdC0+ZG1hX3RpbWVyKTsKCWhvc3QtPmRtYV90aW1lci5mdW5jdGlvbiA9IG1tY19vbWFwX2RtYV90aW1lcjsKCWhvc3QtPmRtYV90aW1lci5kYXRhID0gKHVuc2lnbmVkIGxvbmcpIGhvc3Q7CgoJaG9zdC0+aWQgPSBwZGV2LT5pZDsKCglpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQlob3N0LT5pY2xrID0gY2xrX2dldCgmcGRldi0+ZGV2LCAibW1jX2ljayIpOwoJCWlmIChJU19FUlIoaG9zdC0+aWNsaykpCgkJCWdvdG8gb3V0OwoJCWNsa19lbmFibGUoaG9zdC0+aWNsayk7Cgl9CgoJaWYgKCFjcHVfaXNfb21hcDI0eHgoKSkKCQlob3N0LT5mY2xrID0gY2xrX2dldCgmcGRldi0+ZGV2LCAibW1jX2NrIik7CgllbHNlCgkJaG9zdC0+ZmNsayA9IGNsa19nZXQoJnBkZXYtPmRldiwgIm1tY19mY2siKTsKCglpZiAoSVNfRVJSKGhvc3QtPmZjbGspKSB7CgkJcmV0ID0gUFRSX0VSUihob3N0LT5mY2xrKTsKCQlnb3RvIG91dDsKCX0KCgkvKiBSRVZJU0lUOgoJICogQWxzbywgdXNlIG1pbmZvLT5jb3ZlciB0byBkZWNpZGUgaG93IHRvIG1hbmFnZQoJICogdGhlIGNhcmQgZGV0ZWN0IHNlbnNpbmcuCgkgKi8KCWhvc3QtPnBvd2VyX3BpbiA9IG1pbmZvLT5wb3dlcl9waW47Cglob3N0LT5zd2l0Y2hfcGluID0gbWluZm8tPnN3aXRjaF9waW47Cglob3N0LT53cF9waW4gPSBtaW5mby0+d3BfcGluOwoJaG9zdC0+dXNlX2RtYSA9IDE7Cglob3N0LT5kbWFfY2ggPSAtMTsKCglob3N0LT5pcnEgPSBwZGV2LT5yZXNvdXJjZVsxXS5zdGFydDsKCWhvc3QtPmJhc2UgPSBpb3JlbWFwKHBkZXYtPnJlcy5zdGFydCwgU1pfNEspOwoJaWYgKCFob3N0LT5iYXNlKSB7CgkJcmV0ID0gLUVOT01FTTsKCQlnb3RvIG91dDsKCX0KCgkgaWYgKG1pbmZvLT53aXJlNCkKCQkgbW1jLT5jYXBzIHw9IE1NQ19DQVBfNF9CSVRfREFUQTsKCgltbWMtPm9wcyA9ICZtbWNfb21hcF9vcHM7CgltbWMtPmZfbWluID0gNDAwMDAwOwoJbW1jLT5mX21heCA9IDI0MDAwMDAwOwoJbW1jLT5vY3JfYXZhaWwgPSBNTUNfVkREXzMyXzMzfE1NQ19WRERfMzNfMzQ7CgoJLyogVXNlIHNjYXR0ZXJsaXN0IERNQSB0byByZWR1Y2UgcGVyLXRyYW5zZmVyIGNvc3RzLgoJICogTk9URSBtYXhfc2VnX3NpemUgYXNzdW1wdGlvbiB0aGF0IHNtYWxsIGJsb2NrcyBhcmVuJ3QKCSAqIG5vcm1hbGx5IHVzZWQgKGV4Y2VwdCBlLmcuIGZvciByZWFkaW5nIFNEIHJlZ2lzdGVycykuCgkgKi8KCW1tYy0+bWF4X3BoeXNfc2VncyA9IDMyOwoJbW1jLT5tYXhfaHdfc2VncyA9IDMyOwoJbW1jLT5tYXhfc2VjdG9ycyA9IDI1NjsgLyogTkJMSyBtYXggMTEtYml0cywgT01BUCBhbHNvIGxpbWl0ZWQgYnkgRE1BICovCgltbWMtPm1heF9zZWdfc2l6ZSA9IG1tYy0+bWF4X3NlY3RvcnMgKiA1MTI7CgoJaWYgKGhvc3QtPnBvd2VyX3BpbiA+PSAwKSB7CgkJaWYgKChyZXQgPSBvbWFwX3JlcXVlc3RfZ3Bpbyhob3N0LT5wb3dlcl9waW4pKSAhPSAwKSB7CgkJCWRldl9lcnIobW1jX2Rldihob3N0LT5tbWMpLCAiVW5hYmxlIHRvIGdldCBHUElPCgkJCQkJcGluIGZvciBNTUMgcG93ZXJcbiIpOwoJCQlnb3RvIG91dDsKCQl9CgkJb21hcF9zZXRfZ3Bpb19kaXJlY3Rpb24oaG9zdC0+cG93ZXJfcGluLCAwKTsKCX0KCglyZXQgPSByZXF1ZXN0X2lycShob3N0LT5pcnEsIG1tY19vbWFwX2lycSwgMCwgRFJJVkVSX05BTUUsIGhvc3QpOwoJaWYgKHJldCkKCQlnb3RvIG91dDsKCglob3N0LT5kZXYgPSAmcGRldi0+ZGV2OwoJcGxhdGZvcm1fc2V0X2RydmRhdGEocGRldiwgaG9zdCk7CgoJbW1jX2FkZF9ob3N0KG1tYyk7CgoJaWYgKGhvc3QtPnN3aXRjaF9waW4gPj0gMCkgewoJCUlOSVRfV09SSygmaG9zdC0+c3dpdGNoX3dvcmssIG1tY19vbWFwX3N3aXRjaF9oYW5kbGVyLCBob3N0KTsKCQlpbml0X3RpbWVyKCZob3N0LT5zd2l0Y2hfdGltZXIpOwoJCWhvc3QtPnN3aXRjaF90aW1lci5mdW5jdGlvbiA9IG1tY19vbWFwX3N3aXRjaF90aW1lcjsKCQlob3N0LT5zd2l0Y2hfdGltZXIuZGF0YSA9ICh1bnNpZ25lZCBsb25nKSBob3N0OwoJCWlmIChvbWFwX3JlcXVlc3RfZ3Bpbyhob3N0LT5zd2l0Y2hfcGluKSAhPSAwKSB7CgkJCWRldl93YXJuKG1tY19kZXYoaG9zdC0+bW1jKSwgIlVuYWJsZSB0byBnZXQgR1BJTyBwaW4gZm9yIE1NQyBjb3ZlciBzd2l0Y2hcbiIpOwoJCQlob3N0LT5zd2l0Y2hfcGluID0gLTE7CgkJCWdvdG8gbm9fc3dpdGNoOwoJCX0KCgkJb21hcF9zZXRfZ3Bpb19kaXJlY3Rpb24oaG9zdC0+c3dpdGNoX3BpbiwgMSk7CgkJcmV0ID0gcmVxdWVzdF9pcnEoT01BUF9HUElPX0lSUShob3N0LT5zd2l0Y2hfcGluKSwKCQkJCSAgbW1jX29tYXBfc3dpdGNoX2lycSwgU0FfVFJJR0dFUl9SSVNJTkcsIERSSVZFUl9OQU1FLCBob3N0KTsKCQlpZiAocmV0KSB7CgkJCWRldl93YXJuKG1tY19kZXYoaG9zdC0+bW1jKSwgIlVuYWJsZSB0byBnZXQgSVJRIGZvciBNTUMgY292ZXIgc3dpdGNoXG4iKTsKCQkJb21hcF9mcmVlX2dwaW8oaG9zdC0+c3dpdGNoX3Bpbik7CgkJCWhvc3QtPnN3aXRjaF9waW4gPSAtMTsKCQkJZ290byBub19zd2l0Y2g7CgkJfQoJCXJldCA9IGRldmljZV9jcmVhdGVfZmlsZSgmcGRldi0+ZGV2LCAmZGV2X2F0dHJfY292ZXJfc3dpdGNoKTsKCQlpZiAocmV0ID09IDApIHsKCQkJcmV0ID0gZGV2aWNlX2NyZWF0ZV9maWxlKCZwZGV2LT5kZXYsICZkZXZfYXR0cl9lbmFibGVfcG9sbCk7CgkJCWlmIChyZXQgIT0gMCkKCQkJCWRldmljZV9yZW1vdmVfZmlsZSgmcGRldi0+ZGV2LCAmZGV2X2F0dHJfY292ZXJfc3dpdGNoKTsKCQl9CgkJaWYgKHJldCkgewoJCQlkZXZfd2FuKG1tY19kZXYoaG9zdC0+bW1jKSwgIlVuYWJsZSB0byBjcmVhdGUgc3lzZnMgYXR0cmlidXRlc1xuIik7CgkJCWZyZWVfaXJxKE9NQVBfR1BJT19JUlEoaG9zdC0+c3dpdGNoX3BpbiksIGhvc3QpOwoJCQlvbWFwX2ZyZWVfZ3Bpbyhob3N0LT5zd2l0Y2hfcGluKTsKCQkJaG9zdC0+c3dpdGNoX3BpbiA9IC0xOwoJCQlnb3RvIG5vX3N3aXRjaDsKCQl9CgkJaWYgKG1tY19vbWFwX2VuYWJsZV9wb2xsICYmIG1tY19vbWFwX2NvdmVyX2lzX29wZW4oaG9zdCkpCgkJCXNjaGVkdWxlX3dvcmsoJmhvc3QtPnN3aXRjaF93b3JrKTsKCX0KCm5vX3N3aXRjaDoKCXJldHVybiAwOwoKb3V0OgoJLyogRklYTUU6IEZyZWUgb3RoZXIgcmVzb3VyY2VzIHRvby4gKi8KCWlmIChob3N0KSB7CgkJaWYgKGhvc3QtPmljbGsgJiYgIUlTX0VSUihob3N0LT5pY2xrKSkKCQkJY2xrX3B1dChob3N0LT5pY2xrKTsKCQlpZiAoaG9zdC0+ZmNsayAmJiAhSVNfRVJSKGhvc3QtPmZjbGspKQoJCQljbGtfcHV0KGhvc3QtPmZjbGspOwoJCW1tY19mcmVlX2hvc3QoaG9zdC0+bW1jKTsKCX0KCXJldHVybiByZXQ7Cn0KCnN0YXRpYyBpbnQgbW1jX29tYXBfcmVtb3ZlKHN0cnVjdCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYpCnsKCXN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0ID0gcGxhdGZvcm1fZ2V0X2RydmRhdGEocGRldik7CgoJcGxhdGZvcm1fc2V0X2RydmRhdGEocGRldiwgTlVMTCk7CgoJaWYgKGhvc3QpIHsKCQltbWNfcmVtb3ZlX2hvc3QoaG9zdC0+bW1jKTsKCQlmcmVlX2lycShob3N0LT5pcnEsIGhvc3QpOwoKCQlpZiAoaG9zdC0+cG93ZXJfcGluID49IDApCgkJCW9tYXBfZnJlZV9ncGlvKGhvc3QtPnBvd2VyX3Bpbik7CgkJaWYgKGhvc3QtPnN3aXRjaF9waW4gPj0gMCkgewoJCQlkZXZpY2VfcmVtb3ZlX2ZpbGUoJnBkZXYtPmRldiwgJmRldl9hdHRyX2VuYWJsZV9wb2xsKTsKCQkJZGV2aWNlX3JlbW92ZV9maWxlKCZwZGV2LT5kZXYsICZkZXZfYXR0cl9jb3Zlcl9zd2l0Y2gpOwoJCQlmcmVlX2lycShPTUFQX0dQSU9fSVJRKGhvc3QtPnN3aXRjaF9waW4pLCBob3N0KTsKCQkJb21hcF9mcmVlX2dwaW8oaG9zdC0+c3dpdGNoX3Bpbik7CgkJCWhvc3QtPnN3aXRjaF9waW4gPSAtMTsKCQkJZGVsX3RpbWVyX3N5bmMoJmhvc3QtPnN3aXRjaF90aW1lcik7CgkJCWZsdXNoX3NjaGVkdWxlZF93b3JrKCk7CgkJfQoJCWlmIChob3N0LT5pY2xrICYmICFJU19FUlIoaG9zdC0+aWNsaykpCgkJCWNsa19wdXQoaG9zdC0+aWNsayk7CgkJaWYgKGhvc3QtPmZjbGsgJiYgIUlTX0VSUihob3N0LT5mY2xrKSkKCQkJY2xrX3B1dChob3N0LT5mY2xrKTsKCQltbWNfZnJlZV9ob3N0KGhvc3QtPm1tYyk7Cgl9CgoJcmVsZWFzZV9tZW1fcmVnaW9uKHBkZXYtPnJlc291cmNlWzBdLnN0YXJ0LAoJCQlwZGV2LT5yZXNvdXJjZVswXS5lbmQgLSBwZGV2LT5yZXNvdXJjZVswXS5zdGFydCArIDEpOwoKCXJldHVybiAwOwp9CgojaWZkZWYgQ09ORklHX1BNCnN0YXRpYyBpbnQgbW1jX29tYXBfc3VzcGVuZChzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2LCBwbV9tZXNzYWdlX3QgbWVzZykKewoJaW50IHJldCA9IDA7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBkZXYpOwoKCWlmIChob3N0ICYmIGhvc3QtPnN1c3BlbmRlZCkKCQlyZXR1cm4gMDsKCglpZiAoaG9zdCkgewoJCXJldCA9IG1tY19zdXNwZW5kX2hvc3QoaG9zdC0+bW1jLCBtZXNnKTsKCQlpZiAocmV0ID09IDApCgkJCWhvc3QtPnN1c3BlbmRlZCA9IDE7Cgl9CglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50IG1tY19vbWFwX3Jlc3VtZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQp7CglpbnQgcmV0ID0gMDsKCXN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0ID0gcGxhdGZvcm1fZ2V0X2RydmRhdGEocGRldik7CgoJaWYgKGhvc3QgJiYgIWhvc3QtPnN1c3BlbmRlZCkKCQlyZXR1cm4gMDsKCglpZiAoaG9zdCkgewoJCXJldCA9IG1tY19yZXN1bWVfaG9zdChob3N0LT5tbWMpOwoJCWlmIChyZXQgPT0gMCkKCQkJaG9zdC0+c3VzcGVuZGVkID0gMDsKCX0KCglyZXR1cm4gcmV0Owp9CiNlbHNlCiNkZWZpbmUgbW1jX29tYXBfc3VzcGVuZAlOVUxMCiNkZWZpbmUgbW1jX29tYXBfcmVzdW1lCQlOVUxMCiNlbmRpZgoKc3RhdGljIHN0cnVjdCBwbGF0Zm9ybV9kcml2ZXIgbW1jX29tYXBfZHJpdmVyID0gewoJLnByb2JlCQk9IG1tY19vbWFwX3Byb2JlLAoJLnJlbW92ZQkJPSBtbWNfb21hcF9yZW1vdmUsCgkuc3VzcGVuZAk9IG1tY19vbWFwX3N1c3BlbmQsCgkucmVzdW1lCQk9IG1tY19vbWFwX3Jlc3VtZSwKCS5kcml2ZXIJCT0gewoJCS5uYW1lCT0gRFJJVkVSX05BTUUsCgl9LAp9OwoKc3RhdGljIGludCBfX2luaXQgbW1jX29tYXBfaW5pdCh2b2lkKQp7CglyZXR1cm4gcGxhdGZvcm1fZHJpdmVyX3JlZ2lzdGVyKCZtbWNfb21hcF9kcml2ZXIpOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgbW1jX29tYXBfZXhpdCh2b2lkKQp7CglwbGF0Zm9ybV9kcml2ZXJfdW5yZWdpc3RlcigmbW1jX29tYXBfZHJpdmVyKTsKfQoKbW9kdWxlX2luaXQobW1jX29tYXBfaW5pdCk7Cm1vZHVsZV9leGl0KG1tY19vbWFwX2V4aXQpOwoKTU9EVUxFX0RFU0NSSVBUSU9OKCJPTUFQIE11bHRpbWVkaWEgQ2FyZCBkcml2ZXIiKTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwpNT0RVTEVfQUxJQVMoRFJJVkVSX05BTUUpOwpNT0RVTEVfQVVUSE9SKCJKdWhhIFlyavZs5CIpOwo=