LyoKICogIGxpbnV4L2RyaXZlcnMvbWVkaWEvbW1jL29tYXAuYwogKgogKiAgQ29weXJpZ2h0IChDKSAyMDA0IE5va2lhIENvcnBvcmF0aW9uCiAqICBXcml0dGVuIGJ5IFR1dWtrYSBUaWtrYW5lbiBhbmQgSnVoYSBZcmr2bOQ8anVoYS55cmpvbGFAbm9raWEuY29tPgogKiAgTWlzYyBoYWNrcyBoZXJlIGFuZCB0aGVyZSBieSBUb255IExpbmRncmVuIDx0b255QGF0b21pZGUuY29tPgogKiAgT3RoZXIgaGFja3MgKERNQSwgU0QsIGV0YykgYnkgRGF2aWQgQnJvd25lbGwKICoKICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgYXMKICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uCiAqLwoKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlcGFyYW0uaD4KI2luY2x1ZGUgPGxpbnV4L2luaXQuaD4KI2luY2x1ZGUgPGxpbnV4L2lvcG9ydC5oPgojaW5jbHVkZSA8bGludXgvcGxhdGZvcm1fZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L2RtYS1tYXBwaW5nLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvc3BpbmxvY2suaD4KI2luY2x1ZGUgPGxpbnV4L3RpbWVyLmg+CiNpbmNsdWRlIDxsaW51eC9tbWMvaG9zdC5oPgojaW5jbHVkZSA8bGludXgvbW1jL3Byb3RvY29sLmg+CiNpbmNsdWRlIDxsaW51eC9tbWMvY2FyZC5oPgojaW5jbHVkZSA8bGludXgvY2xrLmg+CgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vaXJxLmg+CiNpbmNsdWRlIDxhc20vc2NhdHRlcmxpc3QuaD4KI2luY2x1ZGUgPGFzbS9tYWNoLXR5cGVzLmg+CgojaW5jbHVkZSA8YXNtL2FyY2gvYm9hcmQuaD4KI2luY2x1ZGUgPGFzbS9hcmNoL2dwaW8uaD4KI2luY2x1ZGUgPGFzbS9hcmNoL2RtYS5oPgojaW5jbHVkZSA8YXNtL2FyY2gvbXV4Lmg+CiNpbmNsdWRlIDxhc20vYXJjaC9mcGdhLmg+CiNpbmNsdWRlIDxhc20vYXJjaC90cHM2NTAxMC5oPgoKI2luY2x1ZGUgIm9tYXAuaCIKCiNkZWZpbmUgRFJJVkVSX05BTUUgIm1tY2ktb21hcCIKI2RlZmluZSBSU1BfVFlQRSh4KQkoKHgpICYgfihNTUNfUlNQX0JVU1l8TU1DX1JTUF9PUENPREUpKQoKLyogU3BlY2lmaWVzIGhvdyBvZnRlbiBpbiBtaWxsaXNlY3MgdG8gcG9sbCBmb3IgY2FyZCBzdGF0dXMgY2hhbmdlcwogKiB3aGVuIHRoZSBjb3ZlciBzd2l0Y2ggaXMgb3BlbiAqLwojZGVmaW5lIE9NQVBfTU1DX1NXSVRDSF9QT0xMX0RFTEFZCTUwMAoKc3RhdGljIGludCBtbWNfb21hcF9lbmFibGVfcG9sbCA9IDE7CgpzdHJ1Y3QgbW1jX29tYXBfaG9zdCB7CglpbnQJCQlpbml0aWFsaXplZDsKCWludAkJCXN1c3BlbmRlZDsKCXN0cnVjdCBtbWNfcmVxdWVzdCAqCW1ycTsKCXN0cnVjdCBtbWNfY29tbWFuZCAqCWNtZDsKCXN0cnVjdCBtbWNfZGF0YSAqCWRhdGE7CglzdHJ1Y3QgbW1jX2hvc3QgKgltbWM7CglzdHJ1Y3QgZGV2aWNlICoJCWRldjsKCXVuc2lnbmVkIGNoYXIJCWlkOyAvKiAxNnh4IGNoaXBzIGhhdmUgMiBNTUMgYmxvY2tzICovCglzdHJ1Y3QgY2xrICoJCWljbGs7CglzdHJ1Y3QgY2xrICoJCWZjbGs7CglzdHJ1Y3QgcmVzb3VyY2UJCSpyZXM7Cgl2b2lkIF9faW9tZW0JCSpiYXNlOwoJaW50CQkJaXJxOwoJdW5zaWduZWQgY2hhcgkJYnVzX21vZGU7Cgl1bnNpZ25lZCBjaGFyCQlod19idXNfbW9kZTsKCgl1bnNpZ25lZCBpbnQJCXNnX2xlbjsKCWludAkJCXNnX2lkeDsKCXUxNiAqCQkJYnVmZmVyOwoJdTMyCQkJYnVmZmVyX2J5dGVzX2xlZnQ7Cgl1MzIJCQl0b3RhbF9ieXRlc19sZWZ0OwoKCXVuc2lnbmVkCQl1c2VfZG1hOjE7Cgl1bnNpZ25lZAkJYnJzX3JlY2VpdmVkOjEsIGRtYV9kb25lOjE7Cgl1bnNpZ25lZAkJZG1hX2lzX3JlYWQ6MTsKCXVuc2lnbmVkCQlkbWFfaW5fdXNlOjE7CglpbnQJCQlkbWFfY2g7CglzcGlubG9ja190CQlkbWFfbG9jazsKCXN0cnVjdCB0aW1lcl9saXN0CWRtYV90aW1lcjsKCXVuc2lnbmVkCQlkbWFfbGVuOwoKCXNob3J0CQkJcG93ZXJfcGluOwoJc2hvcnQJCQl3cF9waW47CgoJaW50CQkJc3dpdGNoX3BpbjsKCXN0cnVjdCB3b3JrX3N0cnVjdAlzd2l0Y2hfd29yazsKCXN0cnVjdCB0aW1lcl9saXN0CXN3aXRjaF90aW1lcjsKCWludAkJCXN3aXRjaF9sYXN0X3N0YXRlOwp9OwoKc3RhdGljIGlubGluZSBpbnQKbW1jX29tYXBfY292ZXJfaXNfb3BlbihzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCkKewoJaWYgKGhvc3QtPnN3aXRjaF9waW4gPCAwKQoJCXJldHVybiAwOwoJcmV0dXJuIG9tYXBfZ2V0X2dwaW9fZGF0YWluKGhvc3QtPnN3aXRjaF9waW4pOwp9CgpzdGF0aWMgc3NpemVfdAptbWNfb21hcF9zaG93X2NvdmVyX3N3aXRjaChzdHJ1Y3QgZGV2aWNlICpkZXYsCglzdHJ1Y3QgZGV2aWNlX2F0dHJpYnV0ZSAqYXR0ciwgY2hhciAqYnVmKQp7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwoKCXJldHVybiBzcHJpbnRmKGJ1ZiwgIiVzXG4iLCBtbWNfb21hcF9jb3Zlcl9pc19vcGVuKGhvc3QpID8gIm9wZW4iIDoKCQkJImNsb3NlZCIpOwp9CgpzdGF0aWMgREVWSUNFX0FUVFIoY292ZXJfc3dpdGNoLCBTX0lSVUdPLCBtbWNfb21hcF9zaG93X2NvdmVyX3N3aXRjaCwgTlVMTCk7CgpzdGF0aWMgc3NpemVfdAptbWNfb21hcF9zaG93X2VuYWJsZV9wb2xsKHN0cnVjdCBkZXZpY2UgKmRldiwKCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjaGFyICpidWYpCnsKCXJldHVybiBzbnByaW50ZihidWYsIFBBR0VfU0laRSwgIiVkXG4iLCBtbWNfb21hcF9lbmFibGVfcG9sbCk7Cn0KCnN0YXRpYyBzc2l6ZV90Cm1tY19vbWFwX3N0b3JlX2VuYWJsZV9wb2xsKHN0cnVjdCBkZXZpY2UgKmRldiwKCXN0cnVjdCBkZXZpY2VfYXR0cmlidXRlICphdHRyLCBjb25zdCBjaGFyICpidWYsCglzaXplX3Qgc2l6ZSkKewoJaW50IGVuYWJsZV9wb2xsOwoKCWlmIChzc2NhbmYoYnVmLCAiJTEwZCIsICZlbmFibGVfcG9sbCkgIT0gMSkKCQlyZXR1cm4gLUVJTlZBTDsKCglpZiAoZW5hYmxlX3BvbGwgIT0gbW1jX29tYXBfZW5hYmxlX3BvbGwpIHsKCQlzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IGRldl9nZXRfZHJ2ZGF0YShkZXYpOwoKCQltbWNfb21hcF9lbmFibGVfcG9sbCA9IGVuYWJsZV9wb2xsOwoJCWlmIChlbmFibGVfcG9sbCAmJiBob3N0LT5zd2l0Y2hfcGluID49IDApCgkJCXNjaGVkdWxlX3dvcmsoJmhvc3QtPnN3aXRjaF93b3JrKTsKCX0KCXJldHVybiBzaXplOwp9CgpzdGF0aWMgREVWSUNFX0FUVFIoZW5hYmxlX3BvbGwsIDA2NjQsCgkJICAgbW1jX29tYXBfc2hvd19lbmFibGVfcG9sbCwgbW1jX29tYXBfc3RvcmVfZW5hYmxlX3BvbGwpOwoKc3RhdGljIHZvaWQKbW1jX29tYXBfc3RhcnRfY29tbWFuZChzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19jb21tYW5kICpjbWQpCnsKCXUzMiBjbWRyZWc7Cgl1MzIgcmVzcHR5cGU7Cgl1MzIgY21kdHlwZTsKCglob3N0LT5jbWQgPSBjbWQ7CgoJcmVzcHR5cGUgPSAwOwoJY21kdHlwZSA9IDA7CgoJLyogT3VyIGhhcmR3YXJlIG5lZWRzIHRvIGtub3cgZXhhY3QgdHlwZSAqLwoJc3dpdGNoIChSU1BfVFlQRShtbWNfcmVzcF90eXBlKGNtZCkpKSB7CgljYXNlIFJTUF9UWVBFKE1NQ19SU1BfUjEpOgoJCS8qIHJlc3AgMSwgcmVzcCAxYiAqLwoJCXJlc3B0eXBlID0gMTsKCQlicmVhazsKCWNhc2UgUlNQX1RZUEUoTU1DX1JTUF9SMik6CgkJcmVzcHR5cGUgPSAyOwoJCWJyZWFrOwoJY2FzZSBSU1BfVFlQRShNTUNfUlNQX1IzKToKCQlyZXNwdHlwZSA9IDM7CgkJYnJlYWs7CglkZWZhdWx0OgoJCWJyZWFrOwoJfQoKCWlmIChtbWNfY21kX3R5cGUoY21kKSA9PSBNTUNfQ01EX0FEVEMpIHsKCQljbWR0eXBlID0gT01BUF9NTUNfQ01EVFlQRV9BRFRDOwoJfSBlbHNlIGlmIChtbWNfY21kX3R5cGUoY21kKSA9PSBNTUNfQ01EX0JDKSB7CgkJY21kdHlwZSA9IE9NQVBfTU1DX0NNRFRZUEVfQkM7Cgl9IGVsc2UgaWYgKG1tY19jbWRfdHlwZShjbWQpID09IE1NQ19DTURfQkNSKSB7CgkJY21kdHlwZSA9IE9NQVBfTU1DX0NNRFRZUEVfQkNSOwoJfSBlbHNlIHsKCQljbWR0eXBlID0gT01BUF9NTUNfQ01EVFlQRV9BQzsKCX0KCgljbWRyZWcgPSBjbWQtPm9wY29kZSB8IChyZXNwdHlwZSA8PCA4KSB8IChjbWR0eXBlIDw8IDEyKTsKCglpZiAoaG9zdC0+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+dG90YWxfYnl0ZXNfbGVmdDsKfQoKLyogUElPIG9ubHkgKi8Kc3RhdGljIHZvaWQKbW1jX29tYXBfeGZlcl9kYXRhKHN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0LCBpbnQgd3JpdGUpCnsKCWludCBuOwoKCWlmIChob3N0LT5idWZmZXJfYnl0ZXNfbGVmdCA9PSAwKSB7CgkJaG9zdC0+c2dfaWR4Kys7CgkJQlVHX09OKGhvc3QtPnNnX2lkeCA9PSBob3N0LT5zZ19sZW4pOwoJCW1tY19vbWFwX3NnX3RvX2J1Zihob3N0KTsKCX0KCW4gPSA2NDsKCWlmIChuID4gaG9zdC0+YnVmZmVyX2J5dGVzX2xlZnQpCgkJbiA9IGhvc3QtPmJ1ZmZlcl9ieXRlc19sZWZ0OwoJaG9zdC0+YnVmZmVyX2J5dGVzX2xlZnQgLT0gbjsKCWhvc3QtPnRvdGFsX2J5dGVzX2xlZnQgLT0gbjsKCWhvc3QtPmRhdGEtPmJ5dGVzX3hmZXJlZCArPSBuOwoKCWlmICh3cml0ZSkgewoJCV9fcmF3X3dyaXRlc3coaG9zdC0+YmFzZSArIE9NQVBfTU1DX1JFR19EQVRBLCBob3N0LT5idWZmZXIsIG4pOwoJfSBlbHNlIHsKCQlfX3Jhd19yZWFkc3coaG9zdC0+YmFzZSArIE9NQVBfTU1DX1JFR19EQVRBLCBob3N0LT5idWZmZXIsIG4pOwoJfQp9CgpzdGF0aWMgaW5saW5lIHZvaWQgbW1jX29tYXBfcmVwb3J0X2lycSh1MTYgc3RhdHVzKQp7CglzdGF0aWMgY29uc3QgY2hhciAqbW1jX29tYXBfc3RhdHVzX2JpdHNbXSA9IHsKCQkiRU9DIiwgIkNEIiwgIkNCIiwgIkJSUyIsICJFT0ZCIiwgIkRUTyIsICJEQ1JDIiwgIkNUTyIsCgkJIkNDUkMiLCAiQ1JXIiwgIkFGIiwgIkFFIiwgIk9DUkIiLCAiQ0lSUSIsICJDRVJSIgoJfTsKCWludCBpLCBjID0gMDsKCglmb3IgKGkgPSAwOyBpIDwgQVJSQVlfU0laRShtbWNfb21hcF9zdGF0dXNfYml0cyk7IGkrKykKCQlpZiAoc3RhdHVzICYgKDEgPDwgaSkpIHsKCQkJaWYgKGMpCgkJCQlwcmludGsoIiAiKTsKCQkJcHJpbnRrKCIlcyIsIG1tY19vbWFwX3N0YXR1c19iaXRzW2ldKTsKCQkJYysrOwoJCX0KfQoKc3RhdGljIGlycXJldHVybl90IG1tY19vbWFwX2lycShpbnQgaXJxLCB2b2lkICpkZXZfaWQsIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqIGhvc3QgPSAoc3RydWN0IG1tY19vbWFwX2hvc3QgKilkZXZfaWQ7Cgl1MTYgc3RhdHVzOwoJaW50IGVuZF9jb21tYW5kOwoJaW50IGVuZF90cmFuc2ZlcjsKCWludCB0cmFuc2Zlcl9lcnJvcjsKCglpZiAoaG9zdC0+Y21kID09IE5VTEwgJiYgaG9zdC0+ZGF0YSA9PSBOVUxMKSB7CgkJc3RhdHVzID0gT01BUF9NTUNfUkVBRChob3N0LT5iYXNlLCBTVEFUKTsKCQlkZXZfaW5mbyhtbWNfZGV2KGhvc3QtPm1tYyksInNwdXJpb3VzIGlycSAweCUwNHhcbiIsIHN0YXR1cyk7CgkJaWYgKHN0YXR1cyAhPSAwKSB7CgkJCU9NQVBfTU1DX1dSSVRFKGhvc3QtPmJhc2UsIFNUQVQsIHN0YXR1cyk7CgkJCU9NQVBfTU1DX1dSSVRFKGhvc3QtPmJhc2UsIElFLCAwKTsKCQl9CgkJcmV0dXJuIElSUV9IQU5ETEVEOwoJfQoKCWVuZF9jb21tYW5kID0gMDsKCWVuZF90cmFuc2ZlciA9IDA7Cgl0cmFuc2Zlcl9lcnJvciA9IDA7CgoJd2hpbGUgKChzdGF0dXMgPSBPTUFQX01NQ19SRUFEKGhvc3QtPmJhc2UsIFNUQVQpKSAhPSAwKSB7CgkJT01BUF9NTUNfV1JJVEUoaG9zdC0+YmFzZSwgU1RBVCwgc3RhdHVzKTsKI2lmZGVmIENPTkZJR19NTUNfREVCVUcKCQlkZXZfZGJnKG1tY19kZXYoaG9zdC0+bW1jKSwgIk1NQyBJUlEgJTA0eCAoQ01EICVkKTogIiwKCQkJc3RhdHVzLCBob3N0LT5jbWQgIT0gTlVMTCA/IGhvc3QtPmNtZC0+b3Bjb2RlIDogLTEpOwoJCW1tY19vbWFwX3JlcG9ydF9pcnEoc3RhdHVzKTsKCQlwcmludGsoIlxuIik7CiNlbmRpZgoJCWlmIChob3N0LT50b3RhbF9ieXRlc19sZWZ0KSB7CgkJCWlmICgoc3RhdHVzICYgT01BUF9NTUNfU1RBVF9BX0ZVTEwpIHx8CgkJCSAgICAoc3RhdHVzICYgT01BUF9NTUNfU1RBVF9FTkRfT0ZfREFUQSkpCgkJCQltbWNfb21hcF94ZmVyX2RhdGEoaG9zdCwgMCk7CgkJCWlmIChzdGF0dXMgJiBPTUFQX01NQ19TVEFUX0FfRU1QVFkpCgkJCQltbWNfb21hcF94ZmVyX2RhdGEoaG9zdCwgMSk7CgkJfQoKCQlpZiAoc3RhdHVzICYgT01BUF9NTUNfU1RBVF9FTkRfT0ZfREFUQSkgewoJCQllbmRfdHJhbnNmZXIgPSAxOwoJCX0KCgkJaWYgKHN0YXR1cyAmIE9NQVBfTU1DX1NUQVRfREFUQV9UT1VUKSB7CgkJCWRldl9kYmcobW1jX2Rldihob3N0LT5tbWMpLCAiZGF0YSB0aW1lb3V0XG4iKTsKCQkJaWYgKGhvc3QtPmRhdGEpIHsKCQkJCWhvc3QtPmRhdGEtPmVycm9yIHw9IE1NQ19FUlJfVElNRU9VVDsKCQkJCXRyYW5zZmVyX2Vycm9yID0gMTsKCQkJfQoJCX0KCgkJaWYgKHN0YXR1cyAmIE9NQVBfTU1DX1NUQVRfREFUQV9DUkMpIHsKCQkJaWYgKGhvc3QtPmRhdGEpIHsKCQkJCWhvc3QtPmRhdGEtPmVycm9yIHw9IE1NQ19FUlJfQkFEQ1JDOwoJCQkJZGV2X2RiZyhtbWNfZGV2KGhvc3QtPm1tYyksCgkJCQkJICJkYXRhIENSQyBlcnJvciwgYnl0ZXMgbGVmdCAlZFxuIiwKCQkJCQlob3N0LT50b3RhbF9ieXRlc19sZWZ0KTsKCQkJCXRyYW5zZmVyX2Vycm9yID0gMTsKCQkJfSBlbHNlIHsKCQkJCWRldl9kYmcobW1jX2Rldihob3N0LT5tbWMpLCAiZGF0YSBDUkMgZXJyb3JcbiIpOwoJCQl9CgkJfQoKCQlpZiAoc3RhdHVzICYgT01BUF9NTUNfU1RBVF9DTURfVE9VVCkgewoJCQkvKiBUaW1lb3V0cyBhcmUgcm91dGluZSB3aXRoIHNvbWUgY29tbWFuZHMgKi8KCQkJaWYgKGhvc3QtPmNtZCkgewoJCQkJaWYgKGhvc3QtPmNtZC0+b3Bjb2RlICE9IE1NQ19BTExfU0VORF9DSUQgJiYKCQkJCQkJaG9zdC0+Y21kLT5vcGNvZGUgIT0KCQkJCQkJTU1DX1NFTkRfT1BfQ09ORCAmJgoJCQkJCQlob3N0LT5jbWQtPm9wY29kZSAhPQoJCQkJCQlNTUNfQVBQX0NNRCAmJgoJCQkJCQkhbW1jX29tYXBfY292ZXJfaXNfb3Blbihob3N0KSkKCQkJCQlkZXZfZXJyKG1tY19kZXYoaG9zdC0+bW1jKSwKCQkJCQkJImNvbW1hbmQgdGltZW91dCwgQ01EICVkXG4iLAoJCQkJCQlob3N0LT5jbWQtPm9wY29kZSk7CgkJCQlob3N0LT5jbWQtPmVycm9yID0gTU1DX0VSUl9USU1FT1VUOwoJCQkJZW5kX2NvbW1hbmQgPSAxOwoJCQl9CgkJfQoKCQlpZiAoc3RhdHVzICYgT01BUF9NTUNfU1RBVF9DTURfQ1JDKSB7CgkJCWlmIChob3N0LT5jbWQpIHsKCQkJCWRldl9lcnIobW1jX2Rldihob3N0LT5tbWMpLAoJCQkJCSJjb21tYW5kIENSQyBlcnJvciAoQ01EJWQsIGFyZyAweCUwOHgpXG4iLAoJCQkJCWhvc3QtPmNtZC0+b3Bjb2RlLCBob3N0LT5jbWQtPmFyZyk7CgkJCQlob3N0LT5jbWQtPmVycm9yID0gTU1DX0VSUl9CQURDUkM7CgkJCQllbmRfY29tbWFuZCA9IDE7CgkJCX0gZWxzZQoJCQkJZGV2X2VycihtbWNfZGV2KGhvc3QtPm1tYyksCgkJCQkJImNvbW1hbmQgQ1JDIGVycm9yIHdpdGhvdXQgY21kP1xuIik7CgkJfQoKCQlpZiAoc3RhdHVzICYgT01BUF9NTUNfU1RBVF9DQVJEX0VSUikgewoJCQlpZiAoaG9zdC0+Y21kICYmIGhvc3QtPmNtZC0+b3Bjb2RlID09IE1NQ19TVE9QX1RSQU5TTUlTU0lPTikgewoJCQkJdTMyIHJlc3BvbnNlID0gT01BUF9NTUNfUkVBRChob3N0LT5iYXNlLCBSU1A2KQoJCQkJCXwgKE9NQVBfTU1DX1JFQUQoaG9zdC0+YmFzZSwgUlNQNykgPDwgMTYpOwoJCQkJLyogU1RPUCBzb21ldGltZXMgc2V0cyBtdXN0LWlnbm9yZSBiaXRzICovCgkJCQlpZiAoIShyZXNwb25zZSAmIChSMV9DQ19FUlJPUgoJCQkJCQkJCXwgUjFfSUxMRUdBTF9DT01NQU5ECgkJCQkJCQkJfCBSMV9DT01fQ1JDX0VSUk9SKSkpIHsKCQkJCQllbmRfY29tbWFuZCA9IDE7CgkJCQkJY29udGludWU7CgkJCQl9CgkJCX0KCgkJCWRldl9kYmcobW1jX2Rldihob3N0LT5tbWMpLCAiY2FyZCBzdGF0dXMgZXJyb3IgKENNRCVkKVxuIiwKCQkJCWhvc3QtPmNtZC0+b3Bjb2RlKTsKCQkJaWYgKGhvc3QtPmNtZCkgewoJCQkJaG9zdC0+Y21kLT5lcnJvciA9IE1NQ19FUlJfRkFJTEVEOwoJCQkJZW5kX2NvbW1hbmQgPSAxOwoJCQl9CgkJCWlmIChob3N0LT5kYXRhKSB7CgkJCQlob3N0LT5kYXRhLT5lcnJvciA9IE1NQ19FUlJfRkFJTEVEOwoJCQkJdHJhbnNmZXJfZXJyb3IgPSAxOwoJCQl9CgkJfQoKCQkvKgoJCSAqIE5PVEU6IE9uIDE2MTAgdGhlIEVORF9PRl9DTUQgbWF5IGNvbWUgdG9vIGVhcmx5IHdoZW4KCQkgKiBzdGFydGluZyBhIHdyaXRlIAoJCSAqLwoJCWlmICgoc3RhdHVzICYgT01BUF9NTUNfU1RBVF9FTkRfT0ZfQ01EKSAmJgoJCSAgICAoIShzdGF0dXMgJiBPTUFQX01NQ19TVEFUX0FfRU1QVFkpKSkgewoJCQllbmRfY29tbWFuZCA9IDE7CgkJfQoJfQoKCWlmIChlbmRfY29tbWFuZCkgewoJCW1tY19vbWFwX2NtZF9kb25lKGhvc3QsIGhvc3QtPmNtZCk7Cgl9CglpZiAodHJhbnNmZXJfZXJyb3IpCgkJbW1jX29tYXBfeGZlcl9kb25lKGhvc3QsIGhvc3QtPmRhdGEpOwoJZWxzZSBpZiAoZW5kX3RyYW5zZmVyKQoJCW1tY19vbWFwX2VuZF9vZl9kYXRhKGhvc3QsIGhvc3QtPmRhdGEpOwoKCXJldHVybiBJUlFfSEFORExFRDsKfQoKc3RhdGljIGlycXJldHVybl90IG1tY19vbWFwX3N3aXRjaF9pcnEoaW50IGlycSwgdm9pZCAqZGV2X2lkLCBzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QgPSAoc3RydWN0IG1tY19vbWFwX2hvc3QgKikgZGV2X2lkOwoKCXNjaGVkdWxlX3dvcmsoJmhvc3QtPnN3aXRjaF93b3JrKTsKCglyZXR1cm4gSVJRX0hBTkRMRUQ7Cn0KCnN0YXRpYyB2b2lkIG1tY19vbWFwX3N3aXRjaF90aW1lcih1bnNpZ25lZCBsb25nIGFyZykKewoJc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QgPSAoc3RydWN0IG1tY19vbWFwX2hvc3QgKikgYXJnOwoKCXNjaGVkdWxlX3dvcmsoJmhvc3QtPnN3aXRjaF93b3JrKTsKfQoKLyogRklYTUU6IEhhbmRsZSBjYXJkIGluc2VydGlvbiBhbmQgcmVtb3ZhbCBwcm9wZXJseS4gTWF5YmUgdXNlIGEgbWFzawogKiBmb3IgTU1DIHN0YXRlPyAqLwpzdGF0aWMgdm9pZCBtbWNfb21hcF9zd2l0Y2hfY2FsbGJhY2sodW5zaWduZWQgbG9uZyBkYXRhLCB1OCBtbWNfbWFzaykKewp9CgpzdGF0aWMgdm9pZCBtbWNfb21hcF9zd2l0Y2hfaGFuZGxlcih2b2lkICpkYXRhKQp7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IChzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqKSBkYXRhOwoJc3RydWN0IG1tY19jYXJkICpjYXJkOwoJc3RhdGljIGludCBjb21wbGFpbmVkID0gMDsKCWludCBjYXJkcyA9IDAsIGNvdmVyX29wZW47CgoJaWYgKGhvc3QtPnN3aXRjaF9waW4gPT0gLTEpCgkJcmV0dXJuOwoJY292ZXJfb3BlbiA9IG1tY19vbWFwX2NvdmVyX2lzX29wZW4oaG9zdCk7CglpZiAoY292ZXJfb3BlbiAhPSBob3N0LT5zd2l0Y2hfbGFzdF9zdGF0ZSkgewoJCWtvYmplY3RfdWV2ZW50KCZob3N0LT5kZXYtPmtvYmosIEtPQkpfQ0hBTkdFKTsKCQlob3N0LT5zd2l0Y2hfbGFzdF9zdGF0ZSA9IGNvdmVyX29wZW47Cgl9CgltbWNfZGV0ZWN0X2NoYW5nZShob3N0LT5tbWMsIDApOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShjYXJkLCAmaG9zdC0+bW1jLT5jYXJkcywgbm9kZSkgewoJCWlmIChtbWNfY2FyZF9wcmVzZW50KGNhcmQpKQoJCQljYXJkcysrOwoJfQoJaWYgKG1tY19vbWFwX2NvdmVyX2lzX29wZW4oaG9zdCkpIHsKCQlpZiAoIWNvbXBsYWluZWQpIHsKCQkJZGV2X2luZm8obW1jX2Rldihob3N0LT5tbWMpLCAiY292ZXIgaXMgb3BlbiIpOwoJCQljb21wbGFpbmVkID0gMTsKCQl9CgkJaWYgKG1tY19vbWFwX2VuYWJsZV9wb2xsKQoJCQltb2RfdGltZXIoJmhvc3QtPnN3aXRjaF90aW1lciwgamlmZmllcyArCgkJCQltc2Vjc190b19qaWZmaWVzKE9NQVBfTU1DX1NXSVRDSF9QT0xMX0RFTEFZKSk7Cgl9IGVsc2UgewoJCWNvbXBsYWluZWQgPSAwOwoJfQp9CgovKiBQcmVwYXJlIHRvIHRyYW5zZmVyIHRoZSBuZXh0IHNlZ21lbnQgb2YgYSBzY2F0dGVybGlzdCAqLwpzdGF0aWMgdm9pZAptbWNfb21hcF9wcmVwYXJlX2RtYShzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19kYXRhICpkYXRhKQp7CglpbnQgZG1hX2NoID0gaG9zdC0+ZG1hX2NoOwoJdW5zaWduZWQgbG9uZyBkYXRhX2FkZHI7Cgl1MTYgYnVmLCBmcmFtZTsKCXUzMiBjb3VudDsKCXN0cnVjdCBzY2F0dGVybGlzdCAqc2cgPSAmZGF0YS0+c2dbaG9zdC0+c2dfaWR4XTsKCWludCBzcmNfcG9ydCA9IDA7CglpbnQgZHN0X3BvcnQgPSAwOwoJaW50IHN5bmNfZGV2ID0gMDsKCglkYXRhX2FkZHIgPSBpb192MnAoKHUzMikgaG9zdC0+YmFzZSkgKyBPTUFQX01NQ19SRUdfREFUQTsKCWZyYW1lID0gZGF0YS0+Ymxrc3o7Cgljb3VudCA9IHNnX2RtYV9sZW4oc2cpOwoKCWlmICgoZGF0YS0+YmxvY2tzID09IDEpICYmIChjb3VudCA+IGRhdGEtPmJsa3N6KSkKCQljb3VudCA9IGZyYW1lOwoKCWhvc3QtPmRtYV9sZW4gPSBjb3VudDsKCgkvKiBGSUZPIGlzIDE2eDIgYnl0ZXMgb24gMTV4eCwgYW5kIDMyeDIgYnl0ZXMgb24gMTZ4eCBhbmQgMjR4eC4KCSAqIFVzZSAxNiBvciAzMiB3b3JkIGZyYW1lcyB3aGVuIHRoZSBibG9ja3NpemUgaXMgYXQgbGVhc3QgdGhhdCBsYXJnZS4KCSAqIEJsb2Nrc2l6ZSBpcyB1c3VhbGx5IDUxMiBieXRlczsgYnV0IG5vdCBmb3Igc29tZSBTRCByZWFkcy4KCSAqLwoJaWYgKGNwdV9pc19vbWFwMTV4eCgpICYmIGZyYW1lID4gMzIpCgkJZnJhbWUgPSAzMjsKCWVsc2UgaWYgKGZyYW1lID4gNjQpCgkJZnJhbWUgPSA2NDsKCWNvdW50IC89IGZyYW1lOwoJZnJhbWUgPj49IDE7CgoJaWYgKCEoZGF0YS0+ZmxhZ3MgJiBNTUNfREFUQV9XUklURSkpIHsKCQlidWYgPSAweDgwMGYgfCAoKGZyYW1lIC0gMSkgPDwgOCk7CgoJCWlmIChjcHVfY2xhc3NfaXNfb21hcDEoKSkgewoJCQlzcmNfcG9ydCA9IE9NQVBfRE1BX1BPUlRfVElQQjsKCQkJZHN0X3BvcnQgPSBPTUFQX0RNQV9QT1JUX0VNSUZGOwoJCX0KCQlpZiAoY3B1X2lzX29tYXAyNHh4KCkpCgkJCXN5bmNfZGV2ID0gT01BUDI0WFhfRE1BX01NQzFfUlg7CgoJCW9tYXBfc2V0X2RtYV9zcmNfcGFyYW1zKGRtYV9jaCwgc3JjX3BvcnQsCgkJCQkJT01BUF9ETUFfQU1PREVfQ09OU1RBTlQsCgkJCQkJZGF0YV9hZGRyLCAwLCAwKTsKCQlvbWFwX3NldF9kbWFfZGVzdF9wYXJhbXMoZG1hX2NoLCBkc3RfcG9ydCwKCQkJCQkgT01BUF9ETUFfQU1PREVfUE9TVF9JTkMsCgkJCQkJIHNnX2RtYV9hZGRyZXNzKHNnKSwgMCwgMCk7CgkJb21hcF9zZXRfZG1hX2Rlc3RfZGF0YV9wYWNrKGRtYV9jaCwgMSk7CgkJb21hcF9zZXRfZG1hX2Rlc3RfYnVyc3RfbW9kZShkbWFfY2gsIE9NQVBfRE1BX0RBVEFfQlVSU1RfNCk7Cgl9IGVsc2UgewoJCWJ1ZiA9IDB4MGY4MCB8ICgoZnJhbWUgLSAxKSA8PCAwKTsKCgkJaWYgKGNwdV9jbGFzc19pc19vbWFwMSgpKSB7CgkJCXNyY19wb3J0ID0gT01BUF9ETUFfUE9SVF9FTUlGRjsKCQkJZHN0X3BvcnQgPSBPTUFQX0RNQV9QT1JUX1RJUEI7CgkJfQoJCWlmIChjcHVfaXNfb21hcDI0eHgoKSkKCQkJc3luY19kZXYgPSBPTUFQMjRYWF9ETUFfTU1DMV9UWDsKCgkJb21hcF9zZXRfZG1hX2Rlc3RfcGFyYW1zKGRtYV9jaCwgZHN0X3BvcnQsCgkJCQkJIE9NQVBfRE1BX0FNT0RFX0NPTlNUQU5ULAoJCQkJCSBkYXRhX2FkZHIsIDAsIDApOwoJCW9tYXBfc2V0X2RtYV9zcmNfcGFyYW1zKGRtYV9jaCwgc3JjX3BvcnQsCgkJCQkJT01BUF9ETUFfQU1PREVfUE9TVF9JTkMsCgkJCQkJc2dfZG1hX2FkZHJlc3Moc2cpLCAwLCAwKTsKCQlvbWFwX3NldF9kbWFfc3JjX2RhdGFfcGFjayhkbWFfY2gsIDEpOwoJCW9tYXBfc2V0X2RtYV9zcmNfYnVyc3RfbW9kZShkbWFfY2gsIE9NQVBfRE1BX0RBVEFfQlVSU1RfNCk7Cgl9CgoJLyogTWF4IGxpbWl0IGZvciBETUEgZnJhbWUgY291bnQgaXMgMHhmZmZmICovCglpZiAodW5saWtlbHkoY291bnQgPiAweGZmZmYpKQoJCUJVRygpOwoKCU9NQVBfTU1DX1dSSVRFKGhvc3QtPmJhc2UsIEJVRiwgYnVmKTsKCW9tYXBfc2V0X2RtYV90cmFuc2Zlcl9wYXJhbXMoZG1hX2NoLCBPTUFQX0RNQV9EQVRBX1RZUEVfUzE2LAoJCQkJICAgICBmcmFtZSwgY291bnQsIE9NQVBfRE1BX1NZTkNfRlJBTUUsCgkJCQkgICAgIHN5bmNfZGV2LCAwKTsKfQoKLyogQSBzY2F0dGVybGlzdCBzZWdtZW50IGNvbXBsZXRlZCAqLwpzdGF0aWMgdm9pZCBtbWNfb21hcF9kbWFfY2IoaW50IGxjaCwgdTE2IGNoX3N0YXR1cywgdm9pZCAqZGF0YSkKewoJc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QgPSAoc3RydWN0IG1tY19vbWFwX2hvc3QgKikgZGF0YTsKCXN0cnVjdCBtbWNfZGF0YSAqbW1jZGF0ID0gaG9zdC0+ZGF0YTsKCglpZiAodW5saWtlbHkoaG9zdC0+ZG1hX2NoIDwgMCkpIHsKCQlkZXZfZXJyKG1tY19kZXYoaG9zdC0+bW1jKSwKCQkJIkRNQSBjYWxsYmFjayB3aGlsZSBETUEgbm90IGVuYWJsZWRcbiIpOwoJCXJldHVybjsKCX0KCS8qIEZJWE1FOiBXZSByZWFsbHkgc2hvdWxkIGRvIHNvbWV0aGluZyB0byBfaGFuZGxlXyB0aGUgZXJyb3JzICovCglpZiAoY2hfc3RhdHVzICYgT01BUDFfRE1BX1RPVVRfSVJRKSB7CgkJZGV2X2VycihtbWNfZGV2KGhvc3QtPm1tYyksIkRNQSB0aW1lb3V0XG4iKTsKCQlyZXR1cm47Cgl9CglpZiAoY2hfc3RhdHVzICYgT01BUF9ETUFfRFJPUF9JUlEpIHsKCQlkZXZfZXJyKG1tY19kZXYoaG9zdC0+bW1jKSwgIkRNQSBzeW5jIGVycm9yXG4iKTsKCQlyZXR1cm47Cgl9CglpZiAoIShjaF9zdGF0dXMgJiBPTUFQX0RNQV9CTE9DS19JUlEpKSB7CgkJcmV0dXJuOwoJfQoJbW1jZGF0LT5ieXRlc194ZmVyZWQgKz0gaG9zdC0+ZG1hX2xlbjsKCWhvc3QtPnNnX2lkeCsrOwoJaWYgKGhvc3QtPnNnX2lkeCA8IGhvc3QtPnNnX2xlbikgewoJCW1tY19vbWFwX3ByZXBhcmVfZG1hKGhvc3QsIGhvc3QtPmRhdGEpOwoJCW9tYXBfc3RhcnRfZG1hKGhvc3QtPmRtYV9jaCk7Cgl9IGVsc2UKCQltbWNfb21hcF9kbWFfZG9uZShob3N0LCBob3N0LT5kYXRhKTsKfQoKc3RhdGljIGludCBtbWNfb21hcF9nZXRfZG1hX2NoYW5uZWwoc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QsIHN0cnVjdCBtbWNfZGF0YSAqZGF0YSkKewoJY29uc3QgY2hhciAqZGV2X25hbWU7CglpbnQgc3luY19kZXYsIGRtYV9jaCwgaXNfcmVhZCwgcjsKCglpc19yZWFkID0gIShkYXRhLT5mbGFncyAmIE1NQ19EQVRBX1dSSVRFKTsKCWRlbF90aW1lcl9zeW5jKCZob3N0LT5kbWFfdGltZXIpOwoJaWYgKGhvc3QtPmRtYV9jaCA+PSAwKSB7CgkJaWYgKGlzX3JlYWQgPT0gaG9zdC0+ZG1hX2lzX3JlYWQpCgkJCXJldHVybiAwOwoJCW9tYXBfZnJlZV9kbWEoaG9zdC0+ZG1hX2NoKTsKCQlob3N0LT5kbWFfY2ggPSAtMTsKCX0KCglpZiAoaXNfcmVhZCkgewoJCWlmIChob3N0LT5pZCA9PSAxKSB7CgkJCXN5bmNfZGV2ID0gT01BUF9ETUFfTU1DX1JYOwoJCQlkZXZfbmFtZSA9ICJNTUMxIHJlYWQiOwoJCX0gZWxzZSB7CgkJCXN5bmNfZGV2ID0gT01BUF9ETUFfTU1DMl9SWDsKCQkJZGV2X25hbWUgPSAiTU1DMiByZWFkIjsKCQl9Cgl9IGVsc2UgewoJCWlmIChob3N0LT5pZCA9PSAxKSB7CgkJCXN5bmNfZGV2ID0gT01BUF9ETUFfTU1DX1RYOwoJCQlkZXZfbmFtZSA9ICJNTUMxIHdyaXRlIjsKCQl9IGVsc2UgewoJCQlzeW5jX2RldiA9IE9NQVBfRE1BX01NQzJfVFg7CgkJCWRldl9uYW1lID0gIk1NQzIgd3JpdGUiOwoJCX0KCX0KCXIgPSBvbWFwX3JlcXVlc3RfZG1hKHN5bmNfZGV2LCBkZXZfbmFtZSwgbW1jX29tYXBfZG1hX2NiLAoJCQkgICAgIGhvc3QsICZkbWFfY2gpOwoJaWYgKHIgIT0gMCkgewoJCWRldl9kYmcobW1jX2Rldihob3N0LT5tbWMpLCAib21hcF9yZXF1ZXN0X2RtYSgpIGZhaWxlZCB3aXRoICVkXG4iLCByKTsKCQlyZXR1cm4gcjsKCX0KCWhvc3QtPmRtYV9jaCA9IGRtYV9jaDsKCWhvc3QtPmRtYV9pc19yZWFkID0gaXNfcmVhZDsKCglyZXR1cm4gMDsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNldF9jbWRfdGltZW91dChzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19yZXF1ZXN0ICpyZXEpCnsKCXUxNiByZWc7CgoJcmVnID0gT01BUF9NTUNfUkVBRChob3N0LT5iYXNlLCBTRElPKTsKCXJlZyAmPSB+KDEgPDwgNSk7CglPTUFQX01NQ19XUklURShob3N0LT5iYXNlLCBTRElPLCByZWcpOwoJLyogU2V0IG1heGltdW0gdGltZW91dCAqLwoJT01BUF9NTUNfV1JJVEUoaG9zdC0+YmFzZSwgQ1RPLCAweGZmKTsKfQoKc3RhdGljIGlubGluZSB2b2lkIHNldF9kYXRhX3RpbWVvdXQoc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QsIHN0cnVjdCBtbWNfcmVxdWVzdCAqcmVxKQp7CglpbnQgdGltZW91dDsKCXUxNiByZWc7CgoJLyogQ29udmVydCBucyB0byBjbG9jayBjeWNsZXMgYnkgYXNzdW1pbmcgMjBNSHogZnJlcXVlbmN5CgkgKiAxIGN5Y2xlIGF0IDIwTUh6ID0gNTAwIG5zCgkgKi8KCXRpbWVvdXQgPSByZXEtPmRhdGEtPnRpbWVvdXRfY2xrcyArIHJlcS0+ZGF0YS0+dGltZW91dF9ucyAvIDUwMDsKCgkvKiBDaGVjayBpZiB3ZSBuZWVkIHRvIHVzZSB0aW1lb3V0IG11bHRpcGxpZXIgcmVnaXN0ZXIgKi8KCXJlZyA9IE9NQVBfTU1DX1JFQUQoaG9zdC0+YmFzZSwgU0RJTyk7CglpZiAodGltZW91dCA+IDB4ZmZmZikgewoJCXJlZyB8PSAoMSA8PCA1KTsKCQl0aW1lb3V0IC89IDEwMjQ7Cgl9IGVsc2UKCQlyZWcgJj0gfigxIDw8IDUpOwoJT01BUF9NTUNfV1JJVEUoaG9zdC0+YmFzZSwgU0RJTywgcmVnKTsKCU9NQVBfTU1DX1dSSVRFKGhvc3QtPmJhc2UsIERUTywgdGltZW91dCk7Cn0KCnN0YXRpYyB2b2lkCm1tY19vbWFwX3ByZXBhcmVfZGF0YShzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCwgc3RydWN0IG1tY19yZXF1ZXN0ICpyZXEpCnsKCXN0cnVjdCBtbWNfZGF0YSAqZGF0YSA9IHJlcS0+ZGF0YTsKCWludCBpLCB1c2VfZG1hLCBibG9ja19zaXplOwoJdW5zaWduZWQgc2dfbGVuOwoKCWhvc3QtPmRhdGEgPSBkYXRhOwoJaWYgKGRhdGEgPT0gTlVMTCkgewoJCU9NQVBfTU1DX1dSSVRFKGhvc3QtPmJhc2UsIEJMRU4sIDApOwoJCU9NQVBfTU1DX1dSSVRFKGhvc3QtPmJhc2UsIE5CTEssIDApOwoJCU9NQVBfTU1DX1dSSVRFKGhvc3QtPmJhc2UsIEJVRiwgMCk7CgkJaG9zdC0+ZG1hX2luX3VzZSA9IDA7CgkJc2V0X2NtZF90aW1lb3V0KGhvc3QsIHJlcSk7CgkJcmV0dXJuOwoJfQoKCglibG9ja19zaXplID0gZGF0YS0+Ymxrc3o7CgoJT01BUF9NTUNfV1JJVEUoaG9zdC0+YmFzZSwgTkJMSywgZGF0YS0+YmxvY2tzIC0gMSk7CglPTUFQX01NQ19XUklURShob3N0LT5iYXNlLCBCTEVOLCBibG9ja19zaXplIC0gMSk7CglzZXRfZGF0YV90aW1lb3V0KGhvc3QsIHJlcSk7CgoJLyogY29wZSB3aXRoIGNhbGxpbmcgbGF5ZXIgY29uZnVzaW9uOyBpdCBpc3N1ZXMgInNpbmdsZQoJICogYmxvY2siIHdyaXRlcyB1c2luZyBtdWx0aS1ibG9jayBzY2F0dGVybGlzdHMuCgkgKi8KCXNnX2xlbiA9IChkYXRhLT5ibG9ja3MgPT0gMSkgPyAxIDogZGF0YS0+c2dfbGVuOwoKCS8qIE9ubHkgZG8gRE1BIGZvciBlbnRpcmUgYmxvY2tzICovCgl1c2VfZG1hID0gaG9zdC0+dXNlX2RtYTsKCWlmICh1c2VfZG1hKSB7CgkJZm9yIChpID0gMDsgaSA8IHNnX2xlbjsgaSsrKSB7CgkJCWlmICgoZGF0YS0+c2dbaV0ubGVuZ3RoICUgYmxvY2tfc2l6ZSkgIT0gMCkgewoJCQkJdXNlX2RtYSA9IDA7CgkJCQlicmVhazsKCQkJfQoJCX0KCX0KCglob3N0LT5zZ19pZHggPSAwOwoJaWYgKHVzZV9kbWEpIHsKCQlpZiAobW1jX29tYXBfZ2V0X2RtYV9jaGFubmVsKGhvc3QsIGRhdGEpID09IDApIHsKCQkJZW51bSBkbWFfZGF0YV9kaXJlY3Rpb24gZG1hX2RhdGFfZGlyOwoKCQkJaWYgKGRhdGEtPmZsYWdzICYgTU1DX0RBVEFfV1JJVEUpCgkJCQlkbWFfZGF0YV9kaXIgPSBETUFfVE9fREVWSUNFOwoJCQllbHNlCgkJCQlkbWFfZGF0YV9kaXIgPSBETUFfRlJPTV9ERVZJQ0U7CgoJCQlob3N0LT5zZ19sZW4gPSBkbWFfbWFwX3NnKG1tY19kZXYoaG9zdC0+bW1jKSwgZGF0YS0+c2csCgkJCQkJCXNnX2xlbiwgZG1hX2RhdGFfZGlyKTsKCQkJaG9zdC0+dG90YWxfYnl0ZXNfbGVmdCA9IDA7CgkJCW1tY19vbWFwX3ByZXBhcmVfZG1hKGhvc3QsIHJlcS0+ZGF0YSk7CgkJCWhvc3QtPmJyc19yZWNlaXZlZCA9IDA7CgkJCWhvc3QtPmRtYV9kb25lID0gMDsKCQkJaG9zdC0+ZG1hX2luX3VzZSA9IDE7CgkJfSBlbHNlCgkJCXVzZV9kbWEgPSAwOwoJfQoKCS8qIFJldmVydCB0byBQSU8/ICovCglpZiAoIXVzZV9kbWEpIHsKCQlPTUFQX01NQ19XUklURShob3N0LT5iYXNlLCBCVUYsIDB4MWYxZik7CgkJaG9zdC0+dG90YWxfYnl0ZXNfbGVmdCA9IGRhdGEtPmJsb2NrcyAqIGJsb2NrX3NpemU7CgkJaG9zdC0+c2dfbGVuID0gc2dfbGVuOwoJCW1tY19vbWFwX3NnX3RvX2J1Zihob3N0KTsKCQlob3N0LT5kbWFfaW5fdXNlID0gMDsKCX0KfQoKc3RhdGljIHZvaWQgbW1jX29tYXBfcmVxdWVzdChzdHJ1Y3QgbW1jX2hvc3QgKm1tYywgc3RydWN0IG1tY19yZXF1ZXN0ICpyZXEpCnsKCXN0cnVjdCBtbWNfb21hcF9ob3N0ICpob3N0ID0gbW1jX3ByaXYobW1jKTsKCglXQVJOX09OKGhvc3QtPm1ycSAhPSBOVUxMKTsKCglob3N0LT5tcnEgPSByZXE7CgoJLyogb25seSB0b3VjaCBmaWZvIEFGVEVSIHRoZSBjb250cm9sbGVyIHJlYWRpZXMgaXQgKi8KCW1tY19vbWFwX3ByZXBhcmVfZGF0YShob3N0LCByZXEpOwoJbW1jX29tYXBfc3RhcnRfY29tbWFuZChob3N0LCByZXEtPmNtZCk7CglpZiAoaG9zdC0+ZG1hX2luX3VzZSkKCQlvbWFwX3N0YXJ0X2RtYShob3N0LT5kbWFfY2gpOwp9CgpzdGF0aWMgdm9pZCBpbm5vdmF0b3JfZnBnYV9zb2NrZXRfcG93ZXIoaW50IG9uKQp7CiNpZiBkZWZpbmVkKENPTkZJR19NQUNIX09NQVBfSU5OT1ZBVE9SKSAmJiBkZWZpbmVkKENPTkZJR19BUkNIX09NQVAxNVhYKQoKCWlmIChvbikgewoJCWZwZ2Ffd3JpdGUoZnBnYV9yZWFkKE9NQVAxNTEwX0ZQR0FfUE9XRVIpIHwgKDEgPDwgMyksCgkJICAgICBPTUFQMTUxMF9GUEdBX1BPV0VSKTsKCX0gZWxzZSB7CgkJZnBnYV93cml0ZShmcGdhX3JlYWQoT01BUDE1MTBfRlBHQV9QT1dFUikgJiB+KDEgPDwgMyksCgkJICAgICBPTUFQMTUxMF9GUEdBX1BPV0VSKTsKCX0KI2VuZGlmCn0KCi8qCiAqIFR1cm4gdGhlIHNvY2tldCBwb3dlciBvbi9vZmYuIElubm92YXRvciB1c2VzIEZQR0EsIG1vc3QgYm9hcmRzCiAqIHByb2JhYmx5IHVzZSBHUElPLgogKi8Kc3RhdGljIHZvaWQgbW1jX29tYXBfcG93ZXIoc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QsIGludCBvbikKewoJaWYgKG9uKSB7CgkJaWYgKG1hY2hpbmVfaXNfb21hcF9pbm5vdmF0b3IoKSkKCQkJaW5ub3ZhdG9yX2ZwZ2Ffc29ja2V0X3Bvd2VyKDEpOwoJCWVsc2UgaWYgKG1hY2hpbmVfaXNfb21hcF9oMigpKQoJCQl0cHM2NTAxMF9zZXRfZ3Bpb19vdXRfdmFsdWUoR1BJTzMsIEhJR0gpOwoJCWVsc2UgaWYgKG1hY2hpbmVfaXNfb21hcF9oMygpKQoJCQkvKiBHUElPIDQgb2YgVFBTNjUwMTAgc2VuZHMgU0RfRU4gc2lnbmFsICovCgkJCXRwczY1MDEwX3NldF9ncGlvX291dF92YWx1ZShHUElPNCwgSElHSCk7CgkJZWxzZSBpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQkJdTE2IHJlZyA9IE9NQVBfTU1DX1JFQUQoaG9zdC0+YmFzZSwgQ09OKTsKCQkJT01BUF9NTUNfV1JJVEUoaG9zdC0+YmFzZSwgQ09OLCByZWcgfCAoMSA8PCAxMSkpOwoJCX0gZWxzZQoJCQlpZiAoaG9zdC0+cG93ZXJfcGluID49IDApCgkJCQlvbWFwX3NldF9ncGlvX2RhdGFvdXQoaG9zdC0+cG93ZXJfcGluLCAxKTsKCX0gZWxzZSB7CgkJaWYgKG1hY2hpbmVfaXNfb21hcF9pbm5vdmF0b3IoKSkKCQkJaW5ub3ZhdG9yX2ZwZ2Ffc29ja2V0X3Bvd2VyKDApOwoJCWVsc2UgaWYgKG1hY2hpbmVfaXNfb21hcF9oMigpKQoJCQl0cHM2NTAxMF9zZXRfZ3Bpb19vdXRfdmFsdWUoR1BJTzMsIExPVyk7CgkJZWxzZSBpZiAobWFjaGluZV9pc19vbWFwX2gzKCkpCgkJCXRwczY1MDEwX3NldF9ncGlvX291dF92YWx1ZShHUElPNCwgTE9XKTsKCQllbHNlIGlmIChjcHVfaXNfb21hcDI0eHgoKSkgewoJCQl1MTYgcmVnID0gT01BUF9NTUNfUkVBRChob3N0LT5iYXNlLCBDT04pOwoJCQlPTUFQX01NQ19XUklURShob3N0LT5iYXNlLCBDT04sIHJlZyAmIH4oMSA8PCAxMSkpOwoJCX0gZWxzZQoJCQlpZiAoaG9zdC0+cG93ZXJfcGluID49IDApCgkJCQlvbWFwX3NldF9ncGlvX2RhdGFvdXQoaG9zdC0+cG93ZXJfcGluLCAwKTsKCX0KfQoKc3RhdGljIHZvaWQgbW1jX29tYXBfc2V0X2lvcyhzdHJ1Y3QgbW1jX2hvc3QgKm1tYywgc3RydWN0IG1tY19pb3MgKmlvcykKewoJc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QgPSBtbWNfcHJpdihtbWMpOwoJaW50IGRzb3I7CglpbnQgcmVhbGNsb2NrLCBpOwoKCXJlYWxjbG9jayA9IGlvcy0+Y2xvY2s7CgoJaWYgKGlvcy0+Y2xvY2sgPT0gMCkKCQlkc29yID0gMDsKCWVsc2UgewoJCWludCBmdW5jX2Nsa19yYXRlID0gY2xrX2dldF9yYXRlKGhvc3QtPmZjbGspOwoKCQlkc29yID0gZnVuY19jbGtfcmF0ZSAvIHJlYWxjbG9jazsKCQlpZiAoZHNvciA8IDEpCgkJCWRzb3IgPSAxOwoKCQlpZiAoZnVuY19jbGtfcmF0ZSAvIGRzb3IgPiByZWFsY2xvY2spCgkJCWRzb3IrKzsKCgkJaWYgKGRzb3IgPiAyNTApCgkJCWRzb3IgPSAyNTA7CgkJZHNvcisrOwoKCQlpZiAoaW9zLT5idXNfd2lkdGggPT0gTU1DX0JVU19XSURUSF80KQoJCQlkc29yIHw9IDEgPDwgMTU7Cgl9CgoJc3dpdGNoIChpb3MtPnBvd2VyX21vZGUpIHsKCWNhc2UgTU1DX1BPV0VSX09GRjoKCQltbWNfb21hcF9wb3dlcihob3N0LCAwKTsKCQlicmVhazsKCWNhc2UgTU1DX1BPV0VSX1VQOgoJY2FzZSBNTUNfUE9XRVJfT046CgkJbW1jX29tYXBfcG93ZXIoaG9zdCwgMSk7CgkJZHNvciB8PSAxPDwxMTsKCQlicmVhazsKCX0KCglob3N0LT5idXNfbW9kZSA9IGlvcy0+YnVzX21vZGU7Cglob3N0LT5od19idXNfbW9kZSA9IGhvc3QtPmJ1c19tb2RlOwoKCWNsa19lbmFibGUoaG9zdC0+ZmNsayk7CgoJLyogT24gaW5zYW5lbHkgaGlnaCBhcm1fcGVyIGZyZXF1ZW5jaWVzIHNvbWV0aGluZyBzb21ldGltZXMKCSAqIGdvZXMgc29tZWhvdyBvdXQgb2Ygc3luYywgYW5kIHRoZSBQT1cgYml0IGlzIG5vdCBiZWluZyBzZXQsCgkgKiB3aGljaCByZXN1bHRzIGluIHRoZSB3aGlsZSBsb29wIGJlbG93IGdldHRpbmcgc3R1Y2suCgkgKiBXcml0aW5nIHRvIHRoZSBDT04gcmVnaXN0ZXIgdHdpY2Ugc2VlbXMgdG8gZG8gdGhlIHRyaWNrLiAqLwoJZm9yIChpID0gMDsgaSA8IDI7IGkrKykKCQlPTUFQX01NQ19XUklURShob3N0LT5iYXNlLCBDT04sIGRzb3IpOwoJaWYgKGlvcy0+cG93ZXJfbW9kZSA9PSBNTUNfUE9XRVJfVVApIHsKCQkvKiBTZW5kIGNsb2NrIGN5Y2xlcywgcG9sbCBjb21wbGV0aW9uICovCgkJT01BUF9NTUNfV1JJVEUoaG9zdC0+YmFzZSwgSUUsIDApOwoJCU9NQVBfTU1DX1dSSVRFKGhvc3QtPmJhc2UsIFNUQVQsIDB4ZmZmZik7CgkJT01BUF9NTUNfV1JJVEUoaG9zdC0+YmFzZSwgQ01ELCAxPDw3KTsKCQl3aGlsZSAoMCA9PSAoT01BUF9NTUNfUkVBRChob3N0LT5iYXNlLCBTVEFUKSAmIDEpKTsKCQlPTUFQX01NQ19XUklURShob3N0LT5iYXNlLCBTVEFULCAxKTsKCX0KCWNsa19kaXNhYmxlKGhvc3QtPmZjbGspOwp9CgpzdGF0aWMgaW50IG1tY19vbWFwX2dldF9ybyhzdHJ1Y3QgbW1jX2hvc3QgKm1tYykKewoJc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QgPSBtbWNfcHJpdihtbWMpOwoKCXJldHVybiBob3N0LT53cF9waW4gJiYgb21hcF9nZXRfZ3Bpb19kYXRhaW4oaG9zdC0+d3BfcGluKTsKfQoKc3RhdGljIHN0cnVjdCBtbWNfaG9zdF9vcHMgbW1jX29tYXBfb3BzID0gewoJLnJlcXVlc3QJPSBtbWNfb21hcF9yZXF1ZXN0LAoJLnNldF9pb3MJPSBtbWNfb21hcF9zZXRfaW9zLAoJLmdldF9ybwkJPSBtbWNfb21hcF9nZXRfcm8sCn07CgpzdGF0aWMgaW50IF9faW5pdCBtbWNfb21hcF9wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQp7CglzdHJ1Y3Qgb21hcF9tbWNfY29uZiAqbWluZm8gPSBwZGV2LT5kZXYucGxhdGZvcm1fZGF0YTsKCXN0cnVjdCBtbWNfaG9zdCAqbW1jOwoJc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QgPSBOVUxMOwoJc3RydWN0IHJlc291cmNlICpyOwoJaW50IHJldCA9IDA7CglpbnQgaXJxOwoJCglyID0gcGxhdGZvcm1fZ2V0X3Jlc291cmNlKHBkZXYsIElPUkVTT1VSQ0VfTUVNLCAwKTsKCWlycSA9IHBsYXRmb3JtX2dldF9pcnEocGRldiwgMCk7CglpZiAoIXIgfHwgaXJxIDwgMCkKCQlyZXR1cm4gLUVOWElPOwoKCXIgPSByZXF1ZXN0X21lbV9yZWdpb24ocGRldi0+cmVzb3VyY2VbMF0uc3RhcnQsCgkJCQlwZGV2LT5yZXNvdXJjZVswXS5lbmQgLSBwZGV2LT5yZXNvdXJjZVswXS5zdGFydCArIDEsCgkJCSAgICAgICBwZGV2LT5uYW1lKTsKCWlmICghcikKCQlyZXR1cm4gLUVCVVNZOwoKCW1tYyA9IG1tY19hbGxvY19ob3N0KHNpemVvZihzdHJ1Y3QgbW1jX29tYXBfaG9zdCksICZwZGV2LT5kZXYpOwoJaWYgKCFtbWMpIHsKCQlyZXQgPSAtRU5PTUVNOwoJCWdvdG8gb3V0OwoJfQoKCWhvc3QgPSBtbWNfcHJpdihtbWMpOwoJaG9zdC0+bW1jID0gbW1jOwoKCXNwaW5fbG9ja19pbml0KCZob3N0LT5kbWFfbG9jayk7Cglpbml0X3RpbWVyKCZob3N0LT5kbWFfdGltZXIpOwoJaG9zdC0+ZG1hX3RpbWVyLmZ1bmN0aW9uID0gbW1jX29tYXBfZG1hX3RpbWVyOwoJaG9zdC0+ZG1hX3RpbWVyLmRhdGEgPSAodW5zaWduZWQgbG9uZykgaG9zdDsKCglob3N0LT5pZCA9IHBkZXYtPmlkOwoJaG9zdC0+cmVzID0gcjsKCWhvc3QtPmlycSA9IGlycTsKCglpZiAoY3B1X2lzX29tYXAyNHh4KCkpIHsKCQlob3N0LT5pY2xrID0gY2xrX2dldCgmcGRldi0+ZGV2LCAibW1jX2ljayIpOwoJCWlmIChJU19FUlIoaG9zdC0+aWNsaykpCgkJCWdvdG8gb3V0OwoJCWNsa19lbmFibGUoaG9zdC0+aWNsayk7Cgl9CgoJaWYgKCFjcHVfaXNfb21hcDI0eHgoKSkKCQlob3N0LT5mY2xrID0gY2xrX2dldCgmcGRldi0+ZGV2LCAibW1jX2NrIik7CgllbHNlCgkJaG9zdC0+ZmNsayA9IGNsa19nZXQoJnBkZXYtPmRldiwgIm1tY19mY2siKTsKCglpZiAoSVNfRVJSKGhvc3QtPmZjbGspKSB7CgkJcmV0ID0gUFRSX0VSUihob3N0LT5mY2xrKTsKCQlnb3RvIG91dDsKCX0KCgkvKiBSRVZJU0lUOgoJICogQWxzbywgdXNlIG1pbmZvLT5jb3ZlciB0byBkZWNpZGUgaG93IHRvIG1hbmFnZQoJICogdGhlIGNhcmQgZGV0ZWN0IHNlbnNpbmcuCgkgKi8KCWhvc3QtPnBvd2VyX3BpbiA9IG1pbmZvLT5wb3dlcl9waW47Cglob3N0LT5zd2l0Y2hfcGluID0gbWluZm8tPnN3aXRjaF9waW47Cglob3N0LT53cF9waW4gPSBtaW5mby0+d3BfcGluOwoJaG9zdC0+dXNlX2RtYSA9IDE7Cglob3N0LT5kbWFfY2ggPSAtMTsKCglob3N0LT5pcnEgPSBwZGV2LT5yZXNvdXJjZVsxXS5zdGFydDsKCWhvc3QtPmJhc2UgPSAodm9pZCBfX2lvbWVtKilJT19BRERSRVNTKHItPnN0YXJ0KTsKCglpZiAobWluZm8tPndpcmU0KQoJCSBtbWMtPmNhcHMgfD0gTU1DX0NBUF80X0JJVF9EQVRBOwoKCW1tYy0+b3BzID0gJm1tY19vbWFwX29wczsKCW1tYy0+Zl9taW4gPSA0MDAwMDA7CgltbWMtPmZfbWF4ID0gMjQwMDAwMDA7CgltbWMtPm9jcl9hdmFpbCA9IE1NQ19WRERfMzJfMzN8TU1DX1ZERF8zM18zNDsKCgkvKiBVc2Ugc2NhdHRlcmxpc3QgRE1BIHRvIHJlZHVjZSBwZXItdHJhbnNmZXIgY29zdHMuCgkgKiBOT1RFIG1heF9zZWdfc2l6ZSBhc3N1bXB0aW9uIHRoYXQgc21hbGwgYmxvY2tzIGFyZW4ndAoJICogbm9ybWFsbHkgdXNlZCAoZXhjZXB0IGUuZy4gZm9yIHJlYWRpbmcgU0QgcmVnaXN0ZXJzKS4KCSAqLwoJbW1jLT5tYXhfcGh5c19zZWdzID0gMzI7CgltbWMtPm1heF9od19zZWdzID0gMzI7CgltbWMtPm1heF9zZWN0b3JzID0gMjU2OyAvKiBOQkxLIG1heCAxMS1iaXRzLCBPTUFQIGFsc28gbGltaXRlZCBieSBETUEgKi8KCW1tYy0+bWF4X3NlZ19zaXplID0gbW1jLT5tYXhfc2VjdG9ycyAqIDUxMjsKCglpZiAoaG9zdC0+cG93ZXJfcGluID49IDApIHsKCQlpZiAoKHJldCA9IG9tYXBfcmVxdWVzdF9ncGlvKGhvc3QtPnBvd2VyX3BpbikpICE9IDApIHsKCQkJZGV2X2VycihtbWNfZGV2KGhvc3QtPm1tYyksCgkJCQkiVW5hYmxlIHRvIGdldCBHUElPIHBpbiBmb3IgTU1DIHBvd2VyXG4iKTsKCQkJZ290byBvdXQ7CgkJfQoJCW9tYXBfc2V0X2dwaW9fZGlyZWN0aW9uKGhvc3QtPnBvd2VyX3BpbiwgMCk7Cgl9CgoJcmV0ID0gcmVxdWVzdF9pcnEoaG9zdC0+aXJxLCBtbWNfb21hcF9pcnEsIDAsIERSSVZFUl9OQU1FLCBob3N0KTsKCWlmIChyZXQpCgkJZ290byBvdXQ7CgoJaG9zdC0+ZGV2ID0gJnBkZXYtPmRldjsKCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIGhvc3QpOwoKCW1tY19hZGRfaG9zdChtbWMpOwoKCWlmIChob3N0LT5zd2l0Y2hfcGluID49IDApIHsKCQlJTklUX1dPUksoJmhvc3QtPnN3aXRjaF93b3JrLCBtbWNfb21hcF9zd2l0Y2hfaGFuZGxlciwgaG9zdCk7CgkJaW5pdF90aW1lcigmaG9zdC0+c3dpdGNoX3RpbWVyKTsKCQlob3N0LT5zd2l0Y2hfdGltZXIuZnVuY3Rpb24gPSBtbWNfb21hcF9zd2l0Y2hfdGltZXI7CgkJaG9zdC0+c3dpdGNoX3RpbWVyLmRhdGEgPSAodW5zaWduZWQgbG9uZykgaG9zdDsKCQlpZiAob21hcF9yZXF1ZXN0X2dwaW8oaG9zdC0+c3dpdGNoX3BpbikgIT0gMCkgewoJCQlkZXZfd2FybihtbWNfZGV2KGhvc3QtPm1tYyksICJVbmFibGUgdG8gZ2V0IEdQSU8gcGluIGZvciBNTUMgY292ZXIgc3dpdGNoXG4iKTsKCQkJaG9zdC0+c3dpdGNoX3BpbiA9IC0xOwoJCQlnb3RvIG5vX3N3aXRjaDsKCQl9CgoJCW9tYXBfc2V0X2dwaW9fZGlyZWN0aW9uKGhvc3QtPnN3aXRjaF9waW4sIDEpOwoJCXJldCA9IHJlcXVlc3RfaXJxKE9NQVBfR1BJT19JUlEoaG9zdC0+c3dpdGNoX3BpbiksCgkJCQkgIG1tY19vbWFwX3N3aXRjaF9pcnEsIElSUUZfVFJJR0dFUl9SSVNJTkcsIERSSVZFUl9OQU1FLCBob3N0KTsKCQlpZiAocmV0KSB7CgkJCWRldl93YXJuKG1tY19kZXYoaG9zdC0+bW1jKSwgIlVuYWJsZSB0byBnZXQgSVJRIGZvciBNTUMgY292ZXIgc3dpdGNoXG4iKTsKCQkJb21hcF9mcmVlX2dwaW8oaG9zdC0+c3dpdGNoX3Bpbik7CgkJCWhvc3QtPnN3aXRjaF9waW4gPSAtMTsKCQkJZ290byBub19zd2l0Y2g7CgkJfQoJCXJldCA9IGRldmljZV9jcmVhdGVfZmlsZSgmcGRldi0+ZGV2LCAmZGV2X2F0dHJfY292ZXJfc3dpdGNoKTsKCQlpZiAocmV0ID09IDApIHsKCQkJcmV0ID0gZGV2aWNlX2NyZWF0ZV9maWxlKCZwZGV2LT5kZXYsICZkZXZfYXR0cl9lbmFibGVfcG9sbCk7CgkJCWlmIChyZXQgIT0gMCkKCQkJCWRldmljZV9yZW1vdmVfZmlsZSgmcGRldi0+ZGV2LCAmZGV2X2F0dHJfY292ZXJfc3dpdGNoKTsKCQl9CgkJaWYgKHJldCkgewoJCQlkZXZfd2FybihtbWNfZGV2KGhvc3QtPm1tYyksICJVbmFibGUgdG8gY3JlYXRlIHN5c2ZzIGF0dHJpYnV0ZXNcbiIpOwoJCQlmcmVlX2lycShPTUFQX0dQSU9fSVJRKGhvc3QtPnN3aXRjaF9waW4pLCBob3N0KTsKCQkJb21hcF9mcmVlX2dwaW8oaG9zdC0+c3dpdGNoX3Bpbik7CgkJCWhvc3QtPnN3aXRjaF9waW4gPSAtMTsKCQkJZ290byBub19zd2l0Y2g7CgkJfQoJCWlmIChtbWNfb21hcF9lbmFibGVfcG9sbCAmJiBtbWNfb21hcF9jb3Zlcl9pc19vcGVuKGhvc3QpKQoJCQlzY2hlZHVsZV93b3JrKCZob3N0LT5zd2l0Y2hfd29yayk7Cgl9Cgpub19zd2l0Y2g6CglyZXR1cm4gMDsKCm91dDoKCS8qIEZJWE1FOiBGcmVlIG90aGVyIHJlc291cmNlcyB0b28uICovCglpZiAoaG9zdCkgewoJCWlmIChob3N0LT5pY2xrICYmICFJU19FUlIoaG9zdC0+aWNsaykpCgkJCWNsa19wdXQoaG9zdC0+aWNsayk7CgkJaWYgKGhvc3QtPmZjbGsgJiYgIUlTX0VSUihob3N0LT5mY2xrKSkKCQkJY2xrX3B1dChob3N0LT5mY2xrKTsKCQltbWNfZnJlZV9ob3N0KGhvc3QtPm1tYyk7Cgl9CglyZXR1cm4gcmV0Owp9CgpzdGF0aWMgaW50IG1tY19vbWFwX3JlbW92ZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQp7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBkZXYpOwoKCXBsYXRmb3JtX3NldF9kcnZkYXRhKHBkZXYsIE5VTEwpOwoKCWlmIChob3N0KSB7CgkJbW1jX3JlbW92ZV9ob3N0KGhvc3QtPm1tYyk7CgkJZnJlZV9pcnEoaG9zdC0+aXJxLCBob3N0KTsKCgkJaWYgKGhvc3QtPnBvd2VyX3BpbiA+PSAwKQoJCQlvbWFwX2ZyZWVfZ3Bpbyhob3N0LT5wb3dlcl9waW4pOwoJCWlmIChob3N0LT5zd2l0Y2hfcGluID49IDApIHsKCQkJZGV2aWNlX3JlbW92ZV9maWxlKCZwZGV2LT5kZXYsICZkZXZfYXR0cl9lbmFibGVfcG9sbCk7CgkJCWRldmljZV9yZW1vdmVfZmlsZSgmcGRldi0+ZGV2LCAmZGV2X2F0dHJfY292ZXJfc3dpdGNoKTsKCQkJZnJlZV9pcnEoT01BUF9HUElPX0lSUShob3N0LT5zd2l0Y2hfcGluKSwgaG9zdCk7CgkJCW9tYXBfZnJlZV9ncGlvKGhvc3QtPnN3aXRjaF9waW4pOwoJCQlob3N0LT5zd2l0Y2hfcGluID0gLTE7CgkJCWRlbF90aW1lcl9zeW5jKCZob3N0LT5zd2l0Y2hfdGltZXIpOwoJCQlmbHVzaF9zY2hlZHVsZWRfd29yaygpOwoJCX0KCQlpZiAoaG9zdC0+aWNsayAmJiAhSVNfRVJSKGhvc3QtPmljbGspKQoJCQljbGtfcHV0KGhvc3QtPmljbGspOwoJCWlmIChob3N0LT5mY2xrICYmICFJU19FUlIoaG9zdC0+ZmNsaykpCgkJCWNsa19wdXQoaG9zdC0+ZmNsayk7CgkJbW1jX2ZyZWVfaG9zdChob3N0LT5tbWMpOwoJfQoKCXJlbGVhc2VfbWVtX3JlZ2lvbihwZGV2LT5yZXNvdXJjZVswXS5zdGFydCwKCQkJcGRldi0+cmVzb3VyY2VbMF0uZW5kIC0gcGRldi0+cmVzb3VyY2VbMF0uc3RhcnQgKyAxKTsKCglyZXR1cm4gMDsKfQoKI2lmZGVmIENPTkZJR19QTQpzdGF0aWMgaW50IG1tY19vbWFwX3N1c3BlbmQoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldiwgcG1fbWVzc2FnZV90IG1lc2cpCnsKCWludCByZXQgPSAwOwoJc3RydWN0IG1tY19vbWFwX2hvc3QgKmhvc3QgPSBwbGF0Zm9ybV9nZXRfZHJ2ZGF0YShwZGV2KTsKCglpZiAoaG9zdCAmJiBob3N0LT5zdXNwZW5kZWQpCgkJcmV0dXJuIDA7CgoJaWYgKGhvc3QpIHsKCQlyZXQgPSBtbWNfc3VzcGVuZF9ob3N0KGhvc3QtPm1tYywgbWVzZyk7CgkJaWYgKHJldCA9PSAwKQoJCQlob3N0LT5zdXNwZW5kZWQgPSAxOwoJfQoJcmV0dXJuIHJldDsKfQoKc3RhdGljIGludCBtbWNfb21hcF9yZXN1bWUoc3RydWN0IHBsYXRmb3JtX2RldmljZSAqcGRldikKewoJaW50IHJldCA9IDA7CglzdHJ1Y3QgbW1jX29tYXBfaG9zdCAqaG9zdCA9IHBsYXRmb3JtX2dldF9kcnZkYXRhKHBkZXYpOwoKCWlmIChob3N0ICYmICFob3N0LT5zdXNwZW5kZWQpCgkJcmV0dXJuIDA7CgoJaWYgKGhvc3QpIHsKCQlyZXQgPSBtbWNfcmVzdW1lX2hvc3QoaG9zdC0+bW1jKTsKCQlpZiAocmV0ID09IDApCgkJCWhvc3QtPnN1c3BlbmRlZCA9IDA7Cgl9CgoJcmV0dXJuIHJldDsKfQojZWxzZQojZGVmaW5lIG1tY19vbWFwX3N1c3BlbmQJTlVMTAojZGVmaW5lIG1tY19vbWFwX3Jlc3VtZQkJTlVMTAojZW5kaWYKCnN0YXRpYyBzdHJ1Y3QgcGxhdGZvcm1fZHJpdmVyIG1tY19vbWFwX2RyaXZlciA9IHsKCS5wcm9iZQkJPSBtbWNfb21hcF9wcm9iZSwKCS5yZW1vdmUJCT0gbW1jX29tYXBfcmVtb3ZlLAoJLnN1c3BlbmQJPSBtbWNfb21hcF9zdXNwZW5kLAoJLnJlc3VtZQkJPSBtbWNfb21hcF9yZXN1bWUsCgkuZHJpdmVyCQk9IHsKCQkubmFtZQk9IERSSVZFUl9OQU1FLAoJfSwKfTsKCnN0YXRpYyBpbnQgX19pbml0IG1tY19vbWFwX2luaXQodm9pZCkKewoJcmV0dXJuIHBsYXRmb3JtX2RyaXZlcl9yZWdpc3RlcigmbW1jX29tYXBfZHJpdmVyKTsKfQoKc3RhdGljIHZvaWQgX19leGl0IG1tY19vbWFwX2V4aXQodm9pZCkKewoJcGxhdGZvcm1fZHJpdmVyX3VucmVnaXN0ZXIoJm1tY19vbWFwX2RyaXZlcik7Cn0KCm1vZHVsZV9pbml0KG1tY19vbWFwX2luaXQpOwptb2R1bGVfZXhpdChtbWNfb21hcF9leGl0KTsKCk1PRFVMRV9ERVNDUklQVElPTigiT01BUCBNdWx0aW1lZGlhIENhcmQgZHJpdmVyIik7Ck1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKTU9EVUxFX0FMSUFTKERSSVZFUl9OQU1FKTsKTU9EVUxFX0FVVEhPUigiSnVoYSBZcmr2bOQiKTsK