LyoKICoKICoJCQlMaW51eCBNZWdhUkFJRCBkZXZpY2UgZHJpdmVyCiAqCiAqIENvcHlyaWdodCCpIDIwMDIgIExTSSBMb2dpYyBDb3Jwb3JhdGlvbi4KICoKICoJICAgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vcgogKgkgICBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKgkgICBhcyBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlvbjsgZWl0aGVyIHZlcnNpb24KICoJICAgMiBvZiB0aGUgTGljZW5zZSwgb3IgKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi4KICoKICogQ29weXJpZ2h0IChjKSAyMDAyICBSZWQgSGF0LCBJbmMuIEFsbCByaWdodHMgcmVzZXJ2ZWQuCiAqCSAgLSBmaXhlcwogKgkgIC0gc3BlZWQtdXBzIChsaXN0IGhhbmRsaW5nIGZpeGVzLCBpc3N1ZWRfbGlzdCwgb3B0aW1pemF0aW9ucy4pCiAqCSAgLSBsb3RzIG9mIGNsZWFudXBzLgogKgogKiBDb3B5cmlnaHQgKGMpIDIwMDMgIENocmlzdG9waCBIZWxsd2lnICA8aGNoQGxzdC5kZT4KICoJICAtIG5ldy1zdHlsZSwgaG90cGx1Zy1hd2FyZSBwY2kgcHJvYmluZyBhbmQgc2NzaSByZWdpc3RyYXRpb24KICoKICogVmVyc2lvbiA6IHYyLjAwLjMgKEZlYiAxOSwgMjAwMykgLSBBdHVsIE11a2tlciA8QXR1bC5NdWtrZXJAbHNpbC5jb20+CiAqCiAqIERlc2NyaXB0aW9uOiBMaW51eCBkZXZpY2UgZHJpdmVyIGZvciBMU0kgTG9naWMgTWVnYVJBSUQgY29udHJvbGxlcgogKgogKiBTdXBwb3J0ZWQgY29udHJvbGxlcnM6IE1lZ2FSQUlEIDQxOCwgNDI4LCA0MzgsIDQ2NiwgNzYyLCA0NjcsIDQ3MSwgNDkwLCA0OTMKICoJCQkJCTUxOCwgNTIwLCA1MzEsIDUzMgogKgogKiBUaGlzIGRyaXZlciBpcyBzdXBwb3J0ZWQgYnkgTFNJIExvZ2ljLCB3aXRoIGFzc2lzdGFuY2UgZnJvbSBSZWQgSGF0LCBEZWxsLAogKiBhbmQgb3RoZXJzLiBQbGVhc2Ugc2VuZCB1cGRhdGVzIHRvIHRoZSBtYWlsaW5nIGxpc3QKICogbGludXgtc2NzaUB2Z2VyLmtlcm5lbC5vcmcgLgogKgogKi8KCiNpbmNsdWRlIDxsaW51eC9tbS5oPgojaW5jbHVkZSA8bGludXgvZnMuaD4KI2luY2x1ZGUgPGxpbnV4L2Jsa2Rldi5oPgojaW5jbHVkZSA8YXNtL3VhY2Nlc3MuaD4KI2luY2x1ZGUgPGFzbS9pby5oPgojaW5jbHVkZSA8bGludXgvZGVsYXkuaD4KI2luY2x1ZGUgPGxpbnV4L3Byb2NfZnMuaD4KI2luY2x1ZGUgPGxpbnV4L3JlYm9vdC5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9saXN0Lmg+CiNpbmNsdWRlIDxsaW51eC9pbnRlcnJ1cHQuaD4KI2luY2x1ZGUgPGxpbnV4L3BjaS5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8c2NzaS9zY3NpY2FtLmg+CgojaW5jbHVkZSAic2NzaS5oIgojaW5jbHVkZSA8c2NzaS9zY3NpX2hvc3QuaD4KCiNpbmNsdWRlICJtZWdhcmFpZC5oIgoKI2RlZmluZSBNRUdBUkFJRF9NT0RVTEVfVkVSU0lPTiAiMi4wMC4zIgoKTU9EVUxFX0FVVEhPUiAoIkxTSSBMb2dpYyBDb3Jwb3JhdGlvbiIpOwpNT0RVTEVfREVTQ1JJUFRJT04gKCJMU0kgTG9naWMgTWVnYVJBSUQgZHJpdmVyIik7Ck1PRFVMRV9MSUNFTlNFICgiR1BMIik7Ck1PRFVMRV9WRVJTSU9OKE1FR0FSQUlEX01PRFVMRV9WRVJTSU9OKTsKCnN0YXRpYyB1bnNpZ25lZCBpbnQgbWF4X2NtZF9wZXJfbHVuID0gREVGX0NNRF9QRVJfTFVOOwptb2R1bGVfcGFyYW0obWF4X2NtZF9wZXJfbHVuLCB1aW50LCAwKTsKTU9EVUxFX1BBUk1fREVTQyhtYXhfY21kX3Blcl9sdW4sICJNYXhpbXVtIG51bWJlciBvZiBjb21tYW5kcyB3aGljaCBjYW4gYmUgaXNzdWVkIHRvIGEgc2luZ2xlIExVTiAoZGVmYXVsdD1ERUZfQ01EX1BFUl9MVU49NjMpIik7CgpzdGF0aWMgdW5zaWduZWQgc2hvcnQgaW50IG1heF9zZWN0b3JzX3Blcl9pbyA9IE1BWF9TRUNUT1JTX1BFUl9JTzsKbW9kdWxlX3BhcmFtKG1heF9zZWN0b3JzX3Blcl9pbywgdXNob3J0LCAwKTsKTU9EVUxFX1BBUk1fREVTQyhtYXhfc2VjdG9yc19wZXJfaW8sICJNYXhpbXVtIG51bWJlciBvZiBzZWN0b3JzIHBlciBJL08gcmVxdWVzdCAoZGVmYXVsdD1NQVhfU0VDVE9SU19QRVJfSU89MTI4KSIpOwoKCnN0YXRpYyB1bnNpZ25lZCBzaG9ydCBpbnQgbWF4X21ib3hfYnVzeV93YWl0ID0gTUJPWF9CVVNZX1dBSVQ7Cm1vZHVsZV9wYXJhbShtYXhfbWJveF9idXN5X3dhaXQsIHVzaG9ydCwgMCk7Ck1PRFVMRV9QQVJNX0RFU0MobWF4X21ib3hfYnVzeV93YWl0LCAiTWF4aW11bSB3YWl0IGZvciBtYWlsYm94IGluIG1pY3Jvc2Vjb25kcyBpZiBidXN5IChkZWZhdWx0PU1CT1hfQlVTWV9XQUlUPTEwKSIpOwoKI2RlZmluZSBSRElORE9PUihhZGFwdGVyKQkJcmVhZGwoKGFkYXB0ZXIpLT5iYXNlICsgMHgyMCkKI2RlZmluZSBSRE9VVERPT1IoYWRhcHRlcikJCXJlYWRsKChhZGFwdGVyKS0+YmFzZSArIDB4MkMpCiNkZWZpbmUgV1JJTkRPT1IoYWRhcHRlcix2YWx1ZSkJCXdyaXRlbCh2YWx1ZSwgKGFkYXB0ZXIpLT5iYXNlICsgMHgyMCkKI2RlZmluZSBXUk9VVERPT1IoYWRhcHRlcix2YWx1ZSkJd3JpdGVsKHZhbHVlLCAoYWRhcHRlciktPmJhc2UgKyAweDJDKQoKLyoKICogR2xvYmFsIHZhcmlhYmxlcwogKi8KCnN0YXRpYyBpbnQgaGJhX2NvdW50OwpzdGF0aWMgYWRhcHRlcl90ICpoYmFfc29mdF9zdGF0ZVtNQVhfQ09OVFJPTExFUlNdOwpzdGF0aWMgc3RydWN0IHByb2NfZGlyX2VudHJ5ICptZWdhX3Byb2NfZGlyX2VudHJ5OwoKLyogRm9yIGNvbnRyb2xsZXIgcmUtb3JkZXJpbmcgKi8Kc3RhdGljIHN0cnVjdCBtZWdhX2hiYXMgbWVnYV9oYmFzW01BWF9DT05UUk9MTEVSU107CgovKgogKiBUaGUgRmlsZSBPcGVyYXRpb25zIHN0cnVjdHVyZSBmb3IgdGhlIHNlcmlhbC9pb2N0bCBpbnRlcmZhY2Ugb2YgdGhlIGRyaXZlcgogKi8Kc3RhdGljIHN0cnVjdCBmaWxlX29wZXJhdGlvbnMgbWVnYWRldl9mb3BzID0gewoJLm93bmVyCQk9IFRISVNfTU9EVUxFLAoJLmlvY3RsCQk9IG1lZ2FkZXZfaW9jdGwsCgkub3BlbgkJPSBtZWdhZGV2X29wZW4sCn07CgovKgogKiBBcnJheSB0byBzdHJ1Y3R1cmVzIGZvciBzdG9yaW5nIHRoZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY29udHJvbGxlcnMuIFRoaXMKICogaW5mb3JtYXRpb24gaXMgc2VudCB0byB0aGUgdXNlciBsZXZlbCBhcHBsaWNhdGlvbnMsIHdoZW4gdGhleSBkbyBhbiBpb2N0bAogKiBmb3IgdGhpcyBpbmZvcm1hdGlvbi4KICovCnN0YXRpYyBzdHJ1Y3QgbWNvbnRyb2xsZXIgbWNvbnRyb2xsZXJbTUFYX0NPTlRST0xMRVJTXTsKCi8qIFRoZSBjdXJyZW50IGRyaXZlciB2ZXJzaW9uICovCnN0YXRpYyB1MzIgZHJpdmVyX3ZlciA9IDB4MDIwMDAwMDA7CgovKiBtYWpvciBudW1iZXIgdXNlZCBieSB0aGUgZGV2aWNlIGZvciBjaGFyYWN0ZXIgaW50ZXJmYWNlICovCnN0YXRpYyBpbnQgbWFqb3I7CgojZGVmaW5lIElTX1JBSURfQ0goaGJhLCBjaCkJKCgoaGJhKS0+bWVnYV9jaF9jbGFzcyA+PiAoY2gpKSAmIDB4MDEpCgoKLyoKICogRGVidWcgdmFyaWFibGUgdG8gcHJpbnQgc29tZSBkaWFnbm9zdGljIG1lc3NhZ2VzCiAqLwpzdGF0aWMgaW50IHRyYWNlX2xldmVsOwoKLyoqCiAqIG1lZ2Ffc2V0dXBfbWFpbGJveCgpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBBbGxvY2F0ZXMgYSA4IGJ5dGUgYWxpZ25lZCBtZW1vcnkgZm9yIHRoZSBoYW5kc2hha2UgbWFpbGJveC4KICovCnN0YXRpYyBpbnQKbWVnYV9zZXR1cF9tYWlsYm94KGFkYXB0ZXJfdCAqYWRhcHRlcikKewoJdW5zaWduZWQgbG9uZwlhbGlnbjsKCglhZGFwdGVyLT51bmFfbWJveDY0ID0gcGNpX2FsbG9jX2NvbnNpc3RlbnQoYWRhcHRlci0+ZGV2LAoJCQlzaXplb2YobWJveDY0X3QpLCAmYWRhcHRlci0+dW5hX21ib3g2NF9kbWEpOwoKCWlmKCAhYWRhcHRlci0+dW5hX21ib3g2NCApIHJldHVybiAtMTsKCQkKCWFkYXB0ZXItPm1ib3ggPSAmYWRhcHRlci0+dW5hX21ib3g2NC0+bWJveDsKCglhZGFwdGVyLT5tYm94ID0gKG1ib3hfdCAqKSgoKCh1bnNpZ25lZCBsb25nKSBhZGFwdGVyLT5tYm94KSArIDE1KSAmCgkJCSh+MFVMIF4gMHhGVUwpKTsKCglhZGFwdGVyLT5tYm94NjQgPSAobWJveDY0X3QgKikoKCh1bnNpZ25lZCBsb25nKWFkYXB0ZXItPm1ib3gpIC0gOCk7CgoJYWxpZ24gPSAoKHZvaWQgKilhZGFwdGVyLT5tYm94KSAtICgodm9pZCAqKSZhZGFwdGVyLT51bmFfbWJveDY0LT5tYm94KTsKCglhZGFwdGVyLT5tYm94X2RtYSA9IGFkYXB0ZXItPnVuYV9tYm94NjRfZG1hICsgOCArIGFsaWduOwoKCS8qCgkgKiBSZWdpc3RlciB0aGUgbWFpbGJveCBpZiB0aGUgY29udHJvbGxlciBpcyBhbiBpby1tYXBwZWQgY29udHJvbGxlcgoJICovCglpZiggYWRhcHRlci0+ZmxhZyAmIEJPQVJEX0lPTUFQICkgewoKCQlvdXRiX3AoYWRhcHRlci0+bWJveF9kbWEgJiAweEZGLAoJCQkJYWRhcHRlci0+aG9zdC0+aW9fcG9ydCArIE1CT1hfUE9SVDApOwoKCQlvdXRiX3AoKGFkYXB0ZXItPm1ib3hfZG1hID4+IDgpICYgMHhGRiwKCQkJCWFkYXB0ZXItPmhvc3QtPmlvX3BvcnQgKyBNQk9YX1BPUlQxKTsKCgkJb3V0Yl9wKChhZGFwdGVyLT5tYm94X2RtYSA+PiAxNikgJiAweEZGLAoJCQkJYWRhcHRlci0+aG9zdC0+aW9fcG9ydCArIE1CT1hfUE9SVDIpOwoKCQlvdXRiX3AoKGFkYXB0ZXItPm1ib3hfZG1hID4+IDI0KSAmIDB4RkYsCgkJCQlhZGFwdGVyLT5ob3N0LT5pb19wb3J0ICsgTUJPWF9QT1JUMyk7CgoJCW91dGJfcChFTkFCTEVfTUJPWF9CWVRFLAoJCQkJYWRhcHRlci0+aG9zdC0+aW9fcG9ydCArIEVOQUJMRV9NQk9YX1JFR0lPTik7CgoJCWlycV9hY2soYWRhcHRlcik7CgoJCWlycV9lbmFibGUoYWRhcHRlcik7Cgl9CgoJcmV0dXJuIDA7Cn0KCgovKgogKiBtZWdhX3F1ZXJ5X2FkYXB0ZXIoKQogKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICoKICogSXNzdWUgdGhlIGFkYXB0ZXIgaW5xdWlyeSBjb21tYW5kcyB0byB0aGUgY29udHJvbGxlciBhbmQgZmluZCBvdXQKICogaW5mb3JtYXRpb24gYW5kIHBhcmFtZXRlciBhYm91dCB0aGUgZGV2aWNlcyBhdHRhY2hlZAogKi8Kc3RhdGljIGludAptZWdhX3F1ZXJ5X2FkYXB0ZXIoYWRhcHRlcl90ICphZGFwdGVyKQp7CglkbWFfYWRkcl90CXByb2RfaW5mb19kbWFfaGFuZGxlOwoJbWVnYV9pbnF1aXJ5MwkqaW5xdWlyeTM7Cgl1OAlyYXdfbWJveFtzaXplb2Yoc3RydWN0IG1ib3hfb3V0KV07CgltYm94X3QJKm1ib3g7CglpbnQJcmV0dmFsOwoKCS8qIEluaXRpYWxpemUgYWRhcHRlciBpbnF1aXJ5IG1haWxib3ggKi8KCgltYm94ID0gKG1ib3hfdCAqKXJhd19tYm94OwoKCW1lbXNldCgodm9pZCAqKWFkYXB0ZXItPm1lZ2FfYnVmZmVyLCAwLCBNRUdBX0JVRkZFUl9TSVpFKTsKCW1lbXNldCgmbWJveC0+bV9vdXQsIDAsIHNpemVvZihyYXdfbWJveCkpOwoKCS8qCgkgKiBUcnkgdG8gaXNzdWUgSW5xdWlyeTMgY29tbWFuZAoJICogaWYgbm90IHN1Y2NlZWRlZCwgdGhlbiBpc3N1ZSBNRUdBX01CT1hDTURfQURBUFRFUklOUSBjb21tYW5kIGFuZAoJICogdXBkYXRlIGVucXVpcnkzIHN0cnVjdHVyZQoJICovCgltYm94LT5tX291dC54ZmVyYWRkciA9ICh1MzIpYWRhcHRlci0+YnVmX2RtYV9oYW5kbGU7CgoJaW5xdWlyeTMgPSAobWVnYV9pbnF1aXJ5MyAqKWFkYXB0ZXItPm1lZ2FfYnVmZmVyOwoKCXJhd19tYm94WzBdID0gRkNfTkVXX0NPTkZJRzsJCS8qIGkuZS4gbWJveC0+Y21kPTB4QTEgKi8KCXJhd19tYm94WzJdID0gTkNfU1VCT1BfRU5RVUlSWTM7CS8qIGkuZS4gMHgwRiAqLwoJcmF3X21ib3hbM10gPSBFTlEzX0dFVF9TT0xJQ0lURURfRlVMTDsJLyogaS5lLiAweDAyICovCgoJLyogSXNzdWUgYSBibG9ja2luZyBjb21tYW5kIHRvIHRoZSBjYXJkICovCglpZiAoKHJldHZhbCA9IGlzc3VlX3NjYl9ibG9jayhhZGFwdGVyLCByYXdfbWJveCkpKSB7CgkJLyogdGhlIGFkYXB0ZXIgZG9lcyBub3Qgc3VwcG9ydCA0MGxkICovCgoJCW1yYWlkX2V4dF9pbnF1aXJ5CSpleHRfaW5xOwoJCW1yYWlkX2lucXVpcnkJCSppbnE7CgkJZG1hX2FkZHJfdAkJZG1hX2hhbmRsZTsKCgkJZXh0X2lucSA9IHBjaV9hbGxvY19jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwKCQkJCXNpemVvZihtcmFpZF9leHRfaW5xdWlyeSksICZkbWFfaGFuZGxlKTsKCgkJaWYoIGV4dF9pbnEgPT0gTlVMTCApIHJldHVybiAtMTsKCgkJaW5xID0gJmV4dF9pbnEtPnJhaWRfaW5xOwoKCQltYm94LT5tX291dC54ZmVyYWRkciA9ICh1MzIpZG1hX2hhbmRsZTsKCgkJLyppc3N1ZSBvbGQgMHgwNCBjb21tYW5kIHRvIGFkYXB0ZXIgKi8KCQltYm94LT5tX291dC5jbWQgPSBNRUdBX01CT1hDTURfQURQRVhUSU5ROwoKCQlpc3N1ZV9zY2JfYmxvY2soYWRhcHRlciwgcmF3X21ib3gpOwoKCQkvKgoJCSAqIHVwZGF0ZSBFbnF1aXJ5MyBhbmQgUHJvZHVjdEluZm8gc3RydWN0dXJlcyB3aXRoCgkJICogbXJhaWRfaW5xdWlyeSBzdHJ1Y3R1cmUKCQkgKi8KCQltZWdhXzhfdG9fNDBsZChpbnEsIGlucXVpcnkzLAoJCQkJKG1lZ2FfcHJvZHVjdF9pbmZvICopJmFkYXB0ZXItPnByb2R1Y3RfaW5mbyk7CgoJCXBjaV9mcmVlX2NvbnNpc3RlbnQoYWRhcHRlci0+ZGV2LCBzaXplb2YobXJhaWRfZXh0X2lucXVpcnkpLAoJCQkJZXh0X2lucSwgZG1hX2hhbmRsZSk7CgoJfSBlbHNlIHsJCS8qYWRhcHRlciBzdXBwb3J0cyA0MGxkICovCgkJYWRhcHRlci0+ZmxhZyB8PSBCT0FSRF80MExEOwoKCQkvKgoJCSAqIGdldCBwcm9kdWN0X2luZm8sIHdoaWNoIGlzIHN0YXRpYyBpbmZvcm1hdGlvbiBhbmQgd2lsbCBiZQoJCSAqIHVuY2hhbmdlZAoJCSAqLwoJCXByb2RfaW5mb19kbWFfaGFuZGxlID0gcGNpX21hcF9zaW5nbGUoYWRhcHRlci0+ZGV2LCAodm9pZCAqKQoJCQkJJmFkYXB0ZXItPnByb2R1Y3RfaW5mbywKCQkJCXNpemVvZihtZWdhX3Byb2R1Y3RfaW5mbyksIFBDSV9ETUFfRlJPTURFVklDRSk7CgoJCW1ib3gtPm1fb3V0LnhmZXJhZGRyID0gcHJvZF9pbmZvX2RtYV9oYW5kbGU7CgoJCXJhd19tYm94WzBdID0gRkNfTkVXX0NPTkZJRzsJLyogaS5lLiBtYm94LT5jbWQ9MHhBMSAqLwoJCXJhd19tYm94WzJdID0gTkNfU1VCT1BfUFJPRFVDVF9JTkZPOwkvKiBpLmUuIDB4MEUgKi8KCgkJaWYgKChyZXR2YWwgPSBpc3N1ZV9zY2JfYmxvY2soYWRhcHRlciwgcmF3X21ib3gpKSkKCQkJcHJpbnRrKEtFUk5fV0FSTklORwoJCQkibWVnYXJhaWQ6IFByb2R1Y3RfaW5mbyBjbWQgZmFpbGVkIHdpdGggZXJyb3I6ICVkXG4iLAoJCQkJcmV0dmFsKTsKCgkJcGNpX3VubWFwX3NpbmdsZShhZGFwdGVyLT5kZXYsIHByb2RfaW5mb19kbWFfaGFuZGxlLAoJCQkJc2l6ZW9mKG1lZ2FfcHJvZHVjdF9pbmZvKSwgUENJX0RNQV9GUk9NREVWSUNFKTsKCX0KCgoJLyoKCSAqIGtlcm5lbCBzY2FucyB0aGUgY2hhbm5lbHMgZnJvbSAwIHRvIDw9IG1heF9jaGFubmVsCgkgKi8KCWFkYXB0ZXItPmhvc3QtPm1heF9jaGFubmVsID0KCQlhZGFwdGVyLT5wcm9kdWN0X2luZm8ubmNoYW5uZWxzICsgTlZJUlRfQ0hBTiAtMTsKCglhZGFwdGVyLT5ob3N0LT5tYXhfaWQgPSAxNjsJLyogbWF4IHRhcmdldHMgcGVyIGNoYW5uZWwgKi8KCglhZGFwdGVyLT5ob3N0LT5tYXhfbHVuID0gNzsJLyogVXB0byA3IGx1bnMgZm9yIG5vbiBkaXNrIGRldmljZXMgKi8KCglhZGFwdGVyLT5ob3N0LT5jbWRfcGVyX2x1biA9IG1heF9jbWRfcGVyX2x1bjsKCglhZGFwdGVyLT5udW1sZHJ2ID0gaW5xdWlyeTMtPm51bV9sZHJ2OwoKCWFkYXB0ZXItPm1heF9jbWRzID0gYWRhcHRlci0+cHJvZHVjdF9pbmZvLm1heF9jb21tYW5kczsKCglpZihhZGFwdGVyLT5tYXhfY21kcyA+IE1BWF9DT01NQU5EUykKCQlhZGFwdGVyLT5tYXhfY21kcyA9IE1BWF9DT01NQU5EUzsKCglhZGFwdGVyLT5ob3N0LT5jYW5fcXVldWUgPSBhZGFwdGVyLT5tYXhfY21kcyAtIDE7CgoJLyoKCSAqIEdldCB0aGUgbWF4aW11bSBudW1iZXIgb2Ygc2NhdHRlci1nYXRoZXIgZWxlbWVudHMgc3VwcG9ydGVkIGJ5IHRoaXMKCSAqIGZpcm13YXJlCgkgKi8KCW1lZ2FfZ2V0X21heF9zZ2woYWRhcHRlcik7CgoJYWRhcHRlci0+aG9zdC0+c2dfdGFibGVzaXplID0gYWRhcHRlci0+c2dsZW47CgoKCS8qIHVzZSBIUCBmaXJtd2FyZSBhbmQgYmlvcyB2ZXJzaW9uIGVuY29kaW5nICovCglpZiAoYWRhcHRlci0+cHJvZHVjdF9pbmZvLnN1YnN5c3ZpZCA9PSBIUF9TVUJTWVNfVklEKSB7CgkJc3ByaW50ZiAoYWRhcHRlci0+ZndfdmVyc2lvbiwgIiVjJWQlZC4lZCVkIiwKCQkJIGFkYXB0ZXItPnByb2R1Y3RfaW5mby5md192ZXJzaW9uWzJdLAoJCQkgYWRhcHRlci0+cHJvZHVjdF9pbmZvLmZ3X3ZlcnNpb25bMV0gPj4gOCwKCQkJIGFkYXB0ZXItPnByb2R1Y3RfaW5mby5md192ZXJzaW9uWzFdICYgMHgwZiwKCQkJIGFkYXB0ZXItPnByb2R1Y3RfaW5mby5md192ZXJzaW9uWzBdID4+IDgsCgkJCSBhZGFwdGVyLT5wcm9kdWN0X2luZm8uZndfdmVyc2lvblswXSAmIDB4MGYpOwoJCXNwcmludGYgKGFkYXB0ZXItPmJpb3NfdmVyc2lvbiwgIiVjJWQlZC4lZCVkIiwKCQkJIGFkYXB0ZXItPnByb2R1Y3RfaW5mby5iaW9zX3ZlcnNpb25bMl0sCgkJCSBhZGFwdGVyLT5wcm9kdWN0X2luZm8uYmlvc192ZXJzaW9uWzFdID4+IDgsCgkJCSBhZGFwdGVyLT5wcm9kdWN0X2luZm8uYmlvc192ZXJzaW9uWzFdICYgMHgwZiwKCQkJIGFkYXB0ZXItPnByb2R1Y3RfaW5mby5iaW9zX3ZlcnNpb25bMF0gPj4gOCwKCQkJIGFkYXB0ZXItPnByb2R1Y3RfaW5mby5iaW9zX3ZlcnNpb25bMF0gJiAweDBmKTsKCX0gZWxzZSB7CgkJbWVtY3B5KGFkYXB0ZXItPmZ3X3ZlcnNpb24sCgkJCQkoY2hhciAqKWFkYXB0ZXItPnByb2R1Y3RfaW5mby5md192ZXJzaW9uLCA0KTsKCQlhZGFwdGVyLT5md192ZXJzaW9uWzRdID0gMDsKCgkJbWVtY3B5KGFkYXB0ZXItPmJpb3NfdmVyc2lvbiwKCQkJCShjaGFyICopYWRhcHRlci0+cHJvZHVjdF9pbmZvLmJpb3NfdmVyc2lvbiwgNCk7CgoJCWFkYXB0ZXItPmJpb3NfdmVyc2lvbls0XSA9IDA7Cgl9CgoJcHJpbnRrKEtFUk5fTk9USUNFICJtZWdhcmFpZDogWyVzOiVzXSBkZXRlY3RlZCAlZCBsb2dpY2FsIGRyaXZlcy5cbiIsCgkJYWRhcHRlci0+ZndfdmVyc2lvbiwgYWRhcHRlci0+Ymlvc192ZXJzaW9uLCBhZGFwdGVyLT5udW1sZHJ2KTsKCgkvKgoJICogRG8gd2Ugc3VwcG9ydCBleHRlbmRlZCAoPjEwIGJ5dGVzKSBjZGJzCgkgKi8KCWFkYXB0ZXItPnN1cHBvcnRfZXh0X2NkYiA9IG1lZ2Ffc3VwcG9ydF9leHRfY2RiKGFkYXB0ZXIpOwoJaWYgKGFkYXB0ZXItPnN1cHBvcnRfZXh0X2NkYikKCQlwcmludGsoS0VSTl9OT1RJQ0UgIm1lZ2FyYWlkOiBzdXBwb3J0cyBleHRlbmRlZCBDREJzLlxuIik7CgoKCXJldHVybiAwOwp9CgovKioKICogbWVnYV9ydW5wZW5kcSgpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBSdW5zIHRocm91Z2ggdGhlIGxpc3Qgb2YgcGVuZGluZyByZXF1ZXN0cy4KICovCnN0YXRpYyBpbmxpbmUgdm9pZAptZWdhX3J1bnBlbmRxKGFkYXB0ZXJfdCAqYWRhcHRlcikKewoJaWYoIWxpc3RfZW1wdHkoJmFkYXB0ZXItPnBlbmRpbmdfbGlzdCkpCgkJX19tZWdhX3J1bnBlbmRxKGFkYXB0ZXIpOwp9CgovKgogKiBtZWdhcmFpZF9xdWV1ZSgpCiAqIEBzY21kIC0gSXNzdWUgdGhpcyBzY3NpIGNvbW1hbmQKICogQGRvbmUgLSB0aGUgY2FsbGJhY2sgaG9vayBpbnRvIHRoZSBzY3NpIG1pZC1sYXllcgogKgogKiBUaGUgY29tbWFuZCBxdWV1aW5nIGVudHJ5IHBvaW50IGZvciB0aGUgbWlkLWxheWVyLgogKi8Kc3RhdGljIGludAptZWdhcmFpZF9xdWV1ZShTY3NpX0NtbmQgKnNjbWQsIHZvaWQgKCpkb25lKShTY3NpX0NtbmQgKikpCnsKCWFkYXB0ZXJfdAkqYWRhcHRlcjsKCXNjYl90CSpzY2I7CglpbnQJYnVzeT0wOwoKCWFkYXB0ZXIgPSAoYWRhcHRlcl90ICopc2NtZC0+ZGV2aWNlLT5ob3N0LT5ob3N0ZGF0YTsKCglzY21kLT5zY3NpX2RvbmUgPSBkb25lOwoKCgkvKgoJICogQWxsb2NhdGUgYW5kIGJ1aWxkIGEgU0NCIHJlcXVlc3QKCSAqIGJ1c3kgZmxhZyB3aWxsIGJlIHNldCBpZiBtZWdhX2J1aWxkX2NtZCgpIGNvbW1hbmQgY291bGQgbm90CgkgKiBhbGxvY2F0ZSBzY2IuIFdlIHdpbGwgcmV0dXJuIG5vbi16ZXJvIHN0YXR1cyBpbiB0aGF0IGNhc2UuCgkgKiBOT1RFOiBzY2IgY2FuIGJlIG51bGwgZXZlbiB0aG91Z2ggY2VydGFpbiBjb21tYW5kcyBjb21wbGV0ZWQKCSAqIHN1Y2Nlc3NmdWxseSwgZS5nLiwgTU9ERV9TRU5TRSBhbmQgVEVTVF9VTklUX1JFQURZLCB3ZSB3b3VsZAoJICogcmV0dXJuIDAgaW4gdGhhdCBjYXNlLgoJICovCgoJc2NiID0gbWVnYV9idWlsZF9jbWQoYWRhcHRlciwgc2NtZCwgJmJ1c3kpOwoKCWlmKHNjYikgewoJCXNjYi0+c3RhdGUgfD0gU0NCX1BFTkRROwoJCWxpc3RfYWRkX3RhaWwoJnNjYi0+bGlzdCwgJmFkYXB0ZXItPnBlbmRpbmdfbGlzdCk7CgoJCS8qCgkJICogQ2hlY2sgaWYgdGhlIEhCQSBpcyBpbiBxdWllc2NlbnQgc3RhdGUsIGUuZy4sIGR1cmluZyBhCgkJICogZGVsZXRlIGxvZ2ljYWwgZHJpdmUgb3BlcnRpb24uIElmIGl0IGlzLCBkb24ndCBydW4KCQkgKiB0aGUgcGVuZGluZ19saXN0LgoJCSAqLwoJCWlmKGF0b21pY19yZWFkKCZhZGFwdGVyLT5xdWllc2NlbnQpID09IDApIHsKCQkJbWVnYV9ydW5wZW5kcShhZGFwdGVyKTsKCQl9CgkJcmV0dXJuIDA7Cgl9CgoJcmV0dXJuIGJ1c3k7Cn0KCi8qKgogKiBtZWdhX2FsbG9jYXRlX3NjYigpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKiBAY21kIC0gc2NzaSBjb21tYW5kIGZyb20gdGhlIG1pZC1sYXllcgogKgogKiBBbGxvY2F0ZSBhIFNDQiBzdHJ1Y3R1cmUuIFRoaXMgaXMgdGhlIGNlbnRyYWwgc3RydWN0dXJlIGZvciBjb250cm9sbGVyCiAqIGNvbW1hbmRzLgogKi8Kc3RhdGljIGlubGluZSBzY2JfdCAqCm1lZ2FfYWxsb2NhdGVfc2NiKGFkYXB0ZXJfdCAqYWRhcHRlciwgU2NzaV9DbW5kICpjbWQpCnsKCXN0cnVjdCBsaXN0X2hlYWQgKmhlYWQgPSAmYWRhcHRlci0+ZnJlZV9saXN0OwoJc2NiX3QJKnNjYjsKCgkvKiBVbmxpbmsgY29tbWFuZCBmcm9tIEZyZWUgTGlzdCAqLwoJaWYoICFsaXN0X2VtcHR5KGhlYWQpICkgewoKCQlzY2IgPSBsaXN0X2VudHJ5KGhlYWQtPm5leHQsIHNjYl90LCBsaXN0KTsKCgkJbGlzdF9kZWxfaW5pdChoZWFkLT5uZXh0KTsKCgkJc2NiLT5zdGF0ZSA9IFNDQl9BQ1RJVkU7CgkJc2NiLT5jbWQgPSBjbWQ7CgkJc2NiLT5kbWFfdHlwZSA9IE1FR0FfRE1BX1RZUEVfTk9ORTsKCgkJcmV0dXJuIHNjYjsKCX0KCglyZXR1cm4gTlVMTDsKfQoKLyoqCiAqIG1lZ2FfZ2V0X2xkcnZfbnVtKCkKICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqIEBjbWQgLSBzY3NpIG1pZCBsYXllciBjb21tYW5kCiAqIEBjaGFubmVsIC0gY2hhbm5lbCBvbiB0aGUgY29udHJvbGxlcgogKgogKiBDYWxjdWxhdGUgdGhlIGxvZ2ljYWwgZHJpdmUgbnVtYmVyIGJhc2VkIG9uIHRoZSBpbmZvcm1hdGlvbiBpbiBzY3NpIGNvbW1hbmQKICogYW5kIHRoZSBjaGFubmVsIG51bWJlci4KICovCnN0YXRpYyBpbmxpbmUgaW50Cm1lZ2FfZ2V0X2xkcnZfbnVtKGFkYXB0ZXJfdCAqYWRhcHRlciwgU2NzaV9DbW5kICpjbWQsIGludCBjaGFubmVsKQp7CglpbnQJCXRndDsKCWludAkJbGRydl9udW07CgoJdGd0ID0gY21kLT5kZXZpY2UtPmlkOwoJCglpZiAoIHRndCA+IGFkYXB0ZXItPnRoaXNfaWQgKQoJCXRndC0tOwkvKiB3ZSBkbyBub3QgZ2V0IGlucXVpcmVzIGZvciBpbml0aWF0b3IgaWQgKi8KCglsZHJ2X251bSA9IChjaGFubmVsICogMTUpICsgdGd0OwoKCgkvKgoJICogSWYgd2UgaGF2ZSBhIGxvZ2ljYWwgZHJpdmUgd2l0aCBib290IGVuYWJsZWQsIHByb2plY3QgaXQgZmlyc3QKCSAqLwoJaWYoIGFkYXB0ZXItPmJvb3RfbGRydl9lbmFibGVkICkgewoJCWlmKCBsZHJ2X251bSA9PSAwICkgewoJCQlsZHJ2X251bSA9IGFkYXB0ZXItPmJvb3RfbGRydjsKCQl9CgkJZWxzZSB7CgkJCWlmKCBsZHJ2X251bSA8PSBhZGFwdGVyLT5ib290X2xkcnYgKSB7CgkJCQlsZHJ2X251bS0tOwoJCQl9CgkJfQoJfQoKCS8qCgkgKiBJZiAiZGVsZXRlIGxvZ2ljYWwgZHJpdmUiIGZlYXR1cmUgaXMgZW5hYmxlZCBvbiB0aGlzIGNvbnRyb2xsZXIuCgkgKiBEbyBvbmx5IGlmIGF0IGxlYXN0IG9uZSBkZWxldGUgbG9naWNhbCBkcml2ZSBvcGVyYXRpb24gd2FzIGRvbmUuCgkgKgoJICogQWxzbywgYWZ0ZXIgbG9naWNhbCBkcml2ZSBkZWxldGlvbiwgaW5zdGVhZCBvZiBsb2dpY2FsIGRyaXZlIG51bWJlciwKCSAqIHRoZSB2YWx1ZSByZXR1cm5lZCBzaG91bGQgYmUgMHg4MCtsb2dpY2FsIGRyaXZlIGlkLgoJICoKCSAqIFRoZXNlIGlzIHZhbGlkIG9ubHkgZm9yIElPIGNvbW1hbmRzLgoJICovCgoJaWYgKGFkYXB0ZXItPnN1cHBvcnRfcmFuZG9tX2RlbCAmJiBhZGFwdGVyLT5yZWFkX2xkaWRtYXAgKQoJCXN3aXRjaCAoY21kLT5jbW5kWzBdKSB7CgkJY2FzZSBSRUFEXzY6CS8qIGZhbGwgdGhyb3VnaCAqLwoJCWNhc2UgV1JJVEVfNjoJLyogZmFsbCB0aHJvdWdoICovCgkJY2FzZSBSRUFEXzEwOgkvKiBmYWxsIHRocm91Z2ggKi8KCQljYXNlIFdSSVRFXzEwOgoJCQlsZHJ2X251bSArPSAweDgwOwoJCX0KCglyZXR1cm4gbGRydl9udW07Cn0KCi8qKgogKiBtZWdhX2J1aWxkX2NtZCgpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKiBAY21kIC0gUHJlcGFyZSB1c2luZyB0aGlzIHNjc2kgY29tbWFuZAogKiBAYnVzeSAtIGJ1c3kgZmxhZyBpZiBubyByZXNvdXJjZXMKICoKICogUHJlcGFyZXMgYSBjb21tYW5kIGFuZCBzY2F0dGVyIGdhdGhlciBsaXN0IGZvciB0aGUgY29udHJvbGxlci4gVGhpcyByb3V0aW5lCiAqIGFsc28gZmluZHMgb3V0IGlmIHRoZSBjb21tYW5kcyBpcyBpbnRlbmRlZCBmb3IgYSBsb2dpY2FsIGRyaXZlIG9yIGEKICogcGh5c2ljYWwgZGV2aWNlIGFuZCBwcmVwYXJlcyB0aGUgY29udHJvbGxlciBjb21tYW5kIGFjY29yZGluZ2x5LgogKgogKiBXZSBhbHNvIHJlLW9yZGVyIHRoZSBsb2dpY2FsIGRyaXZlcyBhbmQgcGh5c2ljYWwgZGV2aWNlcyBiYXNlZCBvbiB0aGVpcgogKiBib290IHNldHRpbmdzLgogKi8Kc3RhdGljIHNjYl90ICoKbWVnYV9idWlsZF9jbWQoYWRhcHRlcl90ICphZGFwdGVyLCBTY3NpX0NtbmQgKmNtZCwgaW50ICpidXN5KQp7CgltZWdhX2V4dF9wYXNzdGhydQkqZXB0aHJ1OwoJbWVnYV9wYXNzdGhydQkqcHRocnU7CglzY2JfdAkqc2NiOwoJbWJveF90CSptYm94OwoJbG9uZwlzZWc7CgljaGFyCWlzbG9naWNhbDsKCWludAltYXhfbGRydl9udW07CglpbnQJY2hhbm5lbCA9IDA7CglpbnQJdGFyZ2V0ID0gMDsKCWludAlsZHJ2X251bSA9IDA7ICAgLyogbG9naWNhbCBkcml2ZSBudW1iZXIgKi8KCgoJLyoKCSAqIGZpbHRlciB0aGUgaW50ZXJuYWwgYW5kIGlvY3RsIGNvbW1hbmRzCgkgKi8KCWlmKChjbWQtPmNtbmRbMF0gPT0gTUVHQV9JTlRFUk5BTF9DTUQpKSB7CgkJcmV0dXJuIGNtZC0+YnVmZmVyOwoJfQoKCgkvKgoJICogV2Uga25vdyB3aGF0IGNoYW5uZWxzIG91ciBsb2dpY2FsIGRyaXZlcyBhcmUgb24gLSBtZWdhX2ZpbmRfY2FyZCgpCgkgKi8KCWlzbG9naWNhbCA9IGFkYXB0ZXItPmxvZ2Rydl9jaGFuW2NtZC0+ZGV2aWNlLT5jaGFubmVsXTsKCgkvKgoJICogVGhlIHRoZW9yeTogSWYgcGh5c2ljYWwgZHJpdmUgaXMgY2hvc2VuIGZvciBib290LCBhbGwgdGhlIHBoeXNpY2FsCgkgKiBkZXZpY2VzIGFyZSBleHBvcnRlZCBiZWZvcmUgdGhlIGxvZ2ljYWwgZHJpdmVzLCBvdGhlcndpc2UgcGh5c2ljYWwKCSAqIGRldmljZXMgYXJlIHB1c2hlZCBhZnRlciBsb2dpY2FsIGRyaXZlcywgaW4gd2hpY2ggY2FzZSAtIEtlcm5lbCBzZWVzCgkgKiB0aGUgcGh5c2ljYWwgZGV2aWNlcyBvbiB2aXJ0dWFsIGNoYW5uZWwgd2hpY2ggaXMgb2J2aW91c2x5IGNvbnZlcnRlZAoJICogdG8gYWN0dWFsIGNoYW5uZWwgb24gdGhlIEhCQS4KCSAqLwoJaWYoIGFkYXB0ZXItPmJvb3RfcGRydl9lbmFibGVkICkgewoJCWlmKCBpc2xvZ2ljYWwgKSB7CgkJCS8qIGxvZ2ljYWwgY2hhbm5lbCAqLwoJCQljaGFubmVsID0gY21kLT5kZXZpY2UtPmNoYW5uZWwgLQoJCQkJYWRhcHRlci0+cHJvZHVjdF9pbmZvLm5jaGFubmVsczsKCQl9CgkJZWxzZSB7CgkJCS8qIHRoaXMgaXMgcGh5c2ljYWwgY2hhbm5lbCAqLwoJCQljaGFubmVsID0gY21kLT5kZXZpY2UtPmNoYW5uZWw7IAoJCQl0YXJnZXQgPSBjbWQtPmRldmljZS0+aWQ7CgoJCQkvKgoJCQkgKiBib290IGZyb20gYSBwaHlzaWNhbCBkaXNrLCB0aGF0IGRpc2sgbmVlZHMgdG8gYmUKCQkJICogZXhwb3NlZCBmaXJzdCBJRiBib3RoIHRoZSBjaGFubmVscyBhcmUgU0NTSSwgdGhlbgoJCQkgKiBib290aW5nIGZyb20gdGhlIHNlY29uZCBjaGFubmVsIGlzIG5vdCBhbGxvd2VkLgoJCQkgKi8KCQkJaWYoIHRhcmdldCA9PSAwICkgewoJCQkJdGFyZ2V0ID0gYWRhcHRlci0+Ym9vdF9wZHJ2X3RndDsKCQkJfQoJCQllbHNlIGlmKCB0YXJnZXQgPT0gYWRhcHRlci0+Ym9vdF9wZHJ2X3RndCApIHsKCQkJCXRhcmdldCA9IDA7CgkJCX0KCQl9Cgl9CgllbHNlIHsKCQlpZiggaXNsb2dpY2FsICkgewoJCQkvKiB0aGlzIGlzIHRoZSBsb2dpY2FsIGNoYW5uZWwgKi8KCQkJY2hhbm5lbCA9IGNtZC0+ZGV2aWNlLT5jaGFubmVsOwkKCQl9CgkJZWxzZSB7CgkJCS8qIHBoeXNpY2FsIGNoYW5uZWwgKi8KCQkJY2hhbm5lbCA9IGNtZC0+ZGV2aWNlLT5jaGFubmVsIC0gTlZJUlRfQ0hBTjsJCgkJCXRhcmdldCA9IGNtZC0+ZGV2aWNlLT5pZDsKCQl9Cgl9CgoKCWlmKGlzbG9naWNhbCkgewoKCQkvKiBoYXZlIGp1c3QgTFVOIDAgZm9yIGVhY2ggdGFyZ2V0IG9uIHZpcnR1YWwgY2hhbm5lbHMgKi8KCQlpZiAoY21kLT5kZXZpY2UtPmx1bikgewoJCQljbWQtPnJlc3VsdCA9IChESURfQkFEX1RBUkdFVCA8PCAxNik7CgkJCWNtZC0+c2NzaV9kb25lKGNtZCk7CgkJCXJldHVybiBOVUxMOwoJCX0KCgkJbGRydl9udW0gPSBtZWdhX2dldF9sZHJ2X251bShhZGFwdGVyLCBjbWQsIGNoYW5uZWwpOwoKCgkJbWF4X2xkcnZfbnVtID0gKGFkYXB0ZXItPmZsYWcgJiBCT0FSRF80MExEKSA/CgkJCU1BWF9MT0dJQ0FMX0RSSVZFU180MExEIDogTUFYX0xPR0lDQUxfRFJJVkVTXzhMRDsKCgkJLyoKCQkgKiBtYXhfbGRydl9udW0gaW5jcmVhc2VzIGJ5IDB4ODAgaWYgc29tZSBsb2dpY2FsIGRyaXZlIHdhcwoJCSAqIGRlbGV0ZWQuCgkJICovCgkJaWYoYWRhcHRlci0+cmVhZF9sZGlkbWFwKQoJCQltYXhfbGRydl9udW0gKz0gMHg4MDsKCgkJaWYobGRydl9udW0gPiBtYXhfbGRydl9udW0gKSB7CgkJCWNtZC0+cmVzdWx0ID0gKERJRF9CQURfVEFSR0VUIDw8IDE2KTsKCQkJY21kLT5zY3NpX2RvbmUoY21kKTsKCQkJcmV0dXJuIE5VTEw7CgkJfQoKCX0KCWVsc2UgewoJCWlmKCBjbWQtPmRldmljZS0+bHVuID4gNykgewoJCQkvKgoJCQkgKiBEbyBub3Qgc3VwcG9ydCBsdW4gPjcgZm9yIHBoeXNpY2FsbHkgYWNjZXNzZWQKCQkJICogZGV2aWNlcwoJCQkgKi8KCQkJY21kLT5yZXN1bHQgPSAoRElEX0JBRF9UQVJHRVQgPDwgMTYpOwoJCQljbWQtPnNjc2lfZG9uZShjbWQpOwoJCQlyZXR1cm4gTlVMTDsKCQl9Cgl9CgoJLyoKCSAqCgkgKiBMb2dpY2FsIGRyaXZlIGNvbW1hbmRzCgkgKgoJICovCglpZihpc2xvZ2ljYWwpIHsKCQlzd2l0Y2ggKGNtZC0+Y21uZFswXSkgewoJCWNhc2UgVEVTVF9VTklUX1JFQURZOgoJCQltZW1zZXQoY21kLT5yZXF1ZXN0X2J1ZmZlciwgMCwgY21kLT5yZXF1ZXN0X2J1ZmZsZW4pOwoKI2lmIE1FR0FfSEFWRV9DTFVTVEVSSU5HCgkJCS8qCgkJCSAqIERvIHdlIHN1cHBvcnQgY2x1c3RlcmluZyBhbmQgaXMgdGhlIHN1cHBvcnQgZW5hYmxlZAoJCQkgKiBJZiBubywgcmV0dXJuIHN1Y2Nlc3MgYWx3YXlzCgkJCSAqLwoJCQlpZiggIWFkYXB0ZXItPmhhc19jbHVzdGVyICkgewoJCQkJY21kLT5yZXN1bHQgPSAoRElEX09LIDw8IDE2KTsKCQkJCWNtZC0+c2NzaV9kb25lKGNtZCk7CgkJCQlyZXR1cm4gTlVMTDsKCQkJfQoKCQkJaWYoIShzY2IgPSBtZWdhX2FsbG9jYXRlX3NjYihhZGFwdGVyLCBjbWQpKSkgewoJCQkJKmJ1c3kgPSAxOwoJCQkJcmV0dXJuIE5VTEw7CgkJCX0KCgkJCXNjYi0+cmF3X21ib3hbMF0gPSBNRUdBX0NMVVNURVJfQ01EOwoJCQlzY2ItPnJhd19tYm94WzJdID0gTUVHQV9SRVNFUlZBVElPTl9TVEFUVVM7CgkJCXNjYi0+cmF3X21ib3hbM10gPSBsZHJ2X251bTsKCgkJCXNjYi0+ZG1hX2RpcmVjdGlvbiA9IFBDSV9ETUFfTk9ORTsKCgkJCXJldHVybiBzY2I7CiNlbHNlCgkJCWNtZC0+cmVzdWx0ID0gKERJRF9PSyA8PCAxNik7CgkJCWNtZC0+c2NzaV9kb25lKGNtZCk7CgkJCXJldHVybiBOVUxMOwojZW5kaWYKCgkJY2FzZSBNT0RFX1NFTlNFOgoJCQltZW1zZXQoY21kLT5yZXF1ZXN0X2J1ZmZlciwgMCwgY21kLT5jbW5kWzRdKTsKCQkJY21kLT5yZXN1bHQgPSAoRElEX09LIDw8IDE2KTsKCQkJY21kLT5zY3NpX2RvbmUoY21kKTsKCQkJcmV0dXJuIE5VTEw7CgoJCWNhc2UgUkVBRF9DQVBBQ0lUWToKCQljYXNlIElOUVVJUlk6CgoJCQlpZighKGFkYXB0ZXItPmZsYWcgJiAoMUwgPDwgY21kLT5kZXZpY2UtPmNoYW5uZWwpKSkgewoKCQkJCXByaW50ayhLRVJOX05PVElDRQoJCQkJCSJzY3NpJWQ6IHNjYW5uaW5nIHNjc2kgY2hhbm5lbCAlZCAiLAoJCQkJCQlhZGFwdGVyLT5ob3N0LT5ob3N0X25vLAoJCQkJCQljbWQtPmRldmljZS0+Y2hhbm5lbCk7CgkJCQlwcmludGsoImZvciBsb2dpY2FsIGRyaXZlcy5cbiIpOwoKCQkJCWFkYXB0ZXItPmZsYWcgfD0gKDFMIDw8IGNtZC0+ZGV2aWNlLT5jaGFubmVsKTsKCQkJfQoKCQkJLyogQWxsb2NhdGUgYSBTQ0IgYW5kIGluaXRpYWxpemUgcGFzc3RocnUgKi8KCQkJaWYoIShzY2IgPSBtZWdhX2FsbG9jYXRlX3NjYihhZGFwdGVyLCBjbWQpKSkgewoJCQkJKmJ1c3kgPSAxOwoJCQkJcmV0dXJuIE5VTEw7CgkJCX0KCQkJcHRocnUgPSBzY2ItPnB0aHJ1OwoKCQkJbWJveCA9IChtYm94X3QgKilzY2ItPnJhd19tYm94OwoJCQltZW1zZXQobWJveCwgMCwgc2l6ZW9mKHNjYi0+cmF3X21ib3gpKTsKCQkJbWVtc2V0KHB0aHJ1LCAwLCBzaXplb2YobWVnYV9wYXNzdGhydSkpOwoKCQkJcHRocnUtPnRpbWVvdXQgPSAwOwoJCQlwdGhydS0+YXJzID0gMTsKCQkJcHRocnUtPnJlcXNlbnNlbGVuID0gMTQ7CgkJCXB0aHJ1LT5pc2xvZ2ljYWwgPSAxOwoJCQlwdGhydS0+bG9nZHJ2ID0gbGRydl9udW07CgkJCXB0aHJ1LT5jZGJsZW4gPSBjbWQtPmNtZF9sZW47CgkJCW1lbWNweShwdGhydS0+Y2RiLCBjbWQtPmNtbmQsIGNtZC0+Y21kX2xlbik7CgoJCQlpZiggYWRhcHRlci0+aGFzXzY0Yml0X2FkZHIgKSB7CgkJCQltYm94LT5tX291dC5jbWQgPSBNRUdBX01CT1hDTURfUEFTU1RIUlU2NDsKCQkJfQoJCQllbHNlIHsKCQkJCW1ib3gtPm1fb3V0LmNtZCA9IE1FR0FfTUJPWENNRF9QQVNTVEhSVTsKCQkJfQoKCQkJc2NiLT5kbWFfZGlyZWN0aW9uID0gUENJX0RNQV9GUk9NREVWSUNFOwoKCQkJcHRocnUtPm51bXNnZWxlbWVudHMgPSBtZWdhX2J1aWxkX3NnbGlzdChhZGFwdGVyLCBzY2IsCgkJCQkmcHRocnUtPmRhdGF4ZmVyYWRkciwgJnB0aHJ1LT5kYXRheGZlcmxlbik7CgoJCQltYm94LT5tX291dC54ZmVyYWRkciA9IHNjYi0+cHRocnVfZG1hX2FkZHI7CgoJCQlyZXR1cm4gc2NiOwoKCQljYXNlIFJFQURfNjoKCQljYXNlIFdSSVRFXzY6CgkJY2FzZSBSRUFEXzEwOgoJCWNhc2UgV1JJVEVfMTA6CgkJY2FzZSBSRUFEXzEyOgoJCWNhc2UgV1JJVEVfMTI6CgoJCQkvKiBBbGxvY2F0ZSBhIFNDQiBhbmQgaW5pdGlhbGl6ZSBtYWlsYm94ICovCgkJCWlmKCEoc2NiID0gbWVnYV9hbGxvY2F0ZV9zY2IoYWRhcHRlciwgY21kKSkpIHsKCQkJCSpidXN5ID0gMTsKCQkJCXJldHVybiBOVUxMOwoJCQl9CgkJCW1ib3ggPSAobWJveF90ICopc2NiLT5yYXdfbWJveDsKCgkJCW1lbXNldChtYm94LCAwLCBzaXplb2Yoc2NiLT5yYXdfbWJveCkpOwoJCQltYm94LT5tX291dC5sb2dkcnYgPSBsZHJ2X251bTsKCgkJCS8qCgkJCSAqIEEgbGl0dGxlIGhhY2s6IDJuZCBiaXQgaXMgemVybyBmb3IgYWxsIHNjc2kgcmVhZAoJCQkgKiBjb21tYW5kcyBhbmQgaXMgc2V0IGZvciBhbGwgc2NzaSB3cml0ZSBjb21tYW5kcwoJCQkgKi8KCQkJaWYoIGFkYXB0ZXItPmhhc182NGJpdF9hZGRyICkgewoJCQkJbWJveC0+bV9vdXQuY21kID0gKCpjbWQtPmNtbmQgJiAweDAyKSA/CgkJCQkJTUVHQV9NQk9YQ01EX0xXUklURTY0OgoJCQkJCU1FR0FfTUJPWENNRF9MUkVBRDY0IDsKCQkJfQoJCQllbHNlIHsKCQkJCW1ib3gtPm1fb3V0LmNtZCA9ICgqY21kLT5jbW5kICYgMHgwMikgPwoJCQkJCU1FR0FfTUJPWENNRF9MV1JJVEU6CgkJCQkJTUVHQV9NQk9YQ01EX0xSRUFEIDsKCQkJfQoKCQkJLyoKCQkJICogNi1ieXRlIFJFQUQoMHgwOCkgb3IgV1JJVEUoMHgwQSkgY2RiCgkJCSAqLwoJCQlpZiggY21kLT5jbWRfbGVuID09IDYgKSB7CgkJCQltYm94LT5tX291dC5udW1zZWN0b3JzID0gKHUzMikgY21kLT5jbW5kWzRdOwoJCQkJbWJveC0+bV9vdXQubGJhID0KCQkJCQkoKHUzMiljbWQtPmNtbmRbMV0gPDwgMTYpIHwKCQkJCQkoKHUzMiljbWQtPmNtbmRbMl0gPDwgOCkgfAoJCQkJCSh1MzIpY21kLT5jbW5kWzNdOwoKCQkJCW1ib3gtPm1fb3V0LmxiYSAmPSAweDFGRkZGRjsKCiNpZiBNRUdBX0hBVkVfU1RBVFMKCQkJCS8qCgkJCQkgKiBUYWtlIG1vZHVsbyAweDgwLCBzaW5jZSB0aGUgbG9naWNhbCBkcml2ZQoJCQkJICogbnVtYmVyIGluY3JlYXNlcyBieSAweDgwIHdoZW4gYSBsb2dpY2FsCgkJCQkgKiBkcml2ZSB3YXMgZGVsZXRlZAoJCQkJICovCgkJCQlpZiAoKmNtZC0+Y21uZCA9PSBSRUFEXzYpIHsKCQkJCQlhZGFwdGVyLT5ucmVhZHNbbGRydl9udW0lMHg4MF0rKzsKCQkJCQlhZGFwdGVyLT5ucmVhZGJsb2Nrc1tsZHJ2X251bSUweDgwXSArPQoJCQkJCQltYm94LT5tX291dC5udW1zZWN0b3JzOwoJCQkJfSBlbHNlIHsKCQkJCQlhZGFwdGVyLT5ud3JpdGVzW2xkcnZfbnVtJTB4ODBdKys7CgkJCQkJYWRhcHRlci0+bndyaXRlYmxvY2tzW2xkcnZfbnVtJTB4ODBdICs9CgkJCQkJCW1ib3gtPm1fb3V0Lm51bXNlY3RvcnM7CgkJCQl9CiNlbmRpZgoJCQl9CgoJCQkvKgoJCQkgKiAxMC1ieXRlIFJFQUQoMHgyOCkgb3IgV1JJVEUoMHgyQSkgY2RiCgkJCSAqLwoJCQlpZiggY21kLT5jbWRfbGVuID09IDEwICkgewoJCQkJbWJveC0+bV9vdXQubnVtc2VjdG9ycyA9CgkJCQkJKHUzMiljbWQtPmNtbmRbOF0gfAoJCQkJCSgodTMyKWNtZC0+Y21uZFs3XSA8PCA4KTsKCQkJCW1ib3gtPm1fb3V0LmxiYSA9CgkJCQkJKCh1MzIpY21kLT5jbW5kWzJdIDw8IDI0KSB8CgkJCQkJKCh1MzIpY21kLT5jbW5kWzNdIDw8IDE2KSB8CgkJCQkJKCh1MzIpY21kLT5jbW5kWzRdIDw8IDgpIHwKCQkJCQkodTMyKWNtZC0+Y21uZFs1XTsKCiNpZiBNRUdBX0hBVkVfU1RBVFMKCQkJCWlmICgqY21kLT5jbW5kID09IFJFQURfMTApIHsKCQkJCQlhZGFwdGVyLT5ucmVhZHNbbGRydl9udW0lMHg4MF0rKzsKCQkJCQlhZGFwdGVyLT5ucmVhZGJsb2Nrc1tsZHJ2X251bSUweDgwXSArPQoJCQkJCQltYm94LT5tX291dC5udW1zZWN0b3JzOwoJCQkJfSBlbHNlIHsKCQkJCQlhZGFwdGVyLT5ud3JpdGVzW2xkcnZfbnVtJTB4ODBdKys7CgkJCQkJYWRhcHRlci0+bndyaXRlYmxvY2tzW2xkcnZfbnVtJTB4ODBdICs9CgkJCQkJCW1ib3gtPm1fb3V0Lm51bXNlY3RvcnM7CgkJCQl9CiNlbmRpZgoJCQl9CgoJCQkvKgoJCQkgKiAxMi1ieXRlIFJFQUQoMHhBOCkgb3IgV1JJVEUoMHhBQSkgY2RiCgkJCSAqLwoJCQlpZiggY21kLT5jbWRfbGVuID09IDEyICkgewoJCQkJbWJveC0+bV9vdXQubGJhID0KCQkJCQkoKHUzMiljbWQtPmNtbmRbMl0gPDwgMjQpIHwKCQkJCQkoKHUzMiljbWQtPmNtbmRbM10gPDwgMTYpIHwKCQkJCQkoKHUzMiljbWQtPmNtbmRbNF0gPDwgOCkgfAoJCQkJCSh1MzIpY21kLT5jbW5kWzVdOwoKCQkJCW1ib3gtPm1fb3V0Lm51bXNlY3RvcnMgPQoJCQkJCSgodTMyKWNtZC0+Y21uZFs2XSA8PCAyNCkgfAoJCQkJCSgodTMyKWNtZC0+Y21uZFs3XSA8PCAxNikgfAoJCQkJCSgodTMyKWNtZC0+Y21uZFs4XSA8PCA4KSB8CgkJCQkJKHUzMiljbWQtPmNtbmRbOV07CgojaWYgTUVHQV9IQVZFX1NUQVRTCgkJCQlpZiAoKmNtZC0+Y21uZCA9PSBSRUFEXzEyKSB7CgkJCQkJYWRhcHRlci0+bnJlYWRzW2xkcnZfbnVtJTB4ODBdKys7CgkJCQkJYWRhcHRlci0+bnJlYWRibG9ja3NbbGRydl9udW0lMHg4MF0gKz0KCQkJCQkJbWJveC0+bV9vdXQubnVtc2VjdG9yczsKCQkJCX0gZWxzZSB7CgkJCQkJYWRhcHRlci0+bndyaXRlc1tsZHJ2X251bSUweDgwXSsrOwoJCQkJCWFkYXB0ZXItPm53cml0ZWJsb2Nrc1tsZHJ2X251bSUweDgwXSArPQoJCQkJCQltYm94LT5tX291dC5udW1zZWN0b3JzOwoJCQkJfQojZW5kaWYKCQkJfQoKCQkJLyoKCQkJICogSWYgaXQgaXMgYSByZWFkIGNvbW1hbmQKCQkJICovCgkJCWlmKCAoKmNtZC0+Y21uZCAmIDB4MEYpID09IDB4MDggKSB7CgkJCQlzY2ItPmRtYV9kaXJlY3Rpb24gPSBQQ0lfRE1BX0ZST01ERVZJQ0U7CgkJCX0KCQkJZWxzZSB7CgkJCQlzY2ItPmRtYV9kaXJlY3Rpb24gPSBQQ0lfRE1BX1RPREVWSUNFOwoJCQl9CgoJCQkvKiBDYWxjdWxhdGUgU2NhdHRlci1HYXRoZXIgaW5mbyAqLwoJCQltYm94LT5tX291dC5udW1zZ2VsZW1lbnRzID0gbWVnYV9idWlsZF9zZ2xpc3QoYWRhcHRlciwgc2NiLAoJCQkJCSh1MzIgKikmbWJveC0+bV9vdXQueGZlcmFkZHIsICh1MzIgKikmc2VnKTsKCgkJCXJldHVybiBzY2I7CgojaWYgTUVHQV9IQVZFX0NMVVNURVJJTkcKCQljYXNlIFJFU0VSVkU6CS8qIEZhbGwgdGhyb3VnaCAqLwoJCWNhc2UgUkVMRUFTRToKCgkJCS8qCgkJCSAqIERvIHdlIHN1cHBvcnQgY2x1c3RlcmluZyBhbmQgaXMgdGhlIHN1cHBvcnQgZW5hYmxlZAoJCQkgKi8KCQkJaWYoICEgYWRhcHRlci0+aGFzX2NsdXN0ZXIgKSB7CgoJCQkJY21kLT5yZXN1bHQgPSAoRElEX0JBRF9UQVJHRVQgPDwgMTYpOwoJCQkJY21kLT5zY3NpX2RvbmUoY21kKTsKCQkJCXJldHVybiBOVUxMOwoJCQl9CgoJCQkvKiBBbGxvY2F0ZSBhIFNDQiBhbmQgaW5pdGlhbGl6ZSBtYWlsYm94ICovCgkJCWlmKCEoc2NiID0gbWVnYV9hbGxvY2F0ZV9zY2IoYWRhcHRlciwgY21kKSkpIHsKCQkJCSpidXN5ID0gMTsKCQkJCXJldHVybiBOVUxMOwoJCQl9CgoJCQlzY2ItPnJhd19tYm94WzBdID0gTUVHQV9DTFVTVEVSX0NNRDsKCQkJc2NiLT5yYXdfbWJveFsyXSA9ICggKmNtZC0+Y21uZCA9PSBSRVNFUlZFICkgPwoJCQkJTUVHQV9SRVNFUlZFX0xEIDogTUVHQV9SRUxFQVNFX0xEOwoKCQkJc2NiLT5yYXdfbWJveFszXSA9IGxkcnZfbnVtOwoKCQkJc2NiLT5kbWFfZGlyZWN0aW9uID0gUENJX0RNQV9OT05FOwoKCQkJcmV0dXJuIHNjYjsKI2VuZGlmCgoJCWRlZmF1bHQ6CgkJCWNtZC0+cmVzdWx0ID0gKERJRF9CQURfVEFSR0VUIDw8IDE2KTsKCQkJY21kLT5zY3NpX2RvbmUoY21kKTsKCQkJcmV0dXJuIE5VTEw7CgkJfQoJfQoKCS8qCgkgKiBQYXNzdGhydSBkcml2ZSBjb21tYW5kcwoJICovCgllbHNlIHsKCQkvKiBBbGxvY2F0ZSBhIFNDQiBhbmQgaW5pdGlhbGl6ZSBwYXNzdGhydSAqLwoJCWlmKCEoc2NiID0gbWVnYV9hbGxvY2F0ZV9zY2IoYWRhcHRlciwgY21kKSkpIHsKCQkJKmJ1c3kgPSAxOwoJCQlyZXR1cm4gTlVMTDsKCQl9CgoJCW1ib3ggPSAobWJveF90ICopc2NiLT5yYXdfbWJveDsKCQltZW1zZXQobWJveCwgMCwgc2l6ZW9mKHNjYi0+cmF3X21ib3gpKTsKCgkJaWYoIGFkYXB0ZXItPnN1cHBvcnRfZXh0X2NkYiApIHsKCgkJCWVwdGhydSA9IG1lZ2FfcHJlcGFyZV9leHRwYXNzdGhydShhZGFwdGVyLCBzY2IsIGNtZCwKCQkJCQljaGFubmVsLCB0YXJnZXQpOwoKCQkJbWJveC0+bV9vdXQuY21kID0gTUVHQV9NQk9YQ01EX0VYVFBUSFJVOwoKCQkJbWJveC0+bV9vdXQueGZlcmFkZHIgPSBzY2ItPmVwdGhydV9kbWFfYWRkcjsKCgkJfQoJCWVsc2UgewoKCQkJcHRocnUgPSBtZWdhX3ByZXBhcmVfcGFzc3RocnUoYWRhcHRlciwgc2NiLCBjbWQsCgkJCQkJY2hhbm5lbCwgdGFyZ2V0KTsKCgkJCS8qIEluaXRpYWxpemUgbWFpbGJveCAqLwoJCQlpZiggYWRhcHRlci0+aGFzXzY0Yml0X2FkZHIgKSB7CgkJCQltYm94LT5tX291dC5jbWQgPSBNRUdBX01CT1hDTURfUEFTU1RIUlU2NDsKCQkJfQoJCQllbHNlIHsKCQkJCW1ib3gtPm1fb3V0LmNtZCA9IE1FR0FfTUJPWENNRF9QQVNTVEhSVTsKCQkJfQoKCQkJbWJveC0+bV9vdXQueGZlcmFkZHIgPSBzY2ItPnB0aHJ1X2RtYV9hZGRyOwoKCQl9CgkJcmV0dXJuIHNjYjsKCX0KCXJldHVybiBOVUxMOwp9CgoKLyoqCiAqIG1lZ2FfcHJlcGFyZV9wYXNzdGhydSgpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKiBAc2NiIC0gb3VyIHNjc2kgY29udHJvbCBibG9jawogKiBAY21kIC0gc2NzaSBjb21tYW5kIGZyb20gdGhlIG1pZC1sYXllcgogKiBAY2hhbm5lbCAtIGFjdHVhbCBjaGFubmVsIG9uIHRoZSBjb250cm9sbGVyCiAqIEB0YXJnZXQgLSBhY3R1YWwgaWQgb24gdGhlIGNvbnRyb2xsZXIuCiAqCiAqIHByZXBhcmUgYSBjb21tYW5kIGZvciB0aGUgc2NzaSBwaHlzaWNhbCBkZXZpY2VzLgogKi8Kc3RhdGljIG1lZ2FfcGFzc3RocnUgKgptZWdhX3ByZXBhcmVfcGFzc3RocnUoYWRhcHRlcl90ICphZGFwdGVyLCBzY2JfdCAqc2NiLCBTY3NpX0NtbmQgKmNtZCwKCQlpbnQgY2hhbm5lbCwgaW50IHRhcmdldCkKewoJbWVnYV9wYXNzdGhydSAqcHRocnU7CgoJcHRocnUgPSBzY2ItPnB0aHJ1OwoJbWVtc2V0KHB0aHJ1LCAwLCBzaXplb2YgKG1lZ2FfcGFzc3RocnUpKTsKCgkvKiAwPTZzZWMvMT02MHNlYy8yPTEwbWluLzM9M2hycyAqLwoJcHRocnUtPnRpbWVvdXQgPSAyOwoKCXB0aHJ1LT5hcnMgPSAxOwoJcHRocnUtPnJlcXNlbnNlbGVuID0gMTQ7CglwdGhydS0+aXNsb2dpY2FsID0gMDsKCglwdGhydS0+Y2hhbm5lbCA9IChhZGFwdGVyLT5mbGFnICYgQk9BUkRfNDBMRCkgPyAwIDogY2hhbm5lbDsKCglwdGhydS0+dGFyZ2V0ID0gKGFkYXB0ZXItPmZsYWcgJiBCT0FSRF80MExEKSA/CgkJKGNoYW5uZWwgPDwgNCkgfCB0YXJnZXQgOiB0YXJnZXQ7CgoJcHRocnUtPmNkYmxlbiA9IGNtZC0+Y21kX2xlbjsKCXB0aHJ1LT5sb2dkcnYgPSBjbWQtPmRldmljZS0+bHVuOwoKCW1lbWNweShwdGhydS0+Y2RiLCBjbWQtPmNtbmQsIGNtZC0+Y21kX2xlbik7CgoJLyogTm90IHN1cmUgYWJvdXQgdGhlIGRpcmVjdGlvbiAqLwoJc2NiLT5kbWFfZGlyZWN0aW9uID0gUENJX0RNQV9CSURJUkVDVElPTkFMOwoKCS8qIFNwZWNpYWwgQ29kZSBmb3IgSGFuZGxpbmcgUkVBRF9DQVBBLyBJTlEgdXNpbmcgYm91bmNlIGJ1ZmZlcnMgKi8KCXN3aXRjaCAoY21kLT5jbW5kWzBdKSB7CgljYXNlIElOUVVJUlk6CgljYXNlIFJFQURfQ0FQQUNJVFk6CgkJaWYoIShhZGFwdGVyLT5mbGFnICYgKDFMIDw8IGNtZC0+ZGV2aWNlLT5jaGFubmVsKSkpIHsKCgkJCXByaW50ayhLRVJOX05PVElDRQoJCQkJInNjc2klZDogc2Nhbm5pbmcgc2NzaSBjaGFubmVsICVkIFtQJWRdICIsCgkJCQkJYWRhcHRlci0+aG9zdC0+aG9zdF9ubywKCQkJCQljbWQtPmRldmljZS0+Y2hhbm5lbCwgY2hhbm5lbCk7CgkJCXByaW50aygiZm9yIHBoeXNpY2FsIGRldmljZXMuXG4iKTsKCgkJCWFkYXB0ZXItPmZsYWcgfD0gKDFMIDw8IGNtZC0+ZGV2aWNlLT5jaGFubmVsKTsKCQl9CgkJLyogRmFsbCB0aHJvdWdoICovCglkZWZhdWx0OgoJCXB0aHJ1LT5udW1zZ2VsZW1lbnRzID0gbWVnYV9idWlsZF9zZ2xpc3QoYWRhcHRlciwgc2NiLAoJCQkJJnB0aHJ1LT5kYXRheGZlcmFkZHIsICZwdGhydS0+ZGF0YXhmZXJsZW4pOwoJCWJyZWFrOwoJfQoJcmV0dXJuIHB0aHJ1Owp9CgoKLyoqCiAqIG1lZ2FfcHJlcGFyZV9leHRwYXNzdGhydSgpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKiBAc2NiIC0gb3VyIHNjc2kgY29udHJvbCBibG9jawogKiBAY21kIC0gc2NzaSBjb21tYW5kIGZyb20gdGhlIG1pZC1sYXllcgogKiBAY2hhbm5lbCAtIGFjdHVhbCBjaGFubmVsIG9uIHRoZSBjb250cm9sbGVyCiAqIEB0YXJnZXQgLSBhY3R1YWwgaWQgb24gdGhlIGNvbnRyb2xsZXIuCiAqCiAqIHByZXBhcmUgYSBjb21tYW5kIGZvciB0aGUgc2NzaSBwaHlzaWNhbCBkZXZpY2VzLiBUaGlzIHJvdW50aW5lIHByZXBhcmVzCiAqIGNvbW1hbmRzIGZvciBkZXZpY2VzIHdoaWNoIGNhbiB0YWtlIGV4dGVuZGVkIENEQnMgKD4xMCBieXRlcykKICovCnN0YXRpYyBtZWdhX2V4dF9wYXNzdGhydSAqCm1lZ2FfcHJlcGFyZV9leHRwYXNzdGhydShhZGFwdGVyX3QgKmFkYXB0ZXIsIHNjYl90ICpzY2IsIFNjc2lfQ21uZCAqY21kLAoJCWludCBjaGFubmVsLCBpbnQgdGFyZ2V0KQp7CgltZWdhX2V4dF9wYXNzdGhydQkqZXB0aHJ1OwoKCWVwdGhydSA9IHNjYi0+ZXB0aHJ1OwoJbWVtc2V0KGVwdGhydSwgMCwgc2l6ZW9mKG1lZ2FfZXh0X3Bhc3N0aHJ1KSk7CgoJLyogMD02c2VjLzE9NjBzZWMvMj0xMG1pbi8zPTNocnMgKi8KCWVwdGhydS0+dGltZW91dCA9IDI7CgoJZXB0aHJ1LT5hcnMgPSAxOwoJZXB0aHJ1LT5yZXFzZW5zZWxlbiA9IDE0OwoJZXB0aHJ1LT5pc2xvZ2ljYWwgPSAwOwoKCWVwdGhydS0+Y2hhbm5lbCA9IChhZGFwdGVyLT5mbGFnICYgQk9BUkRfNDBMRCkgPyAwIDogY2hhbm5lbDsKCWVwdGhydS0+dGFyZ2V0ID0gKGFkYXB0ZXItPmZsYWcgJiBCT0FSRF80MExEKSA/CgkJKGNoYW5uZWwgPDwgNCkgfCB0YXJnZXQgOiB0YXJnZXQ7CgoJZXB0aHJ1LT5jZGJsZW4gPSBjbWQtPmNtZF9sZW47CgllcHRocnUtPmxvZ2RydiA9IGNtZC0+ZGV2aWNlLT5sdW47CgoJbWVtY3B5KGVwdGhydS0+Y2RiLCBjbWQtPmNtbmQsIGNtZC0+Y21kX2xlbik7CgoJLyogTm90IHN1cmUgYWJvdXQgdGhlIGRpcmVjdGlvbiAqLwoJc2NiLT5kbWFfZGlyZWN0aW9uID0gUENJX0RNQV9CSURJUkVDVElPTkFMOwoKCXN3aXRjaChjbWQtPmNtbmRbMF0pIHsKCWNhc2UgSU5RVUlSWToKCWNhc2UgUkVBRF9DQVBBQ0lUWToKCQlpZighKGFkYXB0ZXItPmZsYWcgJiAoMUwgPDwgY21kLT5kZXZpY2UtPmNoYW5uZWwpKSkgewoKCQkJcHJpbnRrKEtFUk5fTk9USUNFCgkJCQkic2NzaSVkOiBzY2FubmluZyBzY3NpIGNoYW5uZWwgJWQgW1AlZF0gIiwKCQkJCQlhZGFwdGVyLT5ob3N0LT5ob3N0X25vLAoJCQkJCWNtZC0+ZGV2aWNlLT5jaGFubmVsLCBjaGFubmVsKTsKCQkJcHJpbnRrKCJmb3IgcGh5c2ljYWwgZGV2aWNlcy5cbiIpOwoKCQkJYWRhcHRlci0+ZmxhZyB8PSAoMUwgPDwgY21kLT5kZXZpY2UtPmNoYW5uZWwpOwoJCX0KCQkvKiBGYWxsIHRocm91Z2ggKi8KCWRlZmF1bHQ6CgkJZXB0aHJ1LT5udW1zZ2VsZW1lbnRzID0gbWVnYV9idWlsZF9zZ2xpc3QoYWRhcHRlciwgc2NiLAoJCQkJJmVwdGhydS0+ZGF0YXhmZXJhZGRyLCAmZXB0aHJ1LT5kYXRheGZlcmxlbik7CgkJYnJlYWs7Cgl9CgoJcmV0dXJuIGVwdGhydTsKfQoKc3RhdGljIHZvaWQKX19tZWdhX3J1bnBlbmRxKGFkYXB0ZXJfdCAqYWRhcHRlcikKewoJc2NiX3QgKnNjYjsKCXN0cnVjdCBsaXN0X2hlYWQgKnBvcywgKm5leHQ7CgoJLyogSXNzdWUgYW55IHBlbmRpbmcgY29tbWFuZHMgdG8gdGhlIGNhcmQgKi8KCWxpc3RfZm9yX2VhY2hfc2FmZShwb3MsIG5leHQsICZhZGFwdGVyLT5wZW5kaW5nX2xpc3QpIHsKCgkJc2NiID0gbGlzdF9lbnRyeShwb3MsIHNjYl90LCBsaXN0KTsKCgkJaWYoICEoc2NiLT5zdGF0ZSAmIFNDQl9JU1NVRUQpICkgewoKCQkJaWYoIGlzc3VlX3NjYihhZGFwdGVyLCBzY2IpICE9IDAgKQoJCQkJcmV0dXJuOwoJCX0KCX0KCglyZXR1cm47Cn0KCgovKioKICogaXNzdWVfc2NiKCkKICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqIEBzY2IgLSBzY3NpIGNvbnRyb2wgYmxvY2sKICoKICogUG9zdCBhIGNvbW1hbmQgdG8gdGhlIGNhcmQgaWYgdGhlIG1haWxib3ggaXMgYXZhaWxhYmxlLCBvdGhlcndpc2UgcmV0dXJuCiAqIGJ1c3kuIFdlIGFsc28gdGFrZSB0aGUgc2NiIGZyb20gdGhlIHBlbmRpbmcgbGlzdCBpZiB0aGUgbWFpbGJveCBpcwogKiBhdmFpbGFibGUuCiAqLwpzdGF0aWMgaW50Cmlzc3VlX3NjYihhZGFwdGVyX3QgKmFkYXB0ZXIsIHNjYl90ICpzY2IpCnsKCXZvbGF0aWxlIG1ib3g2NF90CSptYm94NjQgPSBhZGFwdGVyLT5tYm94NjQ7Cgl2b2xhdGlsZSBtYm94X3QJCSptYm94ID0gYWRhcHRlci0+bWJveDsKCXVuc2lnbmVkIGludAlpID0gMDsKCglpZih1bmxpa2VseShtYm94LT5tX2luLmJ1c3kpKSB7CgkJZG8gewoJCQl1ZGVsYXkoMSk7CgkJCWkrKzsKCQl9IHdoaWxlKCBtYm94LT5tX2luLmJ1c3kgJiYgKGkgPCBtYXhfbWJveF9idXN5X3dhaXQpICk7CgoJCWlmKG1ib3gtPm1faW4uYnVzeSkgcmV0dXJuIC0xOwoJfQoKCS8qIENvcHkgbWFpbGJveCBkYXRhIGludG8gaG9zdCBzdHJ1Y3R1cmUgKi8KCW1lbWNweSgoY2hhciAqKSZtYm94LT5tX291dCwgKGNoYXIgKilzY2ItPnJhd19tYm94LCAKCQkJc2l6ZW9mKHN0cnVjdCBtYm94X291dCkpOwoKCW1ib3gtPm1fb3V0LmNtZGlkID0gc2NiLT5pZHg7CS8qIFNldCBjbWRpZCAqLwoJbWJveC0+bV9pbi5idXN5ID0gMTsJCS8qIFNldCBidXN5ICovCgoKCS8qCgkgKiBJbmNyZW1lbnQgdGhlIHBlbmRpbmcgcXVldWUgY291bnRlcgoJICovCglhdG9taWNfaW5jKCZhZGFwdGVyLT5wZW5kX2NtZHMpOwoKCXN3aXRjaCAobWJveC0+bV9vdXQuY21kKSB7CgljYXNlIE1FR0FfTUJPWENNRF9MUkVBRDY0OgoJY2FzZSBNRUdBX01CT1hDTURfTFdSSVRFNjQ6CgljYXNlIE1FR0FfTUJPWENNRF9QQVNTVEhSVTY0OgoJY2FzZSBNRUdBX01CT1hDTURfRVhUUFRIUlU6CgkJbWJveDY0LT54ZmVyX3NlZ21lbnRfbG8gPSBtYm94LT5tX291dC54ZmVyYWRkcjsKCQltYm94NjQtPnhmZXJfc2VnbWVudF9oaSA9IDA7CgkJbWJveC0+bV9vdXQueGZlcmFkZHIgPSAweEZGRkZGRkZGOwoJCWJyZWFrOwoJZGVmYXVsdDoKCQltYm94NjQtPnhmZXJfc2VnbWVudF9sbyA9IDA7CgkJbWJveDY0LT54ZmVyX3NlZ21lbnRfaGkgPSAwOwoJfQoKCS8qCgkgKiBwb3N0IHRoZSBjb21tYW5kCgkgKi8KCXNjYi0+c3RhdGUgfD0gU0NCX0lTU1VFRDsKCglpZiggbGlrZWx5KGFkYXB0ZXItPmZsYWcgJiBCT0FSRF9NRU1NQVApICkgewoJCW1ib3gtPm1faW4ucG9sbCA9IDA7CgkJbWJveC0+bV9pbi5hY2sgPSAwOwoJCVdSSU5ET09SKGFkYXB0ZXIsIGFkYXB0ZXItPm1ib3hfZG1hIHwgMHgxKTsKCX0KCWVsc2UgewoJCWlycV9lbmFibGUoYWRhcHRlcik7CgkJaXNzdWVfY29tbWFuZChhZGFwdGVyKTsKCX0KCglyZXR1cm4gMDsKfQoKLyoKICogV2FpdCB1bnRpbCB0aGUgY29udHJvbGxlcidzIG1haWxib3ggaXMgYXZhaWxhYmxlCiAqLwpzdGF0aWMgaW5saW5lIGludAptZWdhX2J1c3l3YWl0X21ib3ggKGFkYXB0ZXJfdCAqYWRhcHRlcikKewoJaWYgKGFkYXB0ZXItPm1ib3gtPm1faW4uYnVzeSkKCQlyZXR1cm4gX19tZWdhX2J1c3l3YWl0X21ib3goYWRhcHRlcik7CglyZXR1cm4gMDsKfQoKLyoqCiAqIGlzc3VlX3NjYl9ibG9jaygpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKiBAcmF3X21ib3ggLSB0aGUgbWFpbGJveAogKgogKiBJc3N1ZSBhIHNjYiBpbiBzeW5jaHJvbm91cyBhbmQgbm9uLWludGVycnVwdCBtb2RlCiAqLwpzdGF0aWMgaW50Cmlzc3VlX3NjYl9ibG9jayhhZGFwdGVyX3QgKmFkYXB0ZXIsIHVfY2hhciAqcmF3X21ib3gpCnsKCXZvbGF0aWxlIG1ib3g2NF90ICptYm94NjQgPSBhZGFwdGVyLT5tYm94NjQ7Cgl2b2xhdGlsZSBtYm94X3QgKm1ib3ggPSBhZGFwdGVyLT5tYm94OwoJdTgJYnl0ZTsKCgkvKiBXYWl0IHVudGlsIG1haWxib3ggaXMgZnJlZSAqLwoJaWYobWVnYV9idXN5d2FpdF9tYm94IChhZGFwdGVyKSkKCQlnb3RvIGJ1Z19ibG9ja2VkX21haWxib3g7CgoJLyogQ29weSBtYWlsYm94IGRhdGEgaW50byBob3N0IHN0cnVjdHVyZSAqLwoJbWVtY3B5KChjaGFyICopIG1ib3gsIHJhd19tYm94LCBzaXplb2Yoc3RydWN0IG1ib3hfb3V0KSk7CgltYm94LT5tX291dC5jbWRpZCA9IDB4RkU7CgltYm94LT5tX2luLmJ1c3kgPSAxOwoKCXN3aXRjaCAocmF3X21ib3hbMF0pIHsKCWNhc2UgTUVHQV9NQk9YQ01EX0xSRUFENjQ6CgljYXNlIE1FR0FfTUJPWENNRF9MV1JJVEU2NDoKCWNhc2UgTUVHQV9NQk9YQ01EX1BBU1NUSFJVNjQ6CgljYXNlIE1FR0FfTUJPWENNRF9FWFRQVEhSVToKCQltYm94NjQtPnhmZXJfc2VnbWVudF9sbyA9IG1ib3gtPm1fb3V0LnhmZXJhZGRyOwoJCW1ib3g2NC0+eGZlcl9zZWdtZW50X2hpID0gMDsKCQltYm94LT5tX291dC54ZmVyYWRkciA9IDB4RkZGRkZGRkY7CgkJYnJlYWs7CglkZWZhdWx0OgoJCW1ib3g2NC0+eGZlcl9zZWdtZW50X2xvID0gMDsKCQltYm94NjQtPnhmZXJfc2VnbWVudF9oaSA9IDA7Cgl9CgoJaWYoIGxpa2VseShhZGFwdGVyLT5mbGFnICYgQk9BUkRfTUVNTUFQKSApIHsKCQltYm94LT5tX2luLnBvbGwgPSAwOwoJCW1ib3gtPm1faW4uYWNrID0gMDsKCQltYm94LT5tX2luLm51bXN0YXR1cyA9IDB4RkY7CgkJbWJveC0+bV9pbi5zdGF0dXMgPSAweEZGOwoJCVdSSU5ET09SKGFkYXB0ZXIsIGFkYXB0ZXItPm1ib3hfZG1hIHwgMHgxKTsKCgkJd2hpbGUoKHZvbGF0aWxlIHU4KW1ib3gtPm1faW4ubnVtc3RhdHVzID09IDB4RkYpCgkJCWNwdV9yZWxheCgpOwoKCQltYm94LT5tX2luLm51bXN0YXR1cyA9IDB4RkY7CgoJCXdoaWxlKCAodm9sYXRpbGUgdTgpbWJveC0+bV9pbi5wb2xsICE9IDB4NzcgKQoJCQljcHVfcmVsYXgoKTsKCgkJbWJveC0+bV9pbi5wb2xsID0gMDsKCQltYm94LT5tX2luLmFjayA9IDB4Nzc7CgoJCVdSSU5ET09SKGFkYXB0ZXIsIGFkYXB0ZXItPm1ib3hfZG1hIHwgMHgyKTsKCgkJd2hpbGUoUkRJTkRPT1IoYWRhcHRlcikgJiAweDIpCgkJCWNwdV9yZWxheCgpOwoJfQoJZWxzZSB7CgkJaXJxX2Rpc2FibGUoYWRhcHRlcik7CgkJaXNzdWVfY29tbWFuZChhZGFwdGVyKTsKCgkJd2hpbGUgKCEoKGJ5dGUgPSBpcnFfc3RhdGUoYWRhcHRlcikpICYgSU5UUl9WQUxJRCkpCgkJCWNwdV9yZWxheCgpOwoKCQlzZXRfaXJxX3N0YXRlKGFkYXB0ZXIsIGJ5dGUpOwoJCWlycV9lbmFibGUoYWRhcHRlcik7CgkJaXJxX2FjayhhZGFwdGVyKTsKCX0KCglyZXR1cm4gbWJveC0+bV9pbi5zdGF0dXM7CgpidWdfYmxvY2tlZF9tYWlsYm94OgoJcHJpbnRrKEtFUk5fV0FSTklORyAibWVnYXJhaWQ6IEJsb2NrZWQgbWFpbGJveC4uLi4uLiEhXG4iKTsKCXVkZWxheSAoMTAwMCk7CglyZXR1cm4gLTE7Cn0KCgovKioKICogbWVnYXJhaWRfaXNyX2lvbWFwcGVkKCkKICogQGlycSAtIGlycQogKiBAZGV2cCAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICogQHJlZ3MgLSB1bnVzZWQKICoKICogSW50ZXJydXB0IHNlcnZpY2Ugcm91dGluZSBmb3IgaW8tbWFwcGVkIGNvbnRyb2xsZXJzLgogKiBGaW5kIG91dCBpZiBvdXIgZGV2aWNlIGlzIGludGVycnVwdGluZy4gSWYgeWVzLCBhY2tub3dsZWRnZSB0aGUgaW50ZXJydXB0CiAqIGFuZCBzZXJ2aWNlIHRoZSBjb21wbGV0ZWQgY29tbWFuZHMuCiAqLwpzdGF0aWMgaXJxcmV0dXJuX3QKbWVnYXJhaWRfaXNyX2lvbWFwcGVkKGludCBpcnEsIHZvaWQgKmRldnAsIHN0cnVjdCBwdF9yZWdzICpyZWdzKQp7CglhZGFwdGVyX3QJKmFkYXB0ZXIgPSBkZXZwOwoJdW5zaWduZWQgbG9uZwlmbGFnczsKCXU4CXN0YXR1czsKCXU4CW5zdGF0dXM7Cgl1OAljb21wbGV0ZWRbTUFYX0ZJUk1XQVJFX1NUQVRVU107Cgl1OAlieXRlOwoJaW50CWhhbmRsZWQgPSAwOwoKCgkvKgoJICogbG9vcCB0aWxsIEYvVyBoYXMgbW9yZSBjb21tYW5kcyBmb3IgdXMgdG8gY29tcGxldGUuCgkgKi8KCXNwaW5fbG9ja19pcnFzYXZlKCZhZGFwdGVyLT5sb2NrLCBmbGFncyk7CgoJZG8gewoJCS8qIENoZWNrIGlmIGEgdmFsaWQgaW50ZXJydXB0IGlzIHBlbmRpbmcgKi8KCQlieXRlID0gaXJxX3N0YXRlKGFkYXB0ZXIpOwoJCWlmKCAoYnl0ZSAmIFZBTElEX0lOVFJfQllURSkgPT0gMCApIHsKCQkJLyoKCQkJICogTm8gbW9yZSBwZW5kaW5nIGNvbW1hbmRzCgkJCSAqLwoJCQlnb3RvIG91dF91bmxvY2s7CgkJfQoJCXNldF9pcnFfc3RhdGUoYWRhcHRlciwgYnl0ZSk7CgoJCXdoaWxlKChuc3RhdHVzID0gKHZvbGF0aWxlIHU4KWFkYXB0ZXItPm1ib3gtPm1faW4ubnVtc3RhdHVzKQoJCQkJPT0gMHhGRikKCQkJY3B1X3JlbGF4KCk7CgkJYWRhcHRlci0+bWJveC0+bV9pbi5udW1zdGF0dXMgPSAweEZGOwoKCQlzdGF0dXMgPSBhZGFwdGVyLT5tYm94LT5tX2luLnN0YXR1czsKCgkJLyoKCQkgKiBkZWNyZW1lbnQgdGhlIHBlbmRpbmcgcXVldWUgY291bnRlcgoJCSAqLwoJCWF0b21pY19zdWIobnN0YXR1cywgJmFkYXB0ZXItPnBlbmRfY21kcyk7CgoJCW1lbWNweShjb21wbGV0ZWQsICh2b2lkICopYWRhcHRlci0+bWJveC0+bV9pbi5jb21wbGV0ZWQsIAoJCQkJbnN0YXR1cyk7CgoJCS8qIEFja25vd2xlZGdlIGludGVycnVwdCAqLwoJCWlycV9hY2soYWRhcHRlcik7CgoJCW1lZ2FfY21kX2RvbmUoYWRhcHRlciwgY29tcGxldGVkLCBuc3RhdHVzLCBzdGF0dXMpOwoKCQltZWdhX3J1bmRvbmVxKGFkYXB0ZXIpOwoKCQloYW5kbGVkID0gMTsKCgkJLyogTG9vcCB0aHJvdWdoIGFueSBwZW5kaW5nIHJlcXVlc3RzICovCgkJaWYoYXRvbWljX3JlYWQoJmFkYXB0ZXItPnF1aWVzY2VudCkgPT0gMCkgewoJCQltZWdhX3J1bnBlbmRxKGFkYXB0ZXIpOwoJCX0KCgl9IHdoaWxlKDEpOwoKIG91dF91bmxvY2s6CgoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmYWRhcHRlci0+bG9jaywgZmxhZ3MpOwoKCXJldHVybiBJUlFfUkVUVkFMKGhhbmRsZWQpOwp9CgoKLyoqCiAqIG1lZ2FyYWlkX2lzcl9tZW1tYXBwZWQoKQogKiBAaXJxIC0gaXJxCiAqIEBkZXZwIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKiBAcmVncyAtIHVudXNlZAogKgogKiBJbnRlcnJ1cHQgc2VydmljZSByb3V0aW5lIGZvciBtZW1vcnktbWFwcGVkIGNvbnRyb2xsZXJzLgogKiBGaW5kIG91dCBpZiBvdXIgZGV2aWNlIGlzIGludGVycnVwdGluZy4gSWYgeWVzLCBhY2tub3dsZWRnZSB0aGUgaW50ZXJydXB0CiAqIGFuZCBzZXJ2aWNlIHRoZSBjb21wbGV0ZWQgY29tbWFuZHMuCiAqLwpzdGF0aWMgaXJxcmV0dXJuX3QKbWVnYXJhaWRfaXNyX21lbW1hcHBlZChpbnQgaXJxLCB2b2lkICpkZXZwLCBzdHJ1Y3QgcHRfcmVncyAqcmVncykKewoJYWRhcHRlcl90CSphZGFwdGVyID0gZGV2cDsKCXVuc2lnbmVkIGxvbmcJZmxhZ3M7Cgl1OAlzdGF0dXM7Cgl1MzIJZHdvcmQgPSAwOwoJdTgJbnN0YXR1czsKCXU4CWNvbXBsZXRlZFtNQVhfRklSTVdBUkVfU1RBVFVTXTsKCWludAloYW5kbGVkID0gMDsKCgoJLyoKCSAqIGxvb3AgdGlsbCBGL1cgaGFzIG1vcmUgY29tbWFuZHMgZm9yIHVzIHRvIGNvbXBsZXRlLgoJICovCglzcGluX2xvY2tfaXJxc2F2ZSgmYWRhcHRlci0+bG9jaywgZmxhZ3MpOwoKCWRvIHsKCQkvKiBDaGVjayBpZiBhIHZhbGlkIGludGVycnVwdCBpcyBwZW5kaW5nICovCgkJZHdvcmQgPSBSRE9VVERPT1IoYWRhcHRlcik7CgkJaWYoZHdvcmQgIT0gMHgxMDAwMTIzNCkgewoJCQkvKgoJCQkgKiBObyBtb3JlIHBlbmRpbmcgY29tbWFuZHMKCQkJICovCgkJCWdvdG8gb3V0X3VubG9jazsKCQl9CgkJV1JPVVRET09SKGFkYXB0ZXIsIDB4MTAwMDEyMzQpOwoKCQl3aGlsZSgobnN0YXR1cyA9ICh2b2xhdGlsZSB1OClhZGFwdGVyLT5tYm94LT5tX2luLm51bXN0YXR1cykKCQkJCT09IDB4RkYpIHsKCQkJY3B1X3JlbGF4KCk7CgkJfQoJCWFkYXB0ZXItPm1ib3gtPm1faW4ubnVtc3RhdHVzID0gMHhGRjsKCgkJc3RhdHVzID0gYWRhcHRlci0+bWJveC0+bV9pbi5zdGF0dXM7CgoJCS8qCgkJICogZGVjcmVtZW50IHRoZSBwZW5kaW5nIHF1ZXVlIGNvdW50ZXIKCQkgKi8KCQlhdG9taWNfc3ViKG5zdGF0dXMsICZhZGFwdGVyLT5wZW5kX2NtZHMpOwoKCQltZW1jcHkoY29tcGxldGVkLCAodm9pZCAqKWFkYXB0ZXItPm1ib3gtPm1faW4uY29tcGxldGVkLCAKCQkJCW5zdGF0dXMpOwoKCQkvKiBBY2tub3dsZWRnZSBpbnRlcnJ1cHQgKi8KCQlXUklORE9PUihhZGFwdGVyLCAweDIpOwoKCQloYW5kbGVkID0gMTsKCgkJd2hpbGUoIFJESU5ET09SKGFkYXB0ZXIpICYgMHgwMiApIGNwdV9yZWxheCgpOwoKCQltZWdhX2NtZF9kb25lKGFkYXB0ZXIsIGNvbXBsZXRlZCwgbnN0YXR1cywgc3RhdHVzKTsKCgkJbWVnYV9ydW5kb25lcShhZGFwdGVyKTsKCgkJLyogTG9vcCB0aHJvdWdoIGFueSBwZW5kaW5nIHJlcXVlc3RzICovCgkJaWYoYXRvbWljX3JlYWQoJmFkYXB0ZXItPnF1aWVzY2VudCkgPT0gMCkgewoJCQltZWdhX3J1bnBlbmRxKGFkYXB0ZXIpOwoJCX0KCgl9IHdoaWxlKDEpOwoKIG91dF91bmxvY2s6CgoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmYWRhcHRlci0+bG9jaywgZmxhZ3MpOwoKCXJldHVybiBJUlFfUkVUVkFMKGhhbmRsZWQpOwp9Ci8qKgogKiBtZWdhX2NtZF9kb25lKCkKICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqIEBjb21wbGV0ZWQgLSBhcnJheSBvZiBpZHMgb2YgY29tcGxldGVkIGNvbW1hbmRzCiAqIEBuc3RhdHVzIC0gbnVtYmVyIG9mIGNvbXBsZXRlZCBjb21tYW5kcwogKiBAc3RhdHVzIC0gc3RhdHVzIG9mIHRoZSBsYXN0IGNvbW1hbmQgY29tcGxldGVkCiAqCiAqIENvbXBsZXRlIHRoZSBjb21hbW5kcyBhbmQgY2FsbCB0aGUgc2NzaSBtaWQtbGF5ZXIgY2FsbGJhY2sgaG9va3MuCiAqLwpzdGF0aWMgdm9pZAptZWdhX2NtZF9kb25lKGFkYXB0ZXJfdCAqYWRhcHRlciwgdTggY29tcGxldGVkW10sIGludCBuc3RhdHVzLCBpbnQgc3RhdHVzKQp7CgltZWdhX2V4dF9wYXNzdGhydQkqZXB0aHJ1ID0gTlVMTDsKCXN0cnVjdCBzY2F0dGVybGlzdAkqc2dsOwoJU2NzaV9DbW5kCSpjbWQgPSBOVUxMOwoJbWVnYV9wYXNzdGhydQkqcHRocnUgPSBOVUxMOwoJbWJveF90CSptYm94ID0gTlVMTDsKCXU4CWM7CglzY2JfdAkqc2NiOwoJaW50CWlzbG9naWNhbDsKCWludAljbWRpZDsKCWludAlpOwoKCS8qCgkgKiBmb3IgYWxsIHRoZSBjb21tYW5kcyBjb21wbGV0ZWQsIGNhbGwgdGhlIG1pZC1sYXllciBjYWxsYmFjayByb3V0aW5lCgkgKiBhbmQgZnJlZSB0aGUgc2NiLgoJICovCglmb3IoIGkgPSAwOyBpIDwgbnN0YXR1czsgaSsrICkgewoKCQljbWRpZCA9IGNvbXBsZXRlZFtpXTsKCgkJaWYoIGNtZGlkID09IENNRElEX0lOVF9DTURTICkgeyAvKiBpbnRlcm5hbCBjb21tYW5kICovCgkJCXNjYiA9ICZhZGFwdGVyLT5pbnRfc2NiOwoJCQljbWQgPSBzY2ItPmNtZDsKCQkJbWJveCA9IChtYm94X3QgKilzY2ItPnJhd19tYm94OwoKCQkJLyoKCQkJICogSW50ZXJuYWwgY29tbWFuZCBpbnRlcmZhY2UgZG8gbm90IGZpcmUgdGhlIGV4dGVuZGVkCgkJCSAqIHBhc3N0aHJ1IG9yIDY0LWJpdCBwYXNzdGhydQoJCQkgKi8KCQkJcHRocnUgPSBzY2ItPnB0aHJ1OwoKCQl9CgkJZWxzZSB7CgkJCXNjYiA9ICZhZGFwdGVyLT5zY2JfbGlzdFtjbWRpZF07CgoJCQkvKgoJCQkgKiBNYWtlIHN1cmUgZi93IGhhcyBjb21wbGV0ZWQgYSB2YWxpZCBjb21tYW5kCgkJCSAqLwoJCQlpZiggIShzY2ItPnN0YXRlICYgU0NCX0lTU1VFRCkgfHwgc2NiLT5jbWQgPT0gTlVMTCApIHsKCQkJCXByaW50ayhLRVJOX0NSSVQKCQkJCQkibWVnYXJhaWQ6IGludmFsaWQgY29tbWFuZCAiKTsKCQkJCXByaW50aygiSWQgJWQsIHNjYi0+c3RhdGU6JXgsIHNjc2kgY21kOiVwXG4iLAoJCQkJCWNtZGlkLCBzY2ItPnN0YXRlLCBzY2ItPmNtZCk7CgoJCQkJY29udGludWU7CgkJCX0KCgkJCS8qCgkJCSAqIFdhcyBhIGFib3J0IGlzc3VlZCBmb3IgdGhpcyBjb21tYW5kCgkJCSAqLwoJCQlpZiggc2NiLT5zdGF0ZSAmIFNDQl9BQk9SVCApIHsKCgkJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCQkibWVnYXJhaWQ6IGFib3J0ZWQgY21kICVseFsleF0gY29tcGxldGUuXG4iLAoJCQkJCXNjYi0+Y21kLT5zZXJpYWxfbnVtYmVyLCBzY2ItPmlkeCk7CgoJCQkJc2NiLT5jbWQtPnJlc3VsdCA9IChESURfQUJPUlQgPDwgMTYpOwoKCQkJCWxpc3RfYWRkX3RhaWwoU0NTSV9MSVNUKHNjYi0+Y21kKSwKCQkJCQkJJmFkYXB0ZXItPmNvbXBsZXRlZF9saXN0KTsKCgkJCQltZWdhX2ZyZWVfc2NiKGFkYXB0ZXIsIHNjYik7CgoJCQkJY29udGludWU7CgkJCX0KCgkJCS8qCgkJCSAqIFdhcyBhIHJlc2V0IGlzc3VlZCBmb3IgdGhpcyBjb21tYW5kCgkJCSAqLwoJCQlpZiggc2NiLT5zdGF0ZSAmIFNDQl9SRVNFVCApIHsKCgkJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCQkibWVnYXJhaWQ6IHJlc2V0IGNtZCAlbHhbJXhdIGNvbXBsZXRlLlxuIiwKCQkJCQlzY2ItPmNtZC0+c2VyaWFsX251bWJlciwgc2NiLT5pZHgpOwoKCQkJCXNjYi0+Y21kLT5yZXN1bHQgPSAoRElEX1JFU0VUIDw8IDE2KTsKCgkJCQlsaXN0X2FkZF90YWlsKFNDU0lfTElTVChzY2ItPmNtZCksCgkJCQkJCSZhZGFwdGVyLT5jb21wbGV0ZWRfbGlzdCk7CgoJCQkJbWVnYV9mcmVlX3NjYiAoYWRhcHRlciwgc2NiKTsKCgkJCQljb250aW51ZTsKCQkJfQoKCQkJY21kID0gc2NiLT5jbWQ7CgkJCXB0aHJ1ID0gc2NiLT5wdGhydTsKCQkJZXB0aHJ1ID0gc2NiLT5lcHRocnU7CgkJCW1ib3ggPSAobWJveF90ICopc2NiLT5yYXdfbWJveDsKCiNpZiBNRUdBX0hBVkVfU1RBVFMKCQkJewoKCQkJaW50CWxvZ2RydiA9IG1ib3gtPm1fb3V0LmxvZ2RydjsKCgkJCWlzbG9naWNhbCA9IGFkYXB0ZXItPmxvZ2Rydl9jaGFuW2NtZC0+Y2hhbm5lbF07CgkJCS8qCgkJCSAqIE1haW50YWluIGFuIGVycm9yIGNvdW50ZXIgZm9yIHRoZSBsb2dpY2FsIGRyaXZlLgoJCQkgKiBTb21lIGFwcGxpY2F0aW9uIGxpa2UgU05NUCBhZ2VudCBuZWVkIHN1Y2gKCQkJICogc3RhdGlzdGljcwoJCQkgKi8KCQkJaWYoIHN0YXR1cyAmJiBpc2xvZ2ljYWwgJiYgKGNtZC0+Y21uZFswXSA9PSBSRUFEXzYgfHwKCQkJCQkJY21kLT5jbW5kWzBdID09IFJFQURfMTAgfHwKCQkJCQkJY21kLT5jbW5kWzBdID09IFJFQURfMTIpKSB7CgkJCQkvKgoJCQkJICogTG9naWNhbCBkcml2ZSBudW1iZXIgaW5jcmVhc2VzIGJ5IDB4ODAgd2hlbgoJCQkJICogYSBsb2dpY2FsIGRyaXZlIGlzIGRlbGV0ZWQKCQkJCSAqLwoJCQkJYWRhcHRlci0+cmRfZXJyb3JzW2xvZ2RydiUweDgwXSsrOwoJCQl9CgoJCQlpZiggc3RhdHVzICYmIGlzbG9naWNhbCAmJiAoY21kLT5jbW5kWzBdID09IFdSSVRFXzYgfHwKCQkJCQkJY21kLT5jbW5kWzBdID09IFdSSVRFXzEwIHx8CgkJCQkJCWNtZC0+Y21uZFswXSA9PSBXUklURV8xMikpIHsKCQkJCS8qCgkJCQkgKiBMb2dpY2FsIGRyaXZlIG51bWJlciBpbmNyZWFzZXMgYnkgMHg4MCB3aGVuCgkJCQkgKiBhIGxvZ2ljYWwgZHJpdmUgaXMgZGVsZXRlZAoJCQkJICovCgkJCQlhZGFwdGVyLT53cl9lcnJvcnNbbG9nZHJ2JTB4ODBdKys7CgkJCX0KCgkJCX0KI2VuZGlmCgkJfQoKCQkvKgoJCSAqIERvIG5vdCByZXR1cm4gdGhlIHByZXNlbmNlIG9mIGhhcmQgZGlzayBvbiB0aGUgY2hhbm5lbCBzbywKCQkgKiBpbnF1aXJ5IHNlbnQsIGFuZCByZXR1cm5lZCBkYXRhPT1oYXJkIGRpc2sgb3IgcmVtb3ZhYmxlCgkJICogaGFyZCBkaXNrIGFuZCBub3QgbG9naWNhbCwgcmVxdWVzdCBzaG91bGQgcmV0dXJuIGZhaWx1cmUhIC0KCQkgKiBQSgoJCSAqLwoJCWlzbG9naWNhbCA9IGFkYXB0ZXItPmxvZ2Rydl9jaGFuW2NtZC0+ZGV2aWNlLT5jaGFubmVsXTsKCQlpZiggY21kLT5jbW5kWzBdID09IElOUVVJUlkgJiYgIWlzbG9naWNhbCApIHsKCgkJCWlmKCBjbWQtPnVzZV9zZyApIHsKCQkJCXNnbCA9IChzdHJ1Y3Qgc2NhdHRlcmxpc3QgKikKCQkJCQljbWQtPnJlcXVlc3RfYnVmZmVyOwoKCQkJCWlmKCBzZ2wtPnBhZ2UgKSB7CgkJCQkJYyA9ICoodW5zaWduZWQgY2hhciAqKQoJCQkJCXBhZ2VfYWRkcmVzcygoJnNnbFswXSktPnBhZ2UpICsKCQkJCQkoJnNnbFswXSktPm9mZnNldDsgCgkJCQl9CgkJCQllbHNlIHsKCQkJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCQkJCSJtZWdhcmFpZDogaW52YWxpZCBzZy5cbiIpOwoJCQkJCWMgPSAwOwoJCQkJfQoJCQl9CgkJCWVsc2UgewoJCQkJYyA9ICoodTggKiljbWQtPnJlcXVlc3RfYnVmZmVyOwoJCQl9CgoJCQlpZihJU19SQUlEX0NIKGFkYXB0ZXIsIGNtZC0+ZGV2aWNlLT5jaGFubmVsKSAmJgoJCQkJCSgoYyAmIDB4MUYgKSA9PSBUWVBFX0RJU0spKSB7CgkJCQlzdGF0dXMgPSAweEYwOwoJCQl9CgkJfQoKCQkvKiBjbGVhciByZXN1bHQ7IG90aGVyd2lzZSwgc3VjY2VzcyByZXR1cm5zIGNvcnJ1cHQgdmFsdWUgKi8KCQljbWQtPnJlc3VsdCA9IDA7CgoJCS8qIENvbnZlcnQgTWVnYVJBSUQgc3RhdHVzIHRvIExpbnV4IGVycm9yIGNvZGUgKi8KCQlzd2l0Y2ggKHN0YXR1cykgewoJCWNhc2UgMHgwMDoJLyogU1VDQ0VTUyAsIGkuZS4gU0NTSV9TVEFUVVNfR09PRCAqLwoJCQljbWQtPnJlc3VsdCB8PSAoRElEX09LIDw8IDE2KTsKCQkJYnJlYWs7CgoJCWNhc2UgMHgwMjoJLyogRVJST1JfQUJPUlRFRCwgaS5lLgoJCQkJICAgU0NTSV9TVEFUVVNfQ0hFQ0tfQ09ORElUSU9OICovCgoJCQkvKiBzZXQgc2Vuc2VfYnVmZmVyIGFuZCByZXN1bHQgZmllbGRzICovCgkJCWlmKCBtYm94LT5tX291dC5jbWQgPT0gTUVHQV9NQk9YQ01EX1BBU1NUSFJVIHx8CgkJCQltYm94LT5tX291dC5jbWQgPT0gTUVHQV9NQk9YQ01EX1BBU1NUSFJVNjQgKSB7CgoJCQkJbWVtY3B5KGNtZC0+c2Vuc2VfYnVmZmVyLCBwdGhydS0+cmVxc2Vuc2VhcmVhLAoJCQkJCQkxNCk7CgoJCQkJY21kLT5yZXN1bHQgPSAoRFJJVkVSX1NFTlNFIDw8IDI0KSB8CgkJCQkJKERJRF9PSyA8PCAxNikgfAoJCQkJCShDSEVDS19DT05ESVRJT04gPDwgMSk7CgkJCX0KCQkJZWxzZSB7CgkJCQlpZiAobWJveC0+bV9vdXQuY21kID09IE1FR0FfTUJPWENNRF9FWFRQVEhSVSkgewoKCQkJCQltZW1jcHkoY21kLT5zZW5zZV9idWZmZXIsCgkJCQkJCWVwdGhydS0+cmVxc2Vuc2VhcmVhLCAxNCk7CgoJCQkJCWNtZC0+cmVzdWx0ID0gKERSSVZFUl9TRU5TRSA8PCAyNCkgfAoJCQkJCQkoRElEX09LIDw8IDE2KSB8CgkJCQkJCShDSEVDS19DT05ESVRJT04gPDwgMSk7CgkJCQl9IGVsc2UgewoJCQkJCWNtZC0+c2Vuc2VfYnVmZmVyWzBdID0gMHg3MDsKCQkJCQljbWQtPnNlbnNlX2J1ZmZlclsyXSA9IEFCT1JURURfQ09NTUFORDsKCQkJCQljbWQtPnJlc3VsdCB8PSAoQ0hFQ0tfQ09ORElUSU9OIDw8IDEpOwoJCQkJfQoJCQl9CgkJCWJyZWFrOwoKCQljYXNlIDB4MDg6CS8qIEVSUl9ERVNUX0RSSVZFX0ZBSUxFRCwgaS5lLgoJCQkJICAgU0NTSV9TVEFUVVNfQlVTWSAqLwoJCQljbWQtPnJlc3VsdCB8PSAoRElEX0JVU19CVVNZIDw8IDE2KSB8IHN0YXR1czsKCQkJYnJlYWs7CgoJCWRlZmF1bHQ6CiNpZiBNRUdBX0hBVkVfQ0xVU1RFUklORwoJCQkvKgoJCQkgKiBJZiBURVNUX1VOSVRfUkVBRFkgZmFpbHMsIHdlIGtub3cKCQkJICogTUVHQV9SRVNFUlZBVElPTl9TVEFUVVMgZmFpbGVkCgkJCSAqLwoJCQlpZiggY21kLT5jbW5kWzBdID09IFRFU1RfVU5JVF9SRUFEWSApIHsKCQkJCWNtZC0+cmVzdWx0IHw9IChESURfRVJST1IgPDwgMTYpIHwKCQkJCQkoUkVTRVJWQVRJT05fQ09ORkxJQ1QgPDwgMSk7CgkJCX0KCQkJZWxzZQoJCQkvKgoJCQkgKiBFcnJvciBjb2RlIHJldHVybmVkIGlzIDEgaWYgUmVzZXJ2ZSBvciBSZWxlYXNlCgkJCSAqIGZhaWxlZCBvciB0aGUgaW5wdXQgcGFyYW1ldGVyIGlzIGludmFsaWQKCQkJICovCgkJCWlmKCBzdGF0dXMgPT0gMSAmJgoJCQkJKGNtZC0+Y21uZFswXSA9PSBSRVNFUlZFIHx8CgkJCQkJIGNtZC0+Y21uZFswXSA9PSBSRUxFQVNFKSApIHsKCgkJCQljbWQtPnJlc3VsdCB8PSAoRElEX0VSUk9SIDw8IDE2KSB8CgkJCQkJKFJFU0VSVkFUSU9OX0NPTkZMSUNUIDw8IDEpOwoJCQl9CgkJCWVsc2UKI2VuZGlmCgkJCQljbWQtPnJlc3VsdCB8PSAoRElEX0JBRF9UQVJHRVQgPDwgMTYpfHN0YXR1czsKCQl9CgoJCS8qCgkJICogT25seSBmcmVlIFNDQnMgZm9yIHRoZSBjb21tYW5kcyBjb21pbmcgZG93biBmcm9tIHRoZQoJCSAqIG1pZC1sYXllciwgbm90IGZvciB3aGljaCB3ZXJlIGlzc3VlZCBpbnRlcm5hbGx5CgkJICoKCQkgKiBGb3IgaW50ZXJuYWwgY29tbWFuZCwgcmVzdG9yZSB0aGUgc3RhdHVzIHJldHVybmVkIGJ5IHRoZQoJCSAqIGZpcm13YXJlIHNvIHRoYXQgdXNlciBjYW4gaW50ZXJwcmV0IGl0LgoJCSAqLwoJCWlmKCBjbWRpZCA9PSBDTURJRF9JTlRfQ01EUyApIHsgLyogaW50ZXJuYWwgY29tbWFuZCAqLwoJCQljbWQtPnJlc3VsdCA9IHN0YXR1czsKCgkJCS8qCgkJCSAqIFJlbW92ZSB0aGUgaW50ZXJuYWwgY29tbWFuZCBmcm9tIHRoZSBwZW5kaW5nIGxpc3QKCQkJICovCgkJCWxpc3RfZGVsX2luaXQoJnNjYi0+bGlzdCk7CgkJCXNjYi0+c3RhdGUgPSBTQ0JfRlJFRTsKCQl9CgkJZWxzZSB7CgkJCW1lZ2FfZnJlZV9zY2IoYWRhcHRlciwgc2NiKTsKCQl9CgoJCS8qIEFkZCBTY3NpX0NvbW1hbmQgdG8gZW5kIG9mIGNvbXBsZXRlZCBxdWV1ZSAqLwoJCWxpc3RfYWRkX3RhaWwoU0NTSV9MSVNUKGNtZCksICZhZGFwdGVyLT5jb21wbGV0ZWRfbGlzdCk7Cgl9Cn0KCgovKgogKiBtZWdhX3J1bnBlbmRxKCkKICoKICogUnVuIHRocm91Z2ggdGhlIGxpc3Qgb2YgY29tcGxldGVkIHJlcXVlc3RzIGFuZCBmaW5pc2ggaXQKICovCnN0YXRpYyB2b2lkCm1lZ2FfcnVuZG9uZXEgKGFkYXB0ZXJfdCAqYWRhcHRlcikKewoJU2NzaV9DbW5kICpjbWQ7CglzdHJ1Y3QgbGlzdF9oZWFkICpwb3M7CgoJbGlzdF9mb3JfZWFjaChwb3MsICZhZGFwdGVyLT5jb21wbGV0ZWRfbGlzdCkgewoKCQlTY3NpX1BvaW50ZXIqIHNwb3MgPSAoU2NzaV9Qb2ludGVyICopcG9zOwoKCQljbWQgPSBsaXN0X2VudHJ5KHNwb3MsIFNjc2lfQ21uZCwgU0NwKTsKCQljbWQtPnNjc2lfZG9uZShjbWQpOwoJfQoKCUlOSVRfTElTVF9IRUFEKCZhZGFwdGVyLT5jb21wbGV0ZWRfbGlzdCk7Cn0KCgovKgogKiBGcmVlIGEgU0NCIHN0cnVjdHVyZQogKiBOb3RlOiBXZSBhc3N1bWUgdGhlIHNjc2kgY29tbWFuZHMgYXNzb2NpYXRlZCB3aXRoIHRoaXMgc2NiIGlzIG5vdCBmcmVlIHlldC4KICovCnN0YXRpYyB2b2lkCm1lZ2FfZnJlZV9zY2IoYWRhcHRlcl90ICphZGFwdGVyLCBzY2JfdCAqc2NiKQp7Cglzd2l0Y2goIHNjYi0+ZG1hX3R5cGUgKSB7CgoJY2FzZSBNRUdBX0RNQV9UWVBFX05PTkU6CgkJYnJlYWs7CgoJY2FzZSBNRUdBX0JVTEtfREFUQToKCQlwY2lfdW5tYXBfcGFnZShhZGFwdGVyLT5kZXYsIHNjYi0+ZG1hX2hfYnVsa2RhdGEsCgkJCXNjYi0+Y21kLT5yZXF1ZXN0X2J1ZmZsZW4sIHNjYi0+ZG1hX2RpcmVjdGlvbik7CgkJYnJlYWs7CgoJY2FzZSBNRUdBX1NHTElTVDoKCQlwY2lfdW5tYXBfc2coYWRhcHRlci0+ZGV2LCBzY2ItPmNtZC0+cmVxdWVzdF9idWZmZXIsCgkJCXNjYi0+Y21kLT51c2Vfc2csIHNjYi0+ZG1hX2RpcmVjdGlvbik7CgkJYnJlYWs7CgoJZGVmYXVsdDoKCQlicmVhazsKCX0KCgkvKgoJICogUmVtb3ZlIGZyb20gdGhlIHBlbmRpbmcgbGlzdAoJICovCglsaXN0X2RlbF9pbml0KCZzY2ItPmxpc3QpOwoKCS8qIExpbmsgdGhlIHNjYiBiYWNrIGludG8gZnJlZSBsaXN0ICovCglzY2ItPnN0YXRlID0gU0NCX0ZSRUU7CglzY2ItPmNtZCA9IE5VTEw7CgoJbGlzdF9hZGQoJnNjYi0+bGlzdCwgJmFkYXB0ZXItPmZyZWVfbGlzdCk7Cn0KCgpzdGF0aWMgaW50Cl9fbWVnYV9idXN5d2FpdF9tYm94IChhZGFwdGVyX3QgKmFkYXB0ZXIpCnsKCXZvbGF0aWxlIG1ib3hfdCAqbWJveCA9IGFkYXB0ZXItPm1ib3g7Cglsb25nIGNvdW50ZXI7CgoJZm9yIChjb3VudGVyID0gMDsgY291bnRlciA8IDEwMDAwOyBjb3VudGVyKyspIHsKCQlpZiAoIW1ib3gtPm1faW4uYnVzeSkKCQkJcmV0dXJuIDA7CgkJdWRlbGF5KDEwMCk7IHlpZWxkKCk7Cgl9CglyZXR1cm4gLTE7CQkvKiBnaXZlIHVwIGFmdGVyIDEgc2Vjb25kICovCn0KCi8qCiAqIENvcGllcyBkYXRhIHRvIFNHTElTVAogKiBOb3RlOiBGb3IgNjQgYml0IGNhcmRzLCB3ZSBuZWVkIGEgbWluaW11bSBvZiBvbmUgU0cgZWxlbWVudCBmb3IgcmVhZC93cml0ZQogKi8Kc3RhdGljIGludAptZWdhX2J1aWxkX3NnbGlzdChhZGFwdGVyX3QgKmFkYXB0ZXIsIHNjYl90ICpzY2IsIHUzMiAqYnVmLCB1MzIgKmxlbikKewoJc3RydWN0IHNjYXR0ZXJsaXN0CSpzZ2w7CglzdHJ1Y3QgcGFnZQkqcGFnZTsKCXVuc2lnbmVkIGxvbmcJb2Zmc2V0OwoJU2NzaV9DbW5kCSpjbWQ7CglpbnQJc2djbnQ7CglpbnQJaWR4OwoKCWNtZCA9IHNjYi0+Y21kOwoKCS8qIFNjYXR0ZXItZ2F0aGVyIG5vdCB1c2VkICovCglpZiggIWNtZC0+dXNlX3NnICkgewoKCQlwYWdlID0gdmlydF90b19wYWdlKGNtZC0+cmVxdWVzdF9idWZmZXIpOwoJCW9mZnNldCA9IG9mZnNldF9pbl9wYWdlKGNtZC0+cmVxdWVzdF9idWZmZXIpOwoKCQlzY2ItPmRtYV9oX2J1bGtkYXRhID0gcGNpX21hcF9wYWdlKGFkYXB0ZXItPmRldiwKCQkJCQkJICBwYWdlLCBvZmZzZXQsCgkJCQkJCSAgY21kLT5yZXF1ZXN0X2J1ZmZsZW4sCgkJCQkJCSAgc2NiLT5kbWFfZGlyZWN0aW9uKTsKCQlzY2ItPmRtYV90eXBlID0gTUVHQV9CVUxLX0RBVEE7CgoJCS8qCgkJICogV2UgbmVlZCB0byBoYW5kbGUgc3BlY2lhbCA2NC1iaXQgY29tbWFuZHMgdGhhdCBuZWVkIGEKCQkgKiBtaW5pbXVtIG9mIDEgU0cKCQkgKi8KCQlpZiggYWRhcHRlci0+aGFzXzY0Yml0X2FkZHIgKSB7CgkJCXNjYi0+c2dsNjRbMF0uYWRkcmVzcyA9IHNjYi0+ZG1hX2hfYnVsa2RhdGE7CgkJCXNjYi0+c2dsNjRbMF0ubGVuZ3RoID0gY21kLT5yZXF1ZXN0X2J1ZmZsZW47CgkJCSpidWYgPSAodTMyKXNjYi0+c2dsX2RtYV9hZGRyOwoJCQkqbGVuID0gKHUzMiljbWQtPnJlcXVlc3RfYnVmZmxlbjsKCQkJcmV0dXJuIDE7CgkJfQoJCWVsc2UgewoJCQkqYnVmID0gKHUzMilzY2ItPmRtYV9oX2J1bGtkYXRhOwoJCQkqbGVuID0gKHUzMiljbWQtPnJlcXVlc3RfYnVmZmxlbjsKCQl9CgkJcmV0dXJuIDA7Cgl9CgoJc2dsID0gKHN0cnVjdCBzY2F0dGVybGlzdCAqKWNtZC0+cmVxdWVzdF9idWZmZXI7CgoJLyoKCSAqIENvcHkgU2NhdHRlci1HYXRoZXIgbGlzdCBpbmZvIGludG8gY29udHJvbGxlciBzdHJ1Y3R1cmUuCgkgKgoJICogVGhlIG51bWJlciBvZiBzZyBlbGVtZW50cyByZXR1cm5lZCBtdXN0IG5vdCBleGNlZWQgb3VyIGxpbWl0CgkgKi8KCXNnY250ID0gcGNpX21hcF9zZyhhZGFwdGVyLT5kZXYsIHNnbCwgY21kLT51c2Vfc2csCgkJCXNjYi0+ZG1hX2RpcmVjdGlvbik7CgoJc2NiLT5kbWFfdHlwZSA9IE1FR0FfU0dMSVNUOwoKCWlmKCBzZ2NudCA+IGFkYXB0ZXItPnNnbGVuICkgQlVHKCk7CgoJZm9yKCBpZHggPSAwOyBpZHggPCBzZ2NudDsgaWR4KyssIHNnbCsrICkgewoKCQlpZiggYWRhcHRlci0+aGFzXzY0Yml0X2FkZHIgKSB7CgkJCXNjYi0+c2dsNjRbaWR4XS5hZGRyZXNzID0gc2dfZG1hX2FkZHJlc3Moc2dsKTsKCQkJc2NiLT5zZ2w2NFtpZHhdLmxlbmd0aCA9IHNnX2RtYV9sZW4oc2dsKTsKCQl9CgkJZWxzZSB7CgkJCXNjYi0+c2dsW2lkeF0uYWRkcmVzcyA9IHNnX2RtYV9hZGRyZXNzKHNnbCk7CgkJCXNjYi0+c2dsW2lkeF0ubGVuZ3RoID0gc2dfZG1hX2xlbihzZ2wpOwoJCX0KCX0KCgkvKiBSZXNldCBwb2ludGVyIGFuZCBsZW5ndGggZmllbGRzICovCgkqYnVmID0gc2NiLT5zZ2xfZG1hX2FkZHI7CgoJLyoKCSAqIEZvciBwYXNzdGhydSBjb21tYW5kLCBkYXRheGZlcmxlbiBtdXN0IGJlIHNldCwgZXZlbiBmb3IgY29tbWFuZHMKCSAqIHdpdGggYSBzZyBsaXN0CgkgKi8KCSpsZW4gPSAodTMyKWNtZC0+cmVxdWVzdF9idWZmbGVuOwoKCS8qIFJldHVybiBjb3VudCBvZiBTRyByZXF1ZXN0cyAqLwoJcmV0dXJuIHNnY250Owp9CgoKLyoKICogbWVnYV84X3RvXzQwbGQoKQogKgogKiB0YWtlcyBhbGwgaW5mbyBpbiBBZGFwdGVySW5xdWlyeSBzdHJ1Y3R1cmUgYW5kIHB1dHMgaXQgaW50byBQcm9kdWN0SW5mbyBhbmQKICogRW5xdWlyeTMgc3RydWN0dXJlcyBmb3IgbGF0ZXIgdXNlCiAqLwpzdGF0aWMgdm9pZAptZWdhXzhfdG9fNDBsZChtcmFpZF9pbnF1aXJ5ICppbnF1aXJ5LCBtZWdhX2lucXVpcnkzICplbnF1aXJ5MywKCQltZWdhX3Byb2R1Y3RfaW5mbyAqcHJvZHVjdF9pbmZvKQp7CglpbnQgaTsKCglwcm9kdWN0X2luZm8tPm1heF9jb21tYW5kcyA9IGlucXVpcnktPmFkYXB0ZXJfaW5mby5tYXhfY29tbWFuZHM7CgllbnF1aXJ5My0+cmVidWlsZF9yYXRlID0gaW5xdWlyeS0+YWRhcHRlcl9pbmZvLnJlYnVpbGRfcmF0ZTsKCXByb2R1Y3RfaW5mby0+bmNoYW5uZWxzID0gaW5xdWlyeS0+YWRhcHRlcl9pbmZvLm5jaGFubmVsczsKCglmb3IgKGkgPSAwOyBpIDwgNDsgaSsrKSB7CgkJcHJvZHVjdF9pbmZvLT5md192ZXJzaW9uW2ldID0KCQkJaW5xdWlyeS0+YWRhcHRlcl9pbmZvLmZ3X3ZlcnNpb25baV07CgoJCXByb2R1Y3RfaW5mby0+Ymlvc192ZXJzaW9uW2ldID0KCQkJaW5xdWlyeS0+YWRhcHRlcl9pbmZvLmJpb3NfdmVyc2lvbltpXTsKCX0KCWVucXVpcnkzLT5jYWNoZV9mbHVzaF9pbnRlcnZhbCA9CgkJaW5xdWlyeS0+YWRhcHRlcl9pbmZvLmNhY2hlX2ZsdXNoX2ludGVydmFsOwoKCXByb2R1Y3RfaW5mby0+ZHJhbV9zaXplID0gaW5xdWlyeS0+YWRhcHRlcl9pbmZvLmRyYW1fc2l6ZTsKCgllbnF1aXJ5My0+bnVtX2xkcnYgPSBpbnF1aXJ5LT5sb2dkcnZfaW5mby5udW1fbGRydjsKCglmb3IgKGkgPSAwOyBpIDwgTUFYX0xPR0lDQUxfRFJJVkVTXzhMRDsgaSsrKSB7CgkJZW5xdWlyeTMtPmxkcnZfc2l6ZVtpXSA9IGlucXVpcnktPmxvZ2Rydl9pbmZvLmxkcnZfc2l6ZVtpXTsKCQllbnF1aXJ5My0+bGRydl9wcm9wW2ldID0gaW5xdWlyeS0+bG9nZHJ2X2luZm8ubGRydl9wcm9wW2ldOwoJCWVucXVpcnkzLT5sZHJ2X3N0YXRlW2ldID0gaW5xdWlyeS0+bG9nZHJ2X2luZm8ubGRydl9zdGF0ZVtpXTsKCX0KCglmb3IgKGkgPSAwOyBpIDwgKE1BWF9QSFlTSUNBTF9EUklWRVMpOyBpKyspCgkJZW5xdWlyeTMtPnBkcnZfc3RhdGVbaV0gPSBpbnF1aXJ5LT5wZHJ2X2luZm8ucGRydl9zdGF0ZVtpXTsKfQoKc3RhdGljIGlubGluZSB2b2lkCm1lZ2FfZnJlZV9zZ2woYWRhcHRlcl90ICphZGFwdGVyKQp7CglzY2JfdAkqc2NiOwoJaW50CWk7CgoJZm9yKGkgPSAwOyBpIDwgYWRhcHRlci0+bWF4X2NtZHM7IGkrKykgewoKCQlzY2IgPSAmYWRhcHRlci0+c2NiX2xpc3RbaV07CgoJCWlmKCBzY2ItPnNnbDY0ICkgewoJCQlwY2lfZnJlZV9jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwKCQkJCXNpemVvZihtZWdhX3NnbDY0KSAqIGFkYXB0ZXItPnNnbGVuLAoJCQkJc2NiLT5zZ2w2NCwKCQkJCXNjYi0+c2dsX2RtYV9hZGRyKTsKCgkJCXNjYi0+c2dsNjQgPSBOVUxMOwoJCX0KCgkJaWYoIHNjYi0+cHRocnUgKSB7CgkJCXBjaV9mcmVlX2NvbnNpc3RlbnQoYWRhcHRlci0+ZGV2LCBzaXplb2YobWVnYV9wYXNzdGhydSksCgkJCQlzY2ItPnB0aHJ1LCBzY2ItPnB0aHJ1X2RtYV9hZGRyKTsKCgkJCXNjYi0+cHRocnUgPSBOVUxMOwoJCX0KCgkJaWYoIHNjYi0+ZXB0aHJ1ICkgewoJCQlwY2lfZnJlZV9jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwKCQkJCXNpemVvZihtZWdhX2V4dF9wYXNzdGhydSksCgkJCQlzY2ItPmVwdGhydSwgc2NiLT5lcHRocnVfZG1hX2FkZHIpOwoKCQkJc2NiLT5lcHRocnUgPSBOVUxMOwoJCX0KCgl9Cn0KCgovKgogKiBHZXQgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGNhcmQvZHJpdmVyCiAqLwpjb25zdCBjaGFyICoKbWVnYXJhaWRfaW5mbyhzdHJ1Y3QgU2NzaV9Ib3N0ICpob3N0KQp7CglzdGF0aWMgY2hhciBidWZmZXJbNTEyXTsKCWFkYXB0ZXJfdCAqYWRhcHRlcjsKCglhZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWhvc3QtPmhvc3RkYXRhOwoKCXNwcmludGYgKGJ1ZmZlciwKCQkgIkxTSSBMb2dpYyBNZWdhUkFJRCAlcyAlZCBjb21tYW5kcyAlZCB0YXJncyAlZCBjaGFucyAlZCBsdW5zIiwKCQkgYWRhcHRlci0+ZndfdmVyc2lvbiwgYWRhcHRlci0+cHJvZHVjdF9pbmZvLm1heF9jb21tYW5kcywKCQkgYWRhcHRlci0+aG9zdC0+bWF4X2lkLCBhZGFwdGVyLT5ob3N0LT5tYXhfY2hhbm5lbCwKCQkgYWRhcHRlci0+aG9zdC0+bWF4X2x1bik7CglyZXR1cm4gYnVmZmVyOwp9CgovKgogKiBBYm9ydCBhIHByZXZpb3VzIFNDU0kgcmVxdWVzdC4gT25seSBjb21tYW5kcyBvbiB0aGUgcGVuZGluZyBsaXN0IGNhbiBiZQogKiBhYm9ydGVkLiBBbGwgdGhlIGNvbW1hbmRzIGlzc3VlZCB0byB0aGUgRi9XIG11c3QgY29tcGxldGUuCiAqLwpzdGF0aWMgaW50Cm1lZ2FyYWlkX2Fib3J0KFNjc2lfQ21uZCAqY21kKQp7CglhZGFwdGVyX3QJKmFkYXB0ZXI7CglpbnQJCXJ2YWw7CgoJYWRhcHRlciA9IChhZGFwdGVyX3QgKiljbWQtPmRldmljZS0+aG9zdC0+aG9zdGRhdGE7CgoJcnZhbCA9ICBtZWdhcmFpZF9hYm9ydF9hbmRfcmVzZXQoYWRhcHRlciwgY21kLCBTQ0JfQUJPUlQpOwoKCS8qCgkgKiBUaGlzIGlzIHJlcXVpcmVkIGhlcmUgdG8gY29tcGxldGUgYW55IGNvbXBsZXRlZCByZXF1ZXN0cwoJICogdG8gYmUgY29tbXVuaWNhdGVkIG92ZXIgdG8gdGhlIG1pZCBsYXllci4KCSAqLwoJbWVnYV9ydW5kb25lcShhZGFwdGVyKTsKCglyZXR1cm4gcnZhbDsKfQoKCnN0YXRpYyBpbnQKX19tZWdhcmFpZF9yZXNldChTY3NpX0NtbmQgKmNtZCkKewoJYWRhcHRlcl90CSphZGFwdGVyOwoJbWVnYWNtZF90CW1jOwoJaW50CQlydmFsOwoKCWFkYXB0ZXIgPSAoYWRhcHRlcl90ICopY21kLT5kZXZpY2UtPmhvc3QtPmhvc3RkYXRhOwoKI2lmIE1FR0FfSEFWRV9DTFVTVEVSSU5HCgltYy5jbWQgPSBNRUdBX0NMVVNURVJfQ01EOwoJbWMub3Bjb2RlID0gTUVHQV9SRVNFVF9SRVNFUlZBVElPTlM7CgoJc3Bpbl91bmxvY2tfaXJxKCZhZGFwdGVyLT5sb2NrKTsKCWlmKCBtZWdhX2ludGVybmFsX2NvbW1hbmQoYWRhcHRlciwgTE9DS19JTlQsICZtYywgTlVMTCkgIT0gMCApIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCQkibWVnYXJhaWQ6IHJlc2VydmF0aW9uIHJlc2V0IGZhaWxlZC5cbiIpOwoJfQoJZWxzZSB7CgkJcHJpbnRrKEtFUk5fSU5GTyAibWVnYXJhaWQ6IHJlc2VydmF0aW9uIHJlc2V0LlxuIik7Cgl9CglzcGluX2xvY2tfaXJxKCZhZGFwdGVyLT5sb2NrKTsKI2VuZGlmCgoJcnZhbCA9ICBtZWdhcmFpZF9hYm9ydF9hbmRfcmVzZXQoYWRhcHRlciwgY21kLCBTQ0JfUkVTRVQpOwoKCS8qCgkgKiBUaGlzIGlzIHJlcXVpcmVkIGhlcmUgdG8gY29tcGxldGUgYW55IGNvbXBsZXRlZCByZXF1ZXN0cwoJICogdG8gYmUgY29tbXVuaWNhdGVkIG92ZXIgdG8gdGhlIG1pZCBsYXllci4KCSAqLwoJbWVnYV9ydW5kb25lcShhZGFwdGVyKTsKCglyZXR1cm4gcnZhbDsKfQoKc3RhdGljIGludAptZWdhcmFpZF9yZXNldChTY3NpX0NtbmQgKmNtZCkKewoJYWRhcHRlcl90ICphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWNtZC0+ZGV2aWNlLT5ob3N0LT5ob3N0ZGF0YTsKCWludCByYzsKCglzcGluX2xvY2tfaXJxKCZhZGFwdGVyLT5sb2NrKTsKCXJjID0gX19tZWdhcmFpZF9yZXNldChjbWQpOwoJc3Bpbl91bmxvY2tfaXJxKCZhZGFwdGVyLT5sb2NrKTsKCglyZXR1cm4gcmM7Cn0KCgovKioKICogbWVnYXJhaWRfYWJvcnRfYW5kX3Jlc2V0KCkKICogQGFkYXB0ZXIgLSBtZWdhcmFpZCBzb2Z0IHN0YXRlCiAqIEBjbWQgLSBzY3NpIGNvbW1hbmQgdG8gYmUgYWJvcnRlZCBvciByZXNldAogKiBAYW9yIC0gYWJvcnQgb3IgcmVzZXQgZmxhZwogKgogKiBUcnkgdG8gbG9jYXRlIHRoZSBzY3NpIGNvbW1hbmQgaW4gdGhlIHBlbmRpbmcgcXVldWUuIElmIGZvdW5kIGFuZCBpcyBub3QKICogaXNzdWVkIHRvIHRoZSBjb250cm9sbGVyLCBhYm9ydC9yZXNldCBpdC4gT3RoZXJ3aXNlIHJldHVybiBmYWlsdXJlCiAqLwpzdGF0aWMgaW50Cm1lZ2FyYWlkX2Fib3J0X2FuZF9yZXNldChhZGFwdGVyX3QgKmFkYXB0ZXIsIFNjc2lfQ21uZCAqY21kLCBpbnQgYW9yKQp7CglzdHJ1Y3QgbGlzdF9oZWFkCSpwb3MsICpuZXh0OwoJc2NiX3QJCQkqc2NiOwoKCXByaW50ayhLRVJOX1dBUk5JTkcgIm1lZ2FyYWlkOiAlcy0lbHggY21kPSV4IDxjPSVkIHQ9JWQgbD0lZD5cbiIsCgkgICAgIChhb3IgPT0gU0NCX0FCT1JUKT8gIkFCT1JUSU5HIjoiUkVTRVQiLCBjbWQtPnNlcmlhbF9udW1iZXIsCgkgICAgIGNtZC0+Y21uZFswXSwgY21kLT5kZXZpY2UtPmNoYW5uZWwsIAoJICAgICBjbWQtPmRldmljZS0+aWQsIGNtZC0+ZGV2aWNlLT5sdW4pOwoKCWlmKGxpc3RfZW1wdHkoJmFkYXB0ZXItPnBlbmRpbmdfbGlzdCkpCgkJcmV0dXJuIEZBTFNFOwoKCWxpc3RfZm9yX2VhY2hfc2FmZShwb3MsIG5leHQsICZhZGFwdGVyLT5wZW5kaW5nX2xpc3QpIHsKCgkJc2NiID0gbGlzdF9lbnRyeShwb3MsIHNjYl90LCBsaXN0KTsKCgkJaWYgKHNjYi0+Y21kID09IGNtZCkgeyAvKiBGb3VuZCBjb21tYW5kICovCgoJCQlzY2ItPnN0YXRlIHw9IGFvcjsKCgkJCS8qCgkJCSAqIENoZWNrIGlmIHRoaXMgY29tbWFuZCBoYXMgZmlybWFyZSBvd2VuZXJzaGlwLiBJZgoJCQkgKiB5ZXMsIHdlIGNhbm5vdCByZXNldCB0aGlzIGNvbW1hbmQuIFdoZW5ldmVyLCBmL3cKCQkJICogY29tcGxldGVzIHRoaXMgY29tbWFuZCwgd2Ugd2lsbCByZXR1cm4gYXBwcm9wcmlhdGUKCQkJICogc3RhdHVzIGZyb20gSVNSLgoJCQkgKi8KCQkJaWYoIHNjYi0+c3RhdGUgJiBTQ0JfSVNTVUVEICkgewoKCQkJCXByaW50ayhLRVJOX1dBUk5JTkcKCQkJCQkibWVnYXJhaWQ6ICVzLSVseFsleF0sIGZ3IG93bmVyLlxuIiwKCQkJCQkoYW9yPT1TQ0JfQUJPUlQpID8gIkFCT1JUSU5HIjoiUkVTRVQiLAoJCQkJCWNtZC0+c2VyaWFsX251bWJlciwgc2NiLT5pZHgpOwoKCQkJCXJldHVybiBGQUxTRTsKCQkJfQoJCQllbHNlIHsKCgkJCQkvKgoJCQkJICogTm90IHlldCBpc3N1ZWQhIFJlbW92ZSBmcm9tIHRoZSBwZW5kaW5nCgkJCQkgKiBsaXN0CgkJCQkgKi8KCQkJCXByaW50ayhLRVJOX1dBUk5JTkcKCQkJCQkibWVnYXJhaWQ6ICVzLSVseFsleF0sIGRyaXZlciBvd25lci5cbiIsCgkJCQkJKGFvcj09U0NCX0FCT1JUKSA/ICJBQk9SVElORyI6IlJFU0VUIiwKCQkJCQljbWQtPnNlcmlhbF9udW1iZXIsIHNjYi0+aWR4KTsKCgkJCQltZWdhX2ZyZWVfc2NiKGFkYXB0ZXIsIHNjYik7CgoJCQkJaWYoIGFvciA9PSBTQ0JfQUJPUlQgKSB7CgkJCQkJY21kLT5yZXN1bHQgPSAoRElEX0FCT1JUIDw8IDE2KTsKCQkJCX0KCQkJCWVsc2UgewoJCQkJCWNtZC0+cmVzdWx0ID0gKERJRF9SRVNFVCA8PCAxNik7CgkJCQl9CgoJCQkJbGlzdF9hZGRfdGFpbChTQ1NJX0xJU1QoY21kKSwKCQkJCQkJJmFkYXB0ZXItPmNvbXBsZXRlZF9saXN0KTsKCgkJCQlyZXR1cm4gVFJVRTsKCQkJfQoJCX0KCX0KCglyZXR1cm4gRkFMU0U7Cn0KCnN0YXRpYyBpbmxpbmUgaW50Cm1ha2VfbG9jYWxfcGRldihhZGFwdGVyX3QgKmFkYXB0ZXIsIHN0cnVjdCBwY2lfZGV2ICoqcGRldikKewoJKnBkZXYgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgcGNpX2RldiksIEdGUF9LRVJORUwpOwoKCWlmKCAqcGRldiA9PSBOVUxMICkgcmV0dXJuIC0xOwoKCW1lbWNweSgqcGRldiwgYWRhcHRlci0+ZGV2LCBzaXplb2Yoc3RydWN0IHBjaV9kZXYpKTsKCglpZiggcGNpX3NldF9kbWFfbWFzaygqcGRldiwgMHhmZmZmZmZmZikgIT0gMCApIHsKCQlrZnJlZSgqcGRldik7CgkJcmV0dXJuIC0xOwoJfQoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW5saW5lIHZvaWQKZnJlZV9sb2NhbF9wZGV2KHN0cnVjdCBwY2lfZGV2ICpwZGV2KQp7CglrZnJlZShwZGV2KTsKfQoKLyoqCiAqIG1lZ2FfYWxsb2NhdGVfaW5xdWlyeSgpCiAqIEBkbWFfaGFuZGxlIC0gaGFuZGxlIHJldHVybmVkIGZvciBkbWEgYWRkcmVzcwogKiBAcGRldiAtIGhhbmRsZSB0byBwY2kgZGV2aWNlCiAqCiAqIGFsbG9jYXRlcyBtZW1vcnkgZm9yIGlucXVpcnkgc3RydWN0dXJlCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgKgptZWdhX2FsbG9jYXRlX2lucXVpcnkoZG1hX2FkZHJfdCAqZG1hX2hhbmRsZSwgc3RydWN0IHBjaV9kZXYgKnBkZXYpCnsKCXJldHVybiBwY2lfYWxsb2NfY29uc2lzdGVudChwZGV2LCBzaXplb2YobWVnYV9pbnF1aXJ5MyksIGRtYV9oYW5kbGUpOwp9CgoKc3RhdGljIGlubGluZSB2b2lkCm1lZ2FfZnJlZV9pbnF1aXJ5KHZvaWQgKmlucXVpcnksIGRtYV9hZGRyX3QgZG1hX2hhbmRsZSwgc3RydWN0IHBjaV9kZXYgKnBkZXYpCnsKCXBjaV9mcmVlX2NvbnNpc3RlbnQocGRldiwgc2l6ZW9mKG1lZ2FfaW5xdWlyeTMpLCBpbnF1aXJ5LCBkbWFfaGFuZGxlKTsKfQoKCiNpZmRlZiBDT05GSUdfUFJPQ19GUwovKiBGb2xsb3dpbmcgY29kZSBoYW5kbGVzIC9wcm9jIGZzICAqLwoKI2RlZmluZSBDUkVBVEVfUkVBRF9QUk9DKHN0cmluZywgZnVuYykJY3JlYXRlX3Byb2NfcmVhZF9lbnRyeShzdHJpbmcsCVwKCQkJCQlTX0lSVVNSIHwgU19JRlJFRywJCVwKCQkJCQljb250cm9sbGVyX3Byb2NfZGlyX2VudHJ5LAlcCgkJCQkJZnVuYywgYWRhcHRlcikKCi8qKgogKiBtZWdhX2NyZWF0ZV9wcm9jX2VudHJ5KCkKICogQGluZGV4IC0gaW5kZXggaW4gc29mdCBzdGF0ZSBhcnJheQogKiBAcGFyZW50IC0gcGFyZW50IG5vZGUgZm9yIHRoaXMgL3Byb2MgZW50cnkKICoKICogQ3JlYXRlcyAvcHJvYyBlbnRyaWVzIGZvciBvdXIgY29udHJvbGxlcnMuCiAqLwpzdGF0aWMgdm9pZAptZWdhX2NyZWF0ZV9wcm9jX2VudHJ5KGludCBpbmRleCwgc3RydWN0IHByb2NfZGlyX2VudHJ5ICpwYXJlbnQpCnsKCXN0cnVjdCBwcm9jX2Rpcl9lbnRyeQkqY29udHJvbGxlcl9wcm9jX2Rpcl9lbnRyeSA9IE5VTEw7Cgl1OAkJc3RyaW5nWzY0XSA9IHsgMCB9OwoJYWRhcHRlcl90CSphZGFwdGVyID0gaGJhX3NvZnRfc3RhdGVbaW5kZXhdOwoKCXNwcmludGYoc3RyaW5nLCAiaGJhJWQiLCBhZGFwdGVyLT5ob3N0LT5ob3N0X25vKTsKCgljb250cm9sbGVyX3Byb2NfZGlyX2VudHJ5ID0KCQlhZGFwdGVyLT5jb250cm9sbGVyX3Byb2NfZGlyX2VudHJ5ID0gcHJvY19ta2RpcihzdHJpbmcsIHBhcmVudCk7CgoJaWYoIWNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJcbm1lZ2FyYWlkOiBwcm9jX21rZGlyIGZhaWxlZFxuIik7CgkJcmV0dXJuOwoJfQoJYWRhcHRlci0+cHJvY19yZWFkID0gQ1JFQVRFX1JFQURfUFJPQygiY29uZmlnIiwgcHJvY19yZWFkX2NvbmZpZyk7CglhZGFwdGVyLT5wcm9jX3N0YXQgPSBDUkVBVEVfUkVBRF9QUk9DKCJzdGF0IiwgcHJvY19yZWFkX3N0YXQpOwoJYWRhcHRlci0+cHJvY19tYm94ID0gQ1JFQVRFX1JFQURfUFJPQygibWFpbGJveCIsIHByb2NfcmVhZF9tYm94KTsKI2lmIE1FR0FfSEFWRV9FTkhfUFJPQwoJYWRhcHRlci0+cHJvY19yciA9IENSRUFURV9SRUFEX1BST0MoInJlYnVpbGQtcmF0ZSIsIHByb2NfcmVidWlsZF9yYXRlKTsKCWFkYXB0ZXItPnByb2NfYmF0dGVyeSA9IENSRUFURV9SRUFEX1BST0MoImJhdHRlcnktc3RhdHVzIiwKCQkJcHJvY19iYXR0ZXJ5KTsKCgkvKgoJICogRGlzcGxheSBlYWNoIHBoeXNpY2FsIGRyaXZlIG9uIGl0cyBjaGFubmVsCgkgKi8KCWFkYXB0ZXItPnByb2NfcGRydnN0YXRbMF0gPSBDUkVBVEVfUkVBRF9QUk9DKCJkaXNrZHJpdmVzLWNoMCIsCgkJCQkJcHJvY19wZHJ2X2NoMCk7CglhZGFwdGVyLT5wcm9jX3BkcnZzdGF0WzFdID0gQ1JFQVRFX1JFQURfUFJPQygiZGlza2RyaXZlcy1jaDEiLAoJCQkJCXByb2NfcGRydl9jaDEpOwoJYWRhcHRlci0+cHJvY19wZHJ2c3RhdFsyXSA9IENSRUFURV9SRUFEX1BST0MoImRpc2tkcml2ZXMtY2gyIiwKCQkJCQlwcm9jX3BkcnZfY2gyKTsKCWFkYXB0ZXItPnByb2NfcGRydnN0YXRbM10gPSBDUkVBVEVfUkVBRF9QUk9DKCJkaXNrZHJpdmVzLWNoMyIsCgkJCQkJcHJvY19wZHJ2X2NoMyk7CgoJLyoKCSAqIERpc3BsYXkgYSBzZXQgb2YgdXAgdG8gMTAgbG9naWNhbCBkcml2ZSB0aHJvdWdoIGVhY2ggb2YgZm9sbG93aW5nCgkgKiAvcHJvYyBlbnRyaWVzCgkgKi8KCWFkYXB0ZXItPnByb2NfcmRydnN0YXRbMF0gPSBDUkVBVEVfUkVBRF9QUk9DKCJyYWlkZHJpdmVzLTAtOSIsCgkJCQkJcHJvY19yZHJ2XzEwKTsKCWFkYXB0ZXItPnByb2NfcmRydnN0YXRbMV0gPSBDUkVBVEVfUkVBRF9QUk9DKCJyYWlkZHJpdmVzLTEwLTE5IiwKCQkJCQlwcm9jX3JkcnZfMjApOwoJYWRhcHRlci0+cHJvY19yZHJ2c3RhdFsyXSA9IENSRUFURV9SRUFEX1BST0MoInJhaWRkcml2ZXMtMjAtMjkiLAoJCQkJCXByb2NfcmRydl8zMCk7CglhZGFwdGVyLT5wcm9jX3JkcnZzdGF0WzNdID0gQ1JFQVRFX1JFQURfUFJPQygicmFpZGRyaXZlcy0zMC0zOSIsCgkJCQkJcHJvY19yZHJ2XzQwKTsKI2VuZGlmCn0KCgovKioKICogcHJvY19yZWFkX2NvbmZpZygpCiAqIEBwYWdlIC0gYnVmZmVyIHRvIHdyaXRlIHRoZSBkYXRhIGluCiAqIEBzdGFydCAtIHdoZXJlIHRoZSBhY3R1YWwgZGF0YSBoYXMgYmVlbiB3cml0dGVuIGluIHBhZ2UKICogQG9mZnNldCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAogKiBAY291bnQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKICogQGVvZiAtIHNldCBpZiBubyBtb3JlIGRhdGEgbmVlZHMgdG8gYmUgcmV0dXJuZWQKICogQGRhdGEgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqCiAqIERpc3BsYXkgY29uZmlndXJhdGlvbiBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY29udHJvbGxlci4KICovCnN0YXRpYyBpbnQKcHJvY19yZWFkX2NvbmZpZyhjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZnNldCwgaW50IGNvdW50LCBpbnQgKmVvZiwKCQl2b2lkICpkYXRhKQp7CgoJYWRhcHRlcl90ICphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWRhdGE7CglpbnQgbGVuID0gMDsKCglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiVzIiwgTUVHQVJBSURfVkVSU0lPTik7CgoJaWYoYWRhcHRlci0+cHJvZHVjdF9pbmZvLnByb2R1Y3RfbmFtZVswXSkKCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiVzXG4iLAoJCQkJYWRhcHRlci0+cHJvZHVjdF9pbmZvLnByb2R1Y3RfbmFtZSk7CgoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJDb250cm9sbGVyIFR5cGU6ICIpOwoKCWlmKCBhZGFwdGVyLT5mbGFnICYgQk9BUkRfTUVNTUFQICkgewoJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLAoJCQkiNDM4LzQ2Ni80NjcvNDcxLzQ5My81MTgvNTIwLzUzMS81MzJcbiIpOwoJfQoJZWxzZSB7CgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sCgkJCSI0MTgvNDI4LzQzNFxuIik7Cgl9CgoJaWYoYWRhcHRlci0+ZmxhZyAmIEJPQVJEXzQwTEQpIHsKCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwKCQkJCSJDb250cm9sbGVyIFN1cHBvcnRzIDQwIExvZ2ljYWwgRHJpdmVzXG4iKTsKCX0KCglpZihhZGFwdGVyLT5mbGFnICYgQk9BUkRfNjRCSVQpIHsKCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwKCQkiQ29udHJvbGxlciBjYXBhYmxlIG9mIDY0LWJpdCBtZW1vcnkgYWRkcmVzc2luZ1xuIik7Cgl9CglpZiggYWRhcHRlci0+aGFzXzY0Yml0X2FkZHIgKSB7CgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sCgkJCSJDb250cm9sbGVyIHVzaW5nIDY0LWJpdCBtZW1vcnkgYWRkcmVzc2luZ1xuIik7Cgl9CgllbHNlIHsKCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwKCQkJIkNvbnRyb2xsZXIgaXMgbm90IHVzaW5nIDY0LWJpdCBtZW1vcnkgYWRkcmVzc2luZ1xuIik7Cgl9CgoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJCYXNlID0gJTA4bHgsIElycSA9ICVkLCAiLCBhZGFwdGVyLT5iYXNlLAoJCQlhZGFwdGVyLT5ob3N0LT5pcnEpOwoKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiTG9naWNhbCBEcml2ZXMgPSAlZCwgQ2hhbm5lbHMgPSAlZFxuIiwKCQkJYWRhcHRlci0+bnVtbGRydiwgYWRhcHRlci0+cHJvZHVjdF9pbmZvLm5jaGFubmVscyk7CgoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJWZXJzaW9uID0lczolcywgRFJBTSA9ICVkTWJcbiIsCgkJCWFkYXB0ZXItPmZ3X3ZlcnNpb24sIGFkYXB0ZXItPmJpb3NfdmVyc2lvbiwKCQkJYWRhcHRlci0+cHJvZHVjdF9pbmZvLmRyYW1fc2l6ZSk7CgoJbGVuICs9IHNwcmludGYocGFnZStsZW4sCgkJIkNvbnRyb2xsZXIgUXVldWUgRGVwdGggPSAlZCwgRHJpdmVyIFF1ZXVlIERlcHRoID0gJWRcbiIsCgkJYWRhcHRlci0+cHJvZHVjdF9pbmZvLm1heF9jb21tYW5kcywgYWRhcHRlci0+bWF4X2NtZHMpOwoKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAic3VwcG9ydF9leHRfY2RiICAgID0gJWRcbiIsCgkJCWFkYXB0ZXItPnN1cHBvcnRfZXh0X2NkYik7CglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgInN1cHBvcnRfcmFuZG9tX2RlbCA9ICVkXG4iLAoJCQlhZGFwdGVyLT5zdXBwb3J0X3JhbmRvbV9kZWwpOwoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJib290X2xkcnZfZW5hYmxlZCAgPSAlZFxuIiwKCQkJYWRhcHRlci0+Ym9vdF9sZHJ2X2VuYWJsZWQpOwoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJib290X2xkcnYgICAgICAgICAgPSAlZFxuIiwKCQkJYWRhcHRlci0+Ym9vdF9sZHJ2KTsKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiYm9vdF9wZHJ2X2VuYWJsZWQgID0gJWRcbiIsCgkJCWFkYXB0ZXItPmJvb3RfcGRydl9lbmFibGVkKTsKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiYm9vdF9wZHJ2X2NoICAgICAgID0gJWRcbiIsCgkJCWFkYXB0ZXItPmJvb3RfcGRydl9jaCk7CglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgImJvb3RfcGRydl90Z3QgICAgICA9ICVkXG4iLAoJCQlhZGFwdGVyLT5ib290X3BkcnZfdGd0KTsKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAicXVpZXNjZW50ICAgICAgICAgID0gJWRcbiIsCgkJCWF0b21pY19yZWFkKCZhZGFwdGVyLT5xdWllc2NlbnQpKTsKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiaGFzX2NsdXN0ZXIgICAgICAgID0gJWRcbiIsCgkJCWFkYXB0ZXItPmhhc19jbHVzdGVyKTsKCglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIlxuTW9kdWxlIFBhcmFtZXRlcnM6XG4iKTsKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAibWF4X2NtZF9wZXJfbHVuICAgID0gJWRcbiIsCgkJCW1heF9jbWRfcGVyX2x1bik7CglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIm1heF9zZWN0b3JzX3Blcl9pbyA9ICVkXG4iLAoJCQltYXhfc2VjdG9yc19wZXJfaW8pOwoKCSplb2YgPSAxOwoKCXJldHVybiBsZW47Cn0KCgoKLyoqCiAqIHByb2NfcmVhZF9zdGF0KCkKICogQHBhZ2UgLSBidWZmZXIgdG8gd3JpdGUgdGhlIGRhdGEgaW4KICogQHN0YXJ0IC0gd2hlcmUgdGhlIGFjdHVhbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4gaW4gcGFnZQogKiBAb2Zmc2V0IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBjb3VudCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAogKiBAZW9mIC0gc2V0IGlmIG5vIG1vcmUgZGF0YSBuZWVkcyB0byBiZSByZXR1cm5lZAogKiBAZGF0YSAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICoKICogRGlhcGxheSBzdGF0aXN0aWNhbCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgSS9PIGFjdGl2aXR5LgogKi8Kc3RhdGljIGludApwcm9jX3JlYWRfc3RhdChjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZnNldCwgaW50IGNvdW50LCBpbnQgKmVvZiwKCQl2b2lkICpkYXRhKQp7CglhZGFwdGVyX3QJKmFkYXB0ZXI7CglpbnQJbGVuOwoJaW50CWk7CgoJaSA9IDA7CS8qIGF2b2lkIGNvbXBpbGF0aW9uIHdhcm5pbmdzICovCglsZW4gPSAwOwoJYWRhcHRlciA9IChhZGFwdGVyX3QgKilkYXRhOwoKCWxlbiA9IHNwcmludGYocGFnZSwgIlN0YXRpc3RpY2FsIEluZm9ybWF0aW9uIGZvciB0aGlzIGNvbnRyb2xsZXJcbiIpOwoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJwZW5kX2NtZHMgPSAlZFxuIiwKCQkJYXRvbWljX3JlYWQoJmFkYXB0ZXItPnBlbmRfY21kcykpOwojaWYgTUVHQV9IQVZFX1NUQVRTCglmb3IoaSA9IDA7IGkgPCBhZGFwdGVyLT5udW1sZHJ2OyBpKyspIHsKCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIkxvZ2ljYWwgRHJpdmUgJWQ6XG4iLCBpKTsKCgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sCgkJCSJcdFJlYWRzIElzc3VlZCA9ICVsdSwgV3JpdGVzIElzc3VlZCA9ICVsdVxuIiwKCQkJYWRhcHRlci0+bnJlYWRzW2ldLCBhZGFwdGVyLT5ud3JpdGVzW2ldKTsKCgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sCgkJCSJcdFNlY3RvcnMgUmVhZCA9ICVsdSwgU2VjdG9ycyBXcml0dGVuID0gJWx1XG4iLAoJCQlhZGFwdGVyLT5ucmVhZGJsb2Nrc1tpXSwgYWRhcHRlci0+bndyaXRlYmxvY2tzW2ldKTsKCgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sCgkJCSJcdFJlYWQgZXJyb3JzID0gJWx1LCBXcml0ZSBlcnJvcnMgPSAlbHVcblxuIiwKCQkJYWRhcHRlci0+cmRfZXJyb3JzW2ldLCBhZGFwdGVyLT53cl9lcnJvcnNbaV0pOwoJfQojZWxzZQoJbGVuICs9IHNwcmludGYocGFnZStsZW4sCgkJCSJJTyBhbmQgZXJyb3IgY291bnRlcnMgbm90IGNvbXBpbGVkIGluIGRyaXZlci5cbiIpOwojZW5kaWYKCgkqZW9mID0gMTsKCglyZXR1cm4gbGVuOwp9CgoKLyoqCiAqIHByb2NfcmVhZF9tYm94KCkKICogQHBhZ2UgLSBidWZmZXIgdG8gd3JpdGUgdGhlIGRhdGEgaW4KICogQHN0YXJ0IC0gd2hlcmUgdGhlIGFjdHVhbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4gaW4gcGFnZQogKiBAb2Zmc2V0IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBjb3VudCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAogKiBAZW9mIC0gc2V0IGlmIG5vIG1vcmUgZGF0YSBuZWVkcyB0byBiZSByZXR1cm5lZAogKiBAZGF0YSAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICoKICogRGlzcGxheSBtYWlsYm94IGluZm9ybWF0aW9uIGZvciB0aGUgbGFzdCBjb21tYW5kIGlzc3VlZC4gVGhpcyBpbmZvcm1hdGlvbgogKiBpcyBnb29kIGZvciBkZWJ1Z2dpbmcuCiAqLwpzdGF0aWMgaW50CnByb2NfcmVhZF9tYm94KGNoYXIgKnBhZ2UsIGNoYXIgKipzdGFydCwgb2ZmX3Qgb2Zmc2V0LCBpbnQgY291bnQsIGludCAqZW9mLAoJCXZvaWQgKmRhdGEpCnsKCglhZGFwdGVyX3QJKmFkYXB0ZXIgPSAoYWRhcHRlcl90ICopZGF0YTsKCXZvbGF0aWxlIG1ib3hfdAkqbWJveCA9IGFkYXB0ZXItPm1ib3g7CglpbnQJbGVuID0gMDsKCglsZW4gPSBzcHJpbnRmKHBhZ2UsICJDb250ZW50cyBvZiBNYWlsIEJveCBTdHJ1Y3R1cmVcbiIpOwoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIgIEZ3IENvbW1hbmQgICA9IDB4JTAyeFxuIiwgCgkJCW1ib3gtPm1fb3V0LmNtZCk7CglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiAgQ21kIFNlcXVlbmNlID0gMHglMDJ4XG4iLCAKCQkJbWJveC0+bV9vdXQuY21kaWQpOwoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIgIE5vIG9mIFNlY3RvcnM9ICUwNGRcbiIsIAoJCQltYm94LT5tX291dC5udW1zZWN0b3JzKTsKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiICBMQkEgICAgICAgICAgPSAweCUwMnhcbiIsIAoJCQltYm94LT5tX291dC5sYmEpOwoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIgIERUQSAgICAgICAgICA9IDB4JTA4eFxuIiwgCgkJCW1ib3gtPm1fb3V0LnhmZXJhZGRyKTsKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiICBMb2dpY2FsIERyaXZlPSAweCUwMnhcbiIsIAoJCQltYm94LT5tX291dC5sb2dkcnYpOwoJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIgIE5vIG9mIFNHIEVsbXQ9IDB4JTAyeFxuIiwKCQkJbWJveC0+bV9vdXQubnVtc2dlbGVtZW50cyk7CglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiAgQnVzeSAgICAgICAgID0gJTAxeFxuIiwgCgkJCW1ib3gtPm1faW4uYnVzeSk7CglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiAgU3RhdHVzICAgICAgID0gMHglMDJ4XG4iLCAKCQkJbWJveC0+bV9pbi5zdGF0dXMpOwoKCSplb2YgPSAxOwoKCXJldHVybiBsZW47Cn0KCgovKioKICogcHJvY19yZWJ1aWxkX3JhdGUoKQogKiBAcGFnZSAtIGJ1ZmZlciB0byB3cml0ZSB0aGUgZGF0YSBpbgogKiBAc3RhcnQgLSB3aGVyZSB0aGUgYWN0dWFsIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiBpbiBwYWdlCiAqIEBvZmZzZXQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKICogQGNvdW50IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBlb2YgLSBzZXQgaWYgbm8gbW9yZSBkYXRhIG5lZWRzIHRvIGJlIHJldHVybmVkCiAqIEBkYXRhIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBEaXNwbGF5IGN1cnJlbnQgcmVidWlsZCByYXRlCiAqLwpzdGF0aWMgaW50CnByb2NfcmVidWlsZF9yYXRlKGNoYXIgKnBhZ2UsIGNoYXIgKipzdGFydCwgb2ZmX3Qgb2Zmc2V0LCBpbnQgY291bnQsIGludCAqZW9mLAoJCXZvaWQgKmRhdGEpCnsKCWFkYXB0ZXJfdAkqYWRhcHRlciA9IChhZGFwdGVyX3QgKilkYXRhOwoJZG1hX2FkZHJfdAlkbWFfaGFuZGxlOwoJY2FkZHJfdAkJaW5xdWlyeTsKCXN0cnVjdCBwY2lfZGV2CSpwZGV2OwoJaW50CWxlbiA9IDA7CgoJaWYoIG1ha2VfbG9jYWxfcGRldihhZGFwdGVyLCAmcGRldikgIT0gMCApIHsKCQkqZW9mID0gMTsKCQlyZXR1cm4gbGVuOwoJfQoKCWlmKCAoaW5xdWlyeSA9IG1lZ2FfYWxsb2NhdGVfaW5xdWlyeSgmZG1hX2hhbmRsZSwgcGRldikpID09IE5VTEwgKSB7CgkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOwoJCSplb2YgPSAxOwoJCXJldHVybiBsZW47Cgl9CgoJaWYoIG1lZ2FfYWRhcGlucShhZGFwdGVyLCBkbWFfaGFuZGxlKSAhPSAwICkgewoKCQlsZW4gPSBzcHJpbnRmKHBhZ2UsICJBZGFwdGVyIGlucXVpcnkgZmFpbGVkLlxuIik7CgoJCXByaW50ayhLRVJOX1dBUk5JTkcgIm1lZ2FyYWlkOiBpbnF1aXJ5IGZhaWxlZC5cbiIpOwoKCQltZWdhX2ZyZWVfaW5xdWlyeShpbnF1aXJ5LCBkbWFfaGFuZGxlLCBwZGV2KTsKCgkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOwoKCQkqZW9mID0gMTsKCgkJcmV0dXJuIGxlbjsKCX0KCglpZiggYWRhcHRlci0+ZmxhZyAmIEJPQVJEXzQwTEQgKSB7CgkJbGVuID0gc3ByaW50ZihwYWdlLCAiUmVidWlsZCBSYXRlOiBbJWQlJV1cbiIsCgkJCSgobWVnYV9pbnF1aXJ5MyAqKWlucXVpcnkpLT5yZWJ1aWxkX3JhdGUpOwoJfQoJZWxzZSB7CgkJbGVuID0gc3ByaW50ZihwYWdlLCAiUmVidWlsZCBSYXRlOiBbJWQlJV1cbiIsCgkJCSgobXJhaWRfZXh0X2lucXVpcnkgKikKCQkJaW5xdWlyeSktPnJhaWRfaW5xLmFkYXB0ZXJfaW5mby5yZWJ1aWxkX3JhdGUpOwoJfQoKCgltZWdhX2ZyZWVfaW5xdWlyeShpbnF1aXJ5LCBkbWFfaGFuZGxlLCBwZGV2KTsKCglmcmVlX2xvY2FsX3BkZXYocGRldik7CgoJKmVvZiA9IDE7CgoJcmV0dXJuIGxlbjsKfQoKCi8qKgogKiBwcm9jX2JhdHRlcnkoKQogKiBAcGFnZSAtIGJ1ZmZlciB0byB3cml0ZSB0aGUgZGF0YSBpbgogKiBAc3RhcnQgLSB3aGVyZSB0aGUgYWN0dWFsIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiBpbiBwYWdlCiAqIEBvZmZzZXQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKICogQGNvdW50IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBlb2YgLSBzZXQgaWYgbm8gbW9yZSBkYXRhIG5lZWRzIHRvIGJlIHJldHVybmVkCiAqIEBkYXRhIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBEaXNwbGF5IGluZm9ybWF0aW9uIGFib3V0IHRoZSBiYXR0ZXJ5IG1vZHVsZSBvbiB0aGUgY29udHJvbGxlci4KICovCnN0YXRpYyBpbnQKcHJvY19iYXR0ZXJ5KGNoYXIgKnBhZ2UsIGNoYXIgKipzdGFydCwgb2ZmX3Qgb2Zmc2V0LCBpbnQgY291bnQsIGludCAqZW9mLAoJCXZvaWQgKmRhdGEpCnsKCWFkYXB0ZXJfdAkqYWRhcHRlciA9IChhZGFwdGVyX3QgKilkYXRhOwoJZG1hX2FkZHJfdAlkbWFfaGFuZGxlOwoJY2FkZHJfdAkJaW5xdWlyeTsKCXN0cnVjdCBwY2lfZGV2CSpwZGV2OwoJdTgJYmF0dGVyeV9zdGF0dXMgPSAwOwoJY2hhcglzdHJbMjU2XTsKCWludAlsZW4gPSAwOwoKCWlmKCBtYWtlX2xvY2FsX3BkZXYoYWRhcHRlciwgJnBkZXYpICE9IDAgKSB7CgkJKmVvZiA9IDE7CgkJcmV0dXJuIGxlbjsKCX0KCglpZiggKGlucXVpcnkgPSBtZWdhX2FsbG9jYXRlX2lucXVpcnkoJmRtYV9oYW5kbGUsIHBkZXYpKSA9PSBOVUxMICkgewoJCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKCQkqZW9mID0gMTsKCQlyZXR1cm4gbGVuOwoJfQoKCWlmKCBtZWdhX2FkYXBpbnEoYWRhcHRlciwgZG1hX2hhbmRsZSkgIT0gMCApIHsKCgkJbGVuID0gc3ByaW50ZihwYWdlLCAiQWRhcHRlciBpbnF1aXJ5IGZhaWxlZC5cbiIpOwoKCQlwcmludGsoS0VSTl9XQVJOSU5HICJtZWdhcmFpZDogaW5xdWlyeSBmYWlsZWQuXG4iKTsKCgkJbWVnYV9mcmVlX2lucXVpcnkoaW5xdWlyeSwgZG1hX2hhbmRsZSwgcGRldik7CgoJCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKCgkJKmVvZiA9IDE7CgoJCXJldHVybiBsZW47Cgl9CgoJaWYoIGFkYXB0ZXItPmZsYWcgJiBCT0FSRF80MExEICkgewoJCWJhdHRlcnlfc3RhdHVzID0gKChtZWdhX2lucXVpcnkzICopaW5xdWlyeSktPmJhdHRlcnlfc3RhdHVzOwoJfQoJZWxzZSB7CgkJYmF0dGVyeV9zdGF0dXMgPSAoKG1yYWlkX2V4dF9pbnF1aXJ5ICopaW5xdWlyeSktPgoJCQlyYWlkX2lucS5hZGFwdGVyX2luZm8uYmF0dGVyeV9zdGF0dXM7Cgl9CgoJLyoKCSAqIERlY29kZSB0aGUgYmF0dGVyeSBzdGF0dXMKCSAqLwoJc3ByaW50ZihzdHIsICJCYXR0ZXJ5IFN0YXR1czpbJWRdIiwgYmF0dGVyeV9zdGF0dXMpOwoKCWlmKGJhdHRlcnlfc3RhdHVzID09IE1FR0FfQkFUVF9DSEFSR0VfRE9ORSkKCQlzdHJjYXQoc3RyLCAiIENoYXJnZSBEb25lIik7CgoJaWYoYmF0dGVyeV9zdGF0dXMgJiBNRUdBX0JBVFRfTU9EVUxFX01JU1NJTkcpCgkJc3RyY2F0KHN0ciwgIiBNb2R1bGUgTWlzc2luZyIpOwoJCglpZihiYXR0ZXJ5X3N0YXR1cyAmIE1FR0FfQkFUVF9MT1dfVk9MVEFHRSkKCQlzdHJjYXQoc3RyLCAiIExvdyBWb2x0YWdlIik7CgkKCWlmKGJhdHRlcnlfc3RhdHVzICYgTUVHQV9CQVRUX1RFTVBfSElHSCkKCQlzdHJjYXQoc3RyLCAiIFRlbXBlcmF0dXJlIEhpZ2giKTsKCQoJaWYoYmF0dGVyeV9zdGF0dXMgJiBNRUdBX0JBVFRfUEFDS19NSVNTSU5HKQoJCXN0cmNhdChzdHIsICIgUGFjayBNaXNzaW5nIik7CgkKCWlmKGJhdHRlcnlfc3RhdHVzICYgTUVHQV9CQVRUX0NIQVJHRV9JTlBST0cpCgkJc3RyY2F0KHN0ciwgIiBDaGFyZ2UgSW4tcHJvZ3Jlc3MiKTsKCQoJaWYoYmF0dGVyeV9zdGF0dXMgJiBNRUdBX0JBVFRfQ0hBUkdFX0ZBSUwpCgkJc3RyY2F0KHN0ciwgIiBDaGFyZ2UgRmFpbCIpOwoJCglpZihiYXR0ZXJ5X3N0YXR1cyAmIE1FR0FfQkFUVF9DWUNMRVNfRVhDRUVERUQpCgkJc3RyY2F0KHN0ciwgIiBDeWNsZXMgRXhjZWVkZWQiKTsKCglsZW4gPSBzcHJpbnRmKHBhZ2UsICIlc1xuIiwgc3RyKTsKCgoJbWVnYV9mcmVlX2lucXVpcnkoaW5xdWlyeSwgZG1hX2hhbmRsZSwgcGRldik7CgoJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOwoKCSplb2YgPSAxOwoKCXJldHVybiBsZW47Cn0KCgovKioKICogcHJvY19wZHJ2X2NoMCgpCiAqIEBwYWdlIC0gYnVmZmVyIHRvIHdyaXRlIHRoZSBkYXRhIGluCiAqIEBzdGFydCAtIHdoZXJlIHRoZSBhY3R1YWwgZGF0YSBoYXMgYmVlbiB3cml0dGVuIGluIHBhZ2UKICogQG9mZnNldCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAogKiBAY291bnQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKICogQGVvZiAtIHNldCBpZiBubyBtb3JlIGRhdGEgbmVlZHMgdG8gYmUgcmV0dXJuZWQKICogQGRhdGEgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqCiAqIERpc3BsYXkgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHBoeXNpY2FsIGRyaXZlcyBvbiBwaHlzaWNhbCBjaGFubmVsIDAuCiAqLwpzdGF0aWMgaW50CnByb2NfcGRydl9jaDAoY2hhciAqcGFnZSwgY2hhciAqKnN0YXJ0LCBvZmZfdCBvZmZzZXQsIGludCBjb3VudCwgaW50ICplb2YsCgkJdm9pZCAqZGF0YSkKewoJYWRhcHRlcl90ICphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWRhdGE7CgoJKmVvZiA9IDE7CgoJcmV0dXJuIChwcm9jX3BkcnYoYWRhcHRlciwgcGFnZSwgMCkpOwp9CgoKLyoqCiAqIHByb2NfcGRydl9jaDEoKQogKiBAcGFnZSAtIGJ1ZmZlciB0byB3cml0ZSB0aGUgZGF0YSBpbgogKiBAc3RhcnQgLSB3aGVyZSB0aGUgYWN0dWFsIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiBpbiBwYWdlCiAqIEBvZmZzZXQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKICogQGNvdW50IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBlb2YgLSBzZXQgaWYgbm8gbW9yZSBkYXRhIG5lZWRzIHRvIGJlIHJldHVybmVkCiAqIEBkYXRhIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBEaXNwbGF5IGluZm9ybWF0aW9uIGFib3V0IHRoZSBwaHlzaWNhbCBkcml2ZXMgb24gcGh5c2ljYWwgY2hhbm5lbCAxLgogKi8Kc3RhdGljIGludApwcm9jX3BkcnZfY2gxKGNoYXIgKnBhZ2UsIGNoYXIgKipzdGFydCwgb2ZmX3Qgb2Zmc2V0LCBpbnQgY291bnQsIGludCAqZW9mLAoJCXZvaWQgKmRhdGEpCnsKCWFkYXB0ZXJfdCAqYWRhcHRlciA9IChhZGFwdGVyX3QgKilkYXRhOwoKCSplb2YgPSAxOwoKCXJldHVybiAocHJvY19wZHJ2KGFkYXB0ZXIsIHBhZ2UsIDEpKTsKfQoKCi8qKgogKiBwcm9jX3BkcnZfY2gyKCkKICogQHBhZ2UgLSBidWZmZXIgdG8gd3JpdGUgdGhlIGRhdGEgaW4KICogQHN0YXJ0IC0gd2hlcmUgdGhlIGFjdHVhbCBkYXRhIGhhcyBiZWVuIHdyaXR0ZW4gaW4gcGFnZQogKiBAb2Zmc2V0IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBjb3VudCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAogKiBAZW9mIC0gc2V0IGlmIG5vIG1vcmUgZGF0YSBuZWVkcyB0byBiZSByZXR1cm5lZAogKiBAZGF0YSAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICoKICogRGlzcGxheSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgcGh5c2ljYWwgZHJpdmVzIG9uIHBoeXNpY2FsIGNoYW5uZWwgMi4KICovCnN0YXRpYyBpbnQKcHJvY19wZHJ2X2NoMihjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZnNldCwgaW50IGNvdW50LCBpbnQgKmVvZiwKCQl2b2lkICpkYXRhKQp7CglhZGFwdGVyX3QgKmFkYXB0ZXIgPSAoYWRhcHRlcl90ICopZGF0YTsKCgkqZW9mID0gMTsKCglyZXR1cm4gKHByb2NfcGRydihhZGFwdGVyLCBwYWdlLCAyKSk7Cn0KCgovKioKICogcHJvY19wZHJ2X2NoMygpCiAqIEBwYWdlIC0gYnVmZmVyIHRvIHdyaXRlIHRoZSBkYXRhIGluCiAqIEBzdGFydCAtIHdoZXJlIHRoZSBhY3R1YWwgZGF0YSBoYXMgYmVlbiB3cml0dGVuIGluIHBhZ2UKICogQG9mZnNldCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAogKiBAY291bnQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKICogQGVvZiAtIHNldCBpZiBubyBtb3JlIGRhdGEgbmVlZHMgdG8gYmUgcmV0dXJuZWQKICogQGRhdGEgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqCiAqIERpc3BsYXkgaW5mb3JtYXRpb24gYWJvdXQgdGhlIHBoeXNpY2FsIGRyaXZlcyBvbiBwaHlzaWNhbCBjaGFubmVsIDMuCiAqLwpzdGF0aWMgaW50CnByb2NfcGRydl9jaDMoY2hhciAqcGFnZSwgY2hhciAqKnN0YXJ0LCBvZmZfdCBvZmZzZXQsIGludCBjb3VudCwgaW50ICplb2YsCgkJdm9pZCAqZGF0YSkKewoJYWRhcHRlcl90ICphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWRhdGE7CgoJKmVvZiA9IDE7CgoJcmV0dXJuIChwcm9jX3BkcnYoYWRhcHRlciwgcGFnZSwgMykpOwp9CgoKLyoqCiAqIHByb2NfcGRydigpCiAqIEBwYWdlIC0gYnVmZmVyIHRvIHdyaXRlIHRoZSBkYXRhIGluCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBEaXNwbGF5IGluZm9ybWF0aW9uIGFib3V0IHRoZSBwaHlzaWNhbCBkcml2ZXMuCiAqLwpzdGF0aWMgaW50CnByb2NfcGRydihhZGFwdGVyX3QgKmFkYXB0ZXIsIGNoYXIgKnBhZ2UsIGludCBjaGFubmVsKQp7CglkbWFfYWRkcl90CWRtYV9oYW5kbGU7CgljaGFyCQkqc2NzaV9pbnE7CglkbWFfYWRkcl90CXNjc2lfaW5xX2RtYV9oYW5kbGU7CgljYWRkcl90CQlpbnF1aXJ5OwoJc3RydWN0IHBjaV9kZXYJKnBkZXY7Cgl1OAkqcGRydl9zdGF0ZTsKCXU4CXN0YXRlOwoJaW50CXRndDsKCWludAltYXhfY2hhbm5lbHM7CglpbnQJbGVuID0gMDsKCWNoYXIJc3RyWzgwXTsKCWludAlpOwoKCWlmKCBtYWtlX2xvY2FsX3BkZXYoYWRhcHRlciwgJnBkZXYpICE9IDAgKSB7CgkJcmV0dXJuIGxlbjsKCX0KCglpZiggKGlucXVpcnkgPSBtZWdhX2FsbG9jYXRlX2lucXVpcnkoJmRtYV9oYW5kbGUsIHBkZXYpKSA9PSBOVUxMICkgewoJCWdvdG8gZnJlZV9wZGV2OwoJfQoKCWlmKCBtZWdhX2FkYXBpbnEoYWRhcHRlciwgZG1hX2hhbmRsZSkgIT0gMCApIHsKCQlsZW4gPSBzcHJpbnRmKHBhZ2UsICJBZGFwdGVyIGlucXVpcnkgZmFpbGVkLlxuIik7CgoJCXByaW50ayhLRVJOX1dBUk5JTkcgIm1lZ2FyYWlkOiBpbnF1aXJ5IGZhaWxlZC5cbiIpOwoKCQlnb3RvIGZyZWVfaW5xdWlyeTsKCX0KCgoJc2NzaV9pbnEgPSBwY2lfYWxsb2NfY29uc2lzdGVudChwZGV2LCAyNTYsICZzY3NpX2lucV9kbWFfaGFuZGxlKTsKCglpZiggc2NzaV9pbnEgPT0gTlVMTCApIHsKCQlsZW4gPSBzcHJpbnRmKHBhZ2UsICJtZW1vcnkgbm90IGF2YWlsYWJsZSBmb3Igc2NzaSBpbnEuXG4iKTsKCgkJZ290byBmcmVlX2lucXVpcnk7Cgl9CgoJaWYoIGFkYXB0ZXItPmZsYWcgJiBCT0FSRF80MExEICkgewoJCXBkcnZfc3RhdGUgPSAoKG1lZ2FfaW5xdWlyeTMgKilpbnF1aXJ5KS0+cGRydl9zdGF0ZTsKCX0KCWVsc2UgewoJCXBkcnZfc3RhdGUgPSAoKG1yYWlkX2V4dF9pbnF1aXJ5ICopaW5xdWlyeSktPgoJCQlyYWlkX2lucS5wZHJ2X2luZm8ucGRydl9zdGF0ZTsKCX0KCgltYXhfY2hhbm5lbHMgPSBhZGFwdGVyLT5wcm9kdWN0X2luZm8ubmNoYW5uZWxzOwoKCWlmKCBjaGFubmVsID49IG1heF9jaGFubmVscyApIHsKCQlnb3RvIGZyZWVfcGNpOwoJfQoKCWZvciggdGd0ID0gMDsgdGd0IDw9IE1BWF9UQVJHRVQ7IHRndCsrICkgewoKCQlpID0gY2hhbm5lbCoxNiArIHRndDsKCgkJc3RhdGUgPSAqKHBkcnZfc3RhdGUgKyBpKTsKCgkJc3dpdGNoKCBzdGF0ZSAmIDB4MEYgKSB7CgoJCWNhc2UgUERSVl9PTkxJTkU6CgkJCXNwcmludGYoc3RyLAoJCQkiQ2hhbm5lbDolMmQgSWQ6JTJkIFN0YXRlOiBPbmxpbmUiLAoJCQkJY2hhbm5lbCwgdGd0KTsKCQkJYnJlYWs7CgoJCWNhc2UgUERSVl9GQUlMRUQ6CgkJCXNwcmludGYoc3RyLAoJCQkiQ2hhbm5lbDolMmQgSWQ6JTJkIFN0YXRlOiBGYWlsZWQiLAoJCQkJY2hhbm5lbCwgdGd0KTsKCQkJYnJlYWs7CgoJCWNhc2UgUERSVl9SQkxEOgoJCQlzcHJpbnRmKHN0ciwKCQkJIkNoYW5uZWw6JTJkIElkOiUyZCBTdGF0ZTogUmVidWlsZCIsCgkJCQljaGFubmVsLCB0Z3QpOwoJCQlicmVhazsKCgkJY2FzZSBQRFJWX0hPVFNQQVJFOgoJCQlzcHJpbnRmKHN0ciwKCQkJIkNoYW5uZWw6JTJkIElkOiUyZCBTdGF0ZTogSG90IHNwYXJlIiwKCQkJCWNoYW5uZWwsIHRndCk7CgkJCWJyZWFrOwoKCQlkZWZhdWx0OgoJCQlzcHJpbnRmKHN0ciwKCQkJIkNoYW5uZWw6JTJkIElkOiUyZCBTdGF0ZTogVW4tY29uZmlndXJlZCIsCgkJCQljaGFubmVsLCB0Z3QpOwoJCQlicmVhazsKCgkJfQoKCQkvKgoJCSAqIFRoaXMgaW50ZXJmYWNlIGRpc3BsYXlzIGlucXVpcmllcyBmb3IgZGlzayBkcml2ZXMKCQkgKiBvbmx5LiBJbnF1cmllcyBmb3IgbG9naWNhbCBkcml2ZXMgYW5kIG5vbi1kaXNrCgkJICogZGV2aWNlcyBhcmUgYXZhaWxhYmxlIHRocm91Z2ggL3Byb2Mvc2NzaS9zY3NpCgkJICovCgkJbWVtc2V0KHNjc2lfaW5xLCAwLCAyNTYpOwoJCWlmKCBtZWdhX2ludGVybmFsX2Rldl9pbnF1aXJ5KGFkYXB0ZXIsIGNoYW5uZWwsIHRndCwKCQkJCXNjc2lfaW5xX2RtYV9oYW5kbGUpIHx8CgkJCQkoc2NzaV9pbnFbMF0gJiAweDFGKSAhPSBUWVBFX0RJU0sgKSB7CgkJCWNvbnRpbnVlOwoJCX0KCgkJLyoKCQkgKiBDaGVjayBmb3Igb3ZlcmZsb3cuIFdlIHByaW50IGxlc3MgdGhhbiAyNDAKCQkgKiBjaGFyYWN0ZXJzIGZvciBpbnF1aXJ5CgkJICovCgkJaWYoIChsZW4gKyAyNDApID49IFBBR0VfU0laRSApIGJyZWFrOwoKCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiVzLlxuIiwgc3RyKTsKCgkJbGVuICs9IG1lZ2FfcHJpbnRfaW5xdWlyeShwYWdlK2xlbiwgc2NzaV9pbnEpOwoJfQoKZnJlZV9wY2k6CglwY2lfZnJlZV9jb25zaXN0ZW50KHBkZXYsIDI1Niwgc2NzaV9pbnEsIHNjc2lfaW5xX2RtYV9oYW5kbGUpOwpmcmVlX2lucXVpcnk6CgltZWdhX2ZyZWVfaW5xdWlyeShpbnF1aXJ5LCBkbWFfaGFuZGxlLCBwZGV2KTsKZnJlZV9wZGV2OgoJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOwoKCXJldHVybiBsZW47Cn0KCgovKgogKiBEaXNwbGF5IHNjc2kgaW5xdWlyeQogKi8Kc3RhdGljIGludAptZWdhX3ByaW50X2lucXVpcnkoY2hhciAqcGFnZSwgY2hhciAqc2NzaV9pbnEpCnsKCWludAlsZW4gPSAwOwoJaW50CWk7CgoJbGVuID0gc3ByaW50ZihwYWdlLCAiICBWZW5kb3I6ICIpOwoJZm9yKCBpID0gODsgaSA8IDE2OyBpKysgKSB7CgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICIlYyIsIHNjc2lfaW5xW2ldKTsKCX0KCglsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiAgTW9kZWw6ICIpOwoKCWZvciggaSA9IDE2OyBpIDwgMzI7IGkrKyApIHsKCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiVjIiwgc2NzaV9pbnFbaV0pOwoJfQoKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiICBSZXY6ICIpOwoKCWZvciggaSA9IDMyOyBpIDwgMzY7IGkrKyApIHsKCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiVjIiwgc2NzaV9pbnFbaV0pOwoJfQoKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiXG4iKTsKCglpID0gc2NzaV9pbnFbMF0gJiAweDFmOwoKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiICBUeXBlOiAgICVzICIsCgkJaSA8IE1BWF9TQ1NJX0RFVklDRV9DT0RFID8gc2NzaV9kZXZpY2VfdHlwZXNbaV0gOgoJCSAgICJVbmtub3duICAgICAgICAgICIpOwoKCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLAoJIiAgICAgICAgICAgICAgICAgQU5TSSBTQ1NJIHJldmlzaW9uOiAlMDJ4Iiwgc2NzaV9pbnFbMl0gJiAweDA3KTsKCglpZiggKHNjc2lfaW5xWzJdICYgMHgwNykgPT0gMSAmJiAoc2NzaV9pbnFbM10gJiAweDBmKSA9PSAxICkKCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIiBDQ1NcbiIpOwoJZWxzZQoJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiXG4iKTsKCglyZXR1cm4gbGVuOwp9CgoKLyoqCiAqIHByb2NfcmRydl8xMCgpCiAqIEBwYWdlIC0gYnVmZmVyIHRvIHdyaXRlIHRoZSBkYXRhIGluCiAqIEBzdGFydCAtIHdoZXJlIHRoZSBhY3R1YWwgZGF0YSBoYXMgYmVlbiB3cml0dGVuIGluIHBhZ2UKICogQG9mZnNldCAtIHNhbWUgbWVhbmluZyBhcyB0aGUgcmVhZCBzeXN0ZW0gY2FsbAogKiBAY291bnQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKICogQGVvZiAtIHNldCBpZiBubyBtb3JlIGRhdGEgbmVlZHMgdG8gYmUgcmV0dXJuZWQKICogQGRhdGEgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqCiAqIERpc3BsYXkgcmVhbCB0aW1lIGluZm9ybWF0aW9uIGFib3V0IHRoZSBsb2dpY2FsIGRyaXZlcyAwIHRocm91Z2ggOS4KICovCnN0YXRpYyBpbnQKcHJvY19yZHJ2XzEwKGNoYXIgKnBhZ2UsIGNoYXIgKipzdGFydCwgb2ZmX3Qgb2Zmc2V0LCBpbnQgY291bnQsIGludCAqZW9mLAoJCXZvaWQgKmRhdGEpCnsKCWFkYXB0ZXJfdCAqYWRhcHRlciA9IChhZGFwdGVyX3QgKilkYXRhOwoKCSplb2YgPSAxOwoKCXJldHVybiAocHJvY19yZHJ2KGFkYXB0ZXIsIHBhZ2UsIDAsIDkpKTsKfQoKCi8qKgogKiBwcm9jX3JkcnZfMjAoKQogKiBAcGFnZSAtIGJ1ZmZlciB0byB3cml0ZSB0aGUgZGF0YSBpbgogKiBAc3RhcnQgLSB3aGVyZSB0aGUgYWN0dWFsIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiBpbiBwYWdlCiAqIEBvZmZzZXQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKICogQGNvdW50IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBlb2YgLSBzZXQgaWYgbm8gbW9yZSBkYXRhIG5lZWRzIHRvIGJlIHJldHVybmVkCiAqIEBkYXRhIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBEaXNwbGF5IHJlYWwgdGltZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbG9naWNhbCBkcml2ZXMgMCB0aHJvdWdoIDkuCiAqLwpzdGF0aWMgaW50CnByb2NfcmRydl8yMChjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZnNldCwgaW50IGNvdW50LCBpbnQgKmVvZiwKCQl2b2lkICpkYXRhKQp7CglhZGFwdGVyX3QgKmFkYXB0ZXIgPSAoYWRhcHRlcl90ICopZGF0YTsKCgkqZW9mID0gMTsKCglyZXR1cm4gKHByb2NfcmRydihhZGFwdGVyLCBwYWdlLCAxMCwgMTkpKTsKfQoKCi8qKgogKiBwcm9jX3JkcnZfMzAoKQogKiBAcGFnZSAtIGJ1ZmZlciB0byB3cml0ZSB0aGUgZGF0YSBpbgogKiBAc3RhcnQgLSB3aGVyZSB0aGUgYWN0dWFsIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiBpbiBwYWdlCiAqIEBvZmZzZXQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKICogQGNvdW50IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBlb2YgLSBzZXQgaWYgbm8gbW9yZSBkYXRhIG5lZWRzIHRvIGJlIHJldHVybmVkCiAqIEBkYXRhIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBEaXNwbGF5IHJlYWwgdGltZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbG9naWNhbCBkcml2ZXMgMCB0aHJvdWdoIDkuCiAqLwpzdGF0aWMgaW50CnByb2NfcmRydl8zMChjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZnNldCwgaW50IGNvdW50LCBpbnQgKmVvZiwKCQl2b2lkICpkYXRhKQp7CglhZGFwdGVyX3QgKmFkYXB0ZXIgPSAoYWRhcHRlcl90ICopZGF0YTsKCgkqZW9mID0gMTsKCglyZXR1cm4gKHByb2NfcmRydihhZGFwdGVyLCBwYWdlLCAyMCwgMjkpKTsKfQoKCi8qKgogKiBwcm9jX3JkcnZfNDAoKQogKiBAcGFnZSAtIGJ1ZmZlciB0byB3cml0ZSB0aGUgZGF0YSBpbgogKiBAc3RhcnQgLSB3aGVyZSB0aGUgYWN0dWFsIGRhdGEgaGFzIGJlZW4gd3JpdHRlbiBpbiBwYWdlCiAqIEBvZmZzZXQgLSBzYW1lIG1lYW5pbmcgYXMgdGhlIHJlYWQgc3lzdGVtIGNhbGwKICogQGNvdW50IC0gc2FtZSBtZWFuaW5nIGFzIHRoZSByZWFkIHN5c3RlbSBjYWxsCiAqIEBlb2YgLSBzZXQgaWYgbm8gbW9yZSBkYXRhIG5lZWRzIHRvIGJlIHJldHVybmVkCiAqIEBkYXRhIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBEaXNwbGF5IHJlYWwgdGltZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbG9naWNhbCBkcml2ZXMgMCB0aHJvdWdoIDkuCiAqLwpzdGF0aWMgaW50CnByb2NfcmRydl80MChjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZnNldCwgaW50IGNvdW50LCBpbnQgKmVvZiwKCQl2b2lkICpkYXRhKQp7CglhZGFwdGVyX3QgKmFkYXB0ZXIgPSAoYWRhcHRlcl90ICopZGF0YTsKCgkqZW9mID0gMTsKCglyZXR1cm4gKHByb2NfcmRydihhZGFwdGVyLCBwYWdlLCAzMCwgMzkpKTsKfQoKCi8qKgogKiBwcm9jX3JkcnYoKQogKiBAcGFnZSAtIGJ1ZmZlciB0byB3cml0ZSB0aGUgZGF0YSBpbgogKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICogQHN0YXJ0IC0gc3RhcnRpbmcgbG9naWNhbCBkcml2ZSB0byBkaXNwbGF5CiAqIEBlbmQgLSBlbmRpbmcgbG9naWNhbCBkcml2ZSB0byBkaXNwbGF5CiAqCiAqIFdlIGRvIG5vdCBwcmludCB0aGUgaW5xdWlyeSBpbmZvcm1hdGlvbiBzaW5jZSBpdHMgYWxyZWFkeSBhdmFpbGFibGUgdGhyb3VnaAogKiAvcHJvYy9zY3NpL3Njc2kgaW50ZXJmYWNlCiAqLwpzdGF0aWMgaW50CnByb2NfcmRydihhZGFwdGVyX3QgKmFkYXB0ZXIsIGNoYXIgKnBhZ2UsIGludCBzdGFydCwgaW50IGVuZCApCnsKCWRtYV9hZGRyX3QJZG1hX2hhbmRsZTsKCWxvZ2Rydl9wYXJhbQkqbHBhcmFtOwoJbWVnYWNtZF90CW1jOwoJY2hhcgkJKmRpc2tfYXJyYXk7CglkbWFfYWRkcl90CWRpc2tfYXJyYXlfZG1hX2hhbmRsZTsKCWNhZGRyX3QJCWlucXVpcnk7CglzdHJ1Y3QgcGNpX2RldgkqcGRldjsKCXU4CSpyZHJ2X3N0YXRlOwoJaW50CW51bV9sZHJ2OwoJdTMyCWFycmF5X3N6OwoJaW50CWxlbiA9IDA7CglpbnQJaTsKCglpZiggbWFrZV9sb2NhbF9wZGV2KGFkYXB0ZXIsICZwZGV2KSAhPSAwICkgewoJCXJldHVybiBsZW47Cgl9CgoJaWYoIChpbnF1aXJ5ID0gbWVnYV9hbGxvY2F0ZV9pbnF1aXJ5KCZkbWFfaGFuZGxlLCBwZGV2KSkgPT0gTlVMTCApIHsKCQlmcmVlX2xvY2FsX3BkZXYocGRldik7CgkJcmV0dXJuIGxlbjsKCX0KCglpZiggbWVnYV9hZGFwaW5xKGFkYXB0ZXIsIGRtYV9oYW5kbGUpICE9IDAgKSB7CgoJCWxlbiA9IHNwcmludGYocGFnZSwgIkFkYXB0ZXIgaW5xdWlyeSBmYWlsZWQuXG4iKTsKCgkJcHJpbnRrKEtFUk5fV0FSTklORyAibWVnYXJhaWQ6IGlucXVpcnkgZmFpbGVkLlxuIik7CgoJCW1lZ2FfZnJlZV9pbnF1aXJ5KGlucXVpcnksIGRtYV9oYW5kbGUsIHBkZXYpOwoKCQlmcmVlX2xvY2FsX3BkZXYocGRldik7CgoJCXJldHVybiBsZW47Cgl9CgoJbWVtc2V0KCZtYywgMCwgc2l6ZW9mKG1lZ2FjbWRfdCkpOwoKCWlmKCBhZGFwdGVyLT5mbGFnICYgQk9BUkRfNDBMRCApIHsKCQlhcnJheV9zeiA9IHNpemVvZihkaXNrX2FycmF5XzQwbGQpOwoKCQlyZHJ2X3N0YXRlID0gKChtZWdhX2lucXVpcnkzICopaW5xdWlyeSktPmxkcnZfc3RhdGU7CgoJCW51bV9sZHJ2ID0gKChtZWdhX2lucXVpcnkzICopaW5xdWlyeSktPm51bV9sZHJ2OwoJfQoJZWxzZSB7CgkJYXJyYXlfc3ogPSBzaXplb2YoZGlza19hcnJheV84bGQpOwoKCQlyZHJ2X3N0YXRlID0gKChtcmFpZF9leHRfaW5xdWlyeSAqKWlucXVpcnkpLT4KCQkJcmFpZF9pbnEubG9nZHJ2X2luZm8ubGRydl9zdGF0ZTsKCgkJbnVtX2xkcnYgPSAoKG1yYWlkX2V4dF9pbnF1aXJ5ICopaW5xdWlyeSktPgoJCQlyYWlkX2lucS5sb2dkcnZfaW5mby5udW1fbGRydjsKCX0KCglkaXNrX2FycmF5ID0gcGNpX2FsbG9jX2NvbnNpc3RlbnQocGRldiwgYXJyYXlfc3osCgkJCSZkaXNrX2FycmF5X2RtYV9oYW5kbGUpOwoKCWlmKCBkaXNrX2FycmF5ID09IE5VTEwgKSB7CgkJbGVuID0gc3ByaW50ZihwYWdlLCAibWVtb3J5IG5vdCBhdmFpbGFibGUuXG4iKTsKCgkJbWVnYV9mcmVlX2lucXVpcnkoaW5xdWlyeSwgZG1hX2hhbmRsZSwgcGRldik7CgoJCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKCgkJcmV0dXJuIGxlbjsKCX0KCgltYy54ZmVyYWRkciA9ICh1MzIpZGlza19hcnJheV9kbWFfaGFuZGxlOwoKCWlmKCBhZGFwdGVyLT5mbGFnICYgQk9BUkRfNDBMRCApIHsKCQltYy5jbWQgPSBGQ19ORVdfQ09ORklHOwoJCW1jLm9wY29kZSA9IE9QX0RDTURfUkVBRF9DT05GSUc7CgoJCWlmKCBtZWdhX2ludGVybmFsX2NvbW1hbmQoYWRhcHRlciwgTE9DS19JTlQsICZtYywgTlVMTCkgKSB7CgoJCQlsZW4gPSBzcHJpbnRmKHBhZ2UsICI0MExEIHJlYWQgY29uZmlnIGZhaWxlZC5cbiIpOwoKCQkJbWVnYV9mcmVlX2lucXVpcnkoaW5xdWlyeSwgZG1hX2hhbmRsZSwgcGRldik7CgoJCQlwY2lfZnJlZV9jb25zaXN0ZW50KHBkZXYsIGFycmF5X3N6LCBkaXNrX2FycmF5LAoJCQkJCWRpc2tfYXJyYXlfZG1hX2hhbmRsZSk7CgoJCQlmcmVlX2xvY2FsX3BkZXYocGRldik7CgoJCQlyZXR1cm4gbGVuOwoJCX0KCgl9CgllbHNlIHsKCQltYy5jbWQgPSBORVdfUkVBRF9DT05GSUdfOExEOwoKCQlpZiggbWVnYV9pbnRlcm5hbF9jb21tYW5kKGFkYXB0ZXIsIExPQ0tfSU5ULCAmbWMsIE5VTEwpICkgewoKCQkJbWMuY21kID0gUkVBRF9DT05GSUdfOExEOwoKCQkJaWYoIG1lZ2FfaW50ZXJuYWxfY29tbWFuZChhZGFwdGVyLCBMT0NLX0lOVCwgJm1jLAoJCQkJCQlOVUxMKSApewoKCQkJCWxlbiA9IHNwcmludGYocGFnZSwKCQkJCQkiOExEIHJlYWQgY29uZmlnIGZhaWxlZC5cbiIpOwoKCQkJCW1lZ2FfZnJlZV9pbnF1aXJ5KGlucXVpcnksIGRtYV9oYW5kbGUsIHBkZXYpOwoKCQkJCXBjaV9mcmVlX2NvbnNpc3RlbnQocGRldiwgYXJyYXlfc3osCgkJCQkJCWRpc2tfYXJyYXksCgkJCQkJCWRpc2tfYXJyYXlfZG1hX2hhbmRsZSk7CgoJCQkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOwoKCQkJCXJldHVybiBsZW47CgkJCX0KCQl9Cgl9CgoJZm9yKCBpID0gc3RhcnQ7IGkgPCAoIChlbmQrMSA8IG51bV9sZHJ2KSA/IGVuZCsxIDogbnVtX2xkcnYgKTsgaSsrICkgewoKCQlpZiggYWRhcHRlci0+ZmxhZyAmIEJPQVJEXzQwTEQgKSB7CgkJCWxwYXJhbSA9CgkJCSYoKGRpc2tfYXJyYXlfNDBsZCAqKWRpc2tfYXJyYXkpLT5sZHJ2W2ldLmxwYXJhbTsKCQl9CgkJZWxzZSB7CgkJCWxwYXJhbSA9CgkJCSYoKGRpc2tfYXJyYXlfOGxkICopZGlza19hcnJheSktPmxkcnZbaV0ubHBhcmFtOwoJCX0KCgkJLyoKCQkgKiBDaGVjayBmb3Igb3ZlcmZsb3cuIFdlIHByaW50IGxlc3MgdGhhbiAyNDAgY2hhcmFjdGVycyBmb3IKCQkgKiBpbmZvcm1hdGlvbiBhYm91dCBlYWNoIGxvZ2ljYWwgZHJpdmUuCgkJICovCgkJaWYoIChsZW4gKyAyNDApID49IFBBR0VfU0laRSApIGJyZWFrOwoKCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIkxvZ2ljYWwgZHJpdmU6JTJkOiwgIiwgaSk7CgoJCXN3aXRjaCggcmRydl9zdGF0ZVtpXSAmIDB4MEYgKSB7CgkJY2FzZSBSRFJWX09GRkxJTkU6CgkJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAic3RhdGU6IG9mZmxpbmUiKTsKCQkJYnJlYWs7CgoJCWNhc2UgUkRSVl9ERUdSQURFRDoKCQkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJzdGF0ZTogZGVncmFkZWQiKTsKCQkJYnJlYWs7CgoJCWNhc2UgUkRSVl9PUFRJTUFMOgoJCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgInN0YXRlOiBvcHRpbWFsIik7CgkJCWJyZWFrOwoKCQljYXNlIFJEUlZfREVMRVRFRDoKCQkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJzdGF0ZTogZGVsZXRlZCIpOwoJCQlicmVhazsKCgkJZGVmYXVsdDoKCQkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJzdGF0ZTogdW5rbm93biIpOwoJCQlicmVhazsKCQl9CgoJCS8qCgkJICogQ2hlY2sgaWYgY2hlY2sgY29uc2lzdGVuY3kgb3IgaW5pdGlhbGl6YXRpb24gaXMgZ29pbmcgb24KCQkgKiBmb3IgdGhpcyBsb2dpY2FsIGRyaXZlLgoJCSAqLwoJCWlmKCAocmRydl9zdGF0ZVtpXSAmIDB4RjApID09IDB4MjAgKSB7CgkJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLAoJCQkJCSIsIGNoZWNrLWNvbnNpc3RlbmN5IGluIHByb2dyZXNzIik7CgkJfQoJCWVsc2UgaWYoIChyZHJ2X3N0YXRlW2ldICYgMHhGMCkgPT0gMHgxMCApIHsKCQkJbGVuICs9IHNwcmludGYocGFnZStsZW4sCgkJCQkJIiwgaW5pdGlhbGl6YXRpb24gaW4gcHJvZ3Jlc3MiKTsKCQl9CgkJCgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJcbiIpOwoKCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIlNwYW4gZGVwdGg6JTNkLCAiLAoJCQkJbHBhcmFtLT5zcGFuX2RlcHRoKTsKCgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJSQUlEIGxldmVsOiUzZCwgIiwKCQkJCWxwYXJhbS0+bGV2ZWwpOwoKCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIlN0cmlwZSBzaXplOiUzZCwgIiwKCQkJCWxwYXJhbS0+c3RyaXBlX3N6ID8gbHBhcmFtLT5zdHJpcGVfc3ovMjogMTI4KTsKCgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJSb3cgc2l6ZTolM2RcbiIsCgkJCQlscGFyYW0tPnJvd19zaXplKTsKCgoJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiUmVhZCBQb2xpY3k6ICIpOwoKCQlzd2l0Y2gobHBhcmFtLT5yZWFkX2FoZWFkKSB7CgoJCWNhc2UgTk9fUkVBRF9BSEVBRDoKCQkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJObyByZWFkIGFoZWFkLCAiKTsKCQkJYnJlYWs7CgoJCWNhc2UgUkVBRF9BSEVBRDoKCQkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJSZWFkIGFoZWFkLCAiKTsKCQkJYnJlYWs7CgoJCWNhc2UgQURBUF9SRUFEX0FIRUFEOgoJCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIkFkYXB0aXZlLCAiKTsKCQkJYnJlYWs7CgoJCX0KCgkJbGVuICs9IHNwcmludGYocGFnZStsZW4sICJXcml0ZSBQb2xpY3k6ICIpOwoKCQlzd2l0Y2gobHBhcmFtLT53cml0ZV9tb2RlKSB7CgoJCWNhc2UgV1JNT0RFX1dSSVRFX1RIUlU6CgkJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiV3JpdGUgdGhydSwgIik7CgkJCWJyZWFrOwoKCQljYXNlIFdSTU9ERV9XUklURV9CQUNLOgoJCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIldyaXRlIGJhY2ssICIpOwoJCQlicmVhazsKCQl9CgoJCWxlbiArPSBzcHJpbnRmKHBhZ2UrbGVuLCAiQ2FjaGUgUG9saWN5OiAiKTsKCgkJc3dpdGNoKGxwYXJhbS0+ZGlyZWN0X2lvKSB7CgoJCWNhc2UgQ0FDSEVEX0lPOgoJCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIkNhY2hlZCBJT1xuXG4iKTsKCQkJYnJlYWs7CgoJCWNhc2UgRElSRUNUX0lPOgoJCQlsZW4gKz0gc3ByaW50ZihwYWdlK2xlbiwgIkRpcmVjdCBJT1xuXG4iKTsKCQkJYnJlYWs7CgkJfQoJfQoKCW1lZ2FfZnJlZV9pbnF1aXJ5KGlucXVpcnksIGRtYV9oYW5kbGUsIHBkZXYpOwoKCXBjaV9mcmVlX2NvbnNpc3RlbnQocGRldiwgYXJyYXlfc3osIGRpc2tfYXJyYXksCgkJCWRpc2tfYXJyYXlfZG1hX2hhbmRsZSk7CgoJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOwoKCXJldHVybiBsZW47Cn0KCiNlbmRpZgoKCi8qKgogKiBtZWdhcmFpZF9iaW9zcGFyYW0oKQogKgogKiBSZXR1cm4gdGhlIGRpc2sgZ2VvbWV0cnkgZm9yIGEgcGFydGljdWxhciBkaXNrCiAqLwpzdGF0aWMgaW50Cm1lZ2FyYWlkX2Jpb3NwYXJhbShzdHJ1Y3Qgc2NzaV9kZXZpY2UgKnNkZXYsIHN0cnVjdCBibG9ja19kZXZpY2UgKmJkZXYsCgkJICAgIHNlY3Rvcl90IGNhcGFjaXR5LCBpbnQgZ2VvbVtdKQp7CglhZGFwdGVyX3QJKmFkYXB0ZXI7Cgl1bnNpZ25lZCBjaGFyCSpiaDsKCWludAloZWFkczsKCWludAlzZWN0b3JzOwoJaW50CWN5bGluZGVyczsKCWludAlydmFsOwoKCS8qIEdldCBwb2ludGVyIHRvIGhvc3QgY29uZmlnIHN0cnVjdHVyZSAqLwoJYWRhcHRlciA9IChhZGFwdGVyX3QgKilzZGV2LT5ob3N0LT5ob3N0ZGF0YTsKCglpZiAoSVNfUkFJRF9DSChhZGFwdGVyLCBzZGV2LT5jaGFubmVsKSkgewoJCQkvKiBEZWZhdWx0IGhlYWRzICg2NCkgJiBzZWN0b3JzICgzMikgKi8KCQkJaGVhZHMgPSA2NDsKCQkJc2VjdG9ycyA9IDMyOwoJCQljeWxpbmRlcnMgPSAodWxvbmcpY2FwYWNpdHkgLyAoaGVhZHMgKiBzZWN0b3JzKTsKCgkJCS8qCgkJCSAqIEhhbmRsZSBleHRlbmRlZCB0cmFuc2xhdGlvbiBzaXplIGZvciBsb2dpY2FsIGRyaXZlcwoJCQkgKiA+IDFHYgoJCQkgKi8KCQkJaWYgKCh1bG9uZyljYXBhY2l0eSA+PSAweDIwMDAwMCkgewoJCQkJaGVhZHMgPSAyNTU7CgkJCQlzZWN0b3JzID0gNjM7CgkJCQljeWxpbmRlcnMgPSAodWxvbmcpY2FwYWNpdHkgLyAoaGVhZHMgKiBzZWN0b3JzKTsKCQkJfQoKCQkJLyogcmV0dXJuIHJlc3VsdCAqLwoJCQlnZW9tWzBdID0gaGVhZHM7CgkJCWdlb21bMV0gPSBzZWN0b3JzOwoJCQlnZW9tWzJdID0gY3lsaW5kZXJzOwoJfQoJZWxzZSB7CgkJYmggPSBzY3NpX2Jpb3NfcHRhYmxlKGJkZXYpOwoKCQlpZiggYmggKSB7CgkJCXJ2YWwgPSBzY3NpX3BhcnRzaXplKGJoLCBjYXBhY2l0eSwKCQkJCQkgICAgJmdlb21bMl0sICZnZW9tWzBdLCAmZ2VvbVsxXSk7CgkJCWtmcmVlKGJoKTsKCQkJaWYoIHJ2YWwgIT0gLTEgKQoJCQkJcmV0dXJuIHJ2YWw7CgkJfQoKCQlwcmludGsoS0VSTl9JTkZPCgkJIm1lZ2FyYWlkOiBpbnZhbGlkIHBhcnRpdGlvbiBvbiB0aGlzIGRpc2sgb24gY2hhbm5lbCAlZFxuIiwKCQkJCXNkZXYtPmNoYW5uZWwpOwoKCQkvKiBEZWZhdWx0IGhlYWRzICg2NCkgJiBzZWN0b3JzICgzMikgKi8KCQloZWFkcyA9IDY0OwoJCXNlY3RvcnMgPSAzMjsKCQljeWxpbmRlcnMgPSAodWxvbmcpY2FwYWNpdHkgLyAoaGVhZHMgKiBzZWN0b3JzKTsKCgkJLyogSGFuZGxlIGV4dGVuZGVkIHRyYW5zbGF0aW9uIHNpemUgZm9yIGxvZ2ljYWwgZHJpdmVzID4gMUdiICovCgkJaWYgKCh1bG9uZyljYXBhY2l0eSA+PSAweDIwMDAwMCkgewoJCQloZWFkcyA9IDI1NTsKCQkJc2VjdG9ycyA9IDYzOwoJCQljeWxpbmRlcnMgPSAodWxvbmcpY2FwYWNpdHkgLyAoaGVhZHMgKiBzZWN0b3JzKTsKCQl9CgoJCS8qIHJldHVybiByZXN1bHQgKi8KCQlnZW9tWzBdID0gaGVhZHM7CgkJZ2VvbVsxXSA9IHNlY3RvcnM7CgkJZ2VvbVsyXSA9IGN5bGluZGVyczsKCX0KCglyZXR1cm4gMDsKfQoKLyoqCiAqIG1lZ2FfaW5pdF9zY2IoKQogKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICoKICogQWxsb2NhdGUgbWVtb3J5IGZvciB0aGUgdmFyaW91cyBwb2ludGVycyBpbiB0aGUgc2NiIHN0cnVjdHVyZXM6CiAqIHNjYXR0ZXItZ2F0aGVyIGxpc3QgcG9pbnRlciwgcGFzc3RocnUgYW5kIGV4dGVuZGVkIHBhc3N0aHJ1IHN0cnVjdHVyZQogKiBwb2ludGVycy4KICovCnN0YXRpYyBpbnQKbWVnYV9pbml0X3NjYihhZGFwdGVyX3QgKmFkYXB0ZXIpCnsKCXNjYl90CSpzY2I7CglpbnQJaTsKCglmb3IoIGkgPSAwOyBpIDwgYWRhcHRlci0+bWF4X2NtZHM7IGkrKyApIHsKCgkJc2NiID0gJmFkYXB0ZXItPnNjYl9saXN0W2ldOwoKCQlzY2ItPnNnbDY0ID0gTlVMTDsKCQlzY2ItPnNnbCA9IE5VTEw7CgkJc2NiLT5wdGhydSA9IE5VTEw7CgkJc2NiLT5lcHRocnUgPSBOVUxMOwoJfQoKCWZvciggaSA9IDA7IGkgPCBhZGFwdGVyLT5tYXhfY21kczsgaSsrICkgewoKCQlzY2IgPSAmYWRhcHRlci0+c2NiX2xpc3RbaV07CgoJCXNjYi0+aWR4ID0gaTsKCgkJc2NiLT5zZ2w2NCA9IHBjaV9hbGxvY19jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwKCQkJCXNpemVvZihtZWdhX3NnbDY0KSAqIGFkYXB0ZXItPnNnbGVuLAoJCQkJJnNjYi0+c2dsX2RtYV9hZGRyKTsKCgkJc2NiLT5zZ2wgPSAobWVnYV9zZ2xpc3QgKilzY2ItPnNnbDY0OwoKCQlpZiggIXNjYi0+c2dsICkgewoJCQlwcmludGsoS0VSTl9XQVJOSU5HICJSQUlEOiBDYW4ndCBhbGxvY2F0ZSBzZ2xpc3QuXG4iKTsKCQkJbWVnYV9mcmVlX3NnbChhZGFwdGVyKTsKCQkJcmV0dXJuIC0xOwoJCX0KCgkJc2NiLT5wdGhydSA9IHBjaV9hbGxvY19jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwKCQkJCXNpemVvZihtZWdhX3Bhc3N0aHJ1KSwKCQkJCSZzY2ItPnB0aHJ1X2RtYV9hZGRyKTsKCgkJaWYoICFzY2ItPnB0aHJ1ICkgewoJCQlwcmludGsoS0VSTl9XQVJOSU5HICJSQUlEOiBDYW4ndCBhbGxvY2F0ZSBwYXNzdGhydS5cbiIpOwoJCQltZWdhX2ZyZWVfc2dsKGFkYXB0ZXIpOwoJCQlyZXR1cm4gLTE7CgkJfQoKCQlzY2ItPmVwdGhydSA9IHBjaV9hbGxvY19jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwKCQkJCXNpemVvZihtZWdhX2V4dF9wYXNzdGhydSksCgkJCQkmc2NiLT5lcHRocnVfZG1hX2FkZHIpOwoKCQlpZiggIXNjYi0+ZXB0aHJ1ICkgewoJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCQkiQ2FuJ3QgYWxsb2NhdGUgZXh0ZW5kZWQgcGFzc3RocnUuXG4iKTsKCQkJbWVnYV9mcmVlX3NnbChhZGFwdGVyKTsKCQkJcmV0dXJuIC0xOwoJCX0KCgoJCXNjYi0+ZG1hX3R5cGUgPSBNRUdBX0RNQV9UWVBFX05PTkU7CgoJCS8qCgkJICogTGluayB0byBmcmVlIGxpc3QKCQkgKiBsb2NrIG5vdCByZXF1aXJlZCBzaW5jZSB3ZSBhcmUgbG9hZGluZyB0aGUgZHJpdmVyLCBzbyBubwoJCSAqIGNvbW1hbmRzIHBvc3NpYmxlIHJpZ2h0IG5vdy4KCQkgKi8KCQlzY2ItPnN0YXRlID0gU0NCX0ZSRUU7CgkJc2NiLT5jbWQgPSBOVUxMOwoJCWxpc3RfYWRkKCZzY2ItPmxpc3QsICZhZGFwdGVyLT5mcmVlX2xpc3QpOwoJfQoKCXJldHVybiAwOwp9CgoKLyoqCiAqIG1lZ2FkZXZfb3BlbigpCiAqIEBpbm9kZSAtIHVudXNlZAogKiBAZmlsZXAgLSB1bnVzZWQKICoKICogUm91dGluZXMgZm9yIHRoZSBjaGFyYWN0ZXIvaW9jdGwgaW50ZXJmYWNlIHRvIHRoZSBkcml2ZXIuIEZpbmQgb3V0IGlmIHRoaXMKICogaXMgYSB2YWxpZCBvcGVuLiBJZiB5ZXMsIGluY3JlbWVudCB0aGUgbW9kdWxlIHVzZSBjb3VudCBzbyB0aGF0IGl0IGNhbm5vdAogKiBiZSB1bmxvYWRlZC4KICovCnN0YXRpYyBpbnQKbWVnYWRldl9vcGVuIChzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZXApCnsKCS8qCgkgKiBPbmx5IGFsbG93IHN1cGVydXNlciB0byBhY2Nlc3MgcHJpdmF0ZSBpb2N0bCBpbnRlcmZhY2UKCSAqLwoJaWYoICFjYXBhYmxlKENBUF9TWVNfQURNSU4pICkgcmV0dXJuIC1FQUNDRVM7CgoJcmV0dXJuIDA7Cn0KCgovKioKICogbWVnYWRldl9pb2N0bCgpCiAqIEBpbm9kZSAtIE91ciBkZXZpY2UgaW5vZGUKICogQGZpbGVwIC0gdW51c2VkCiAqIEBjbWQgLSBpb2N0bCBjb21tYW5kCiAqIEBhcmcgLSB1c2VyIGJ1ZmZlcgogKgogKiBpb2N0bCBlbnRyeSBwb2ludCBmb3Igb3VyIHByaXZhdGUgaW9jdGwgaW50ZXJmYWNlLiBXZSBtb3ZlIHRoZSBkYXRhIGluIGZyb20KICogdGhlIHVzZXIgc3BhY2UsIHByZXBhcmUgdGhlIGNvbW1hbmQgKGlmIG5lY2Vzc2FyeSwgY29udmVydCB0aGUgb2xkIE1JTUQKICogaW9jdGwgdG8gbmV3IGlvY3RsIGNvbW1hbmQpLCBhbmQgaXNzdWUgYSBzeW5jaHJvbm91cyBjb21tYW5kIHRvIHRoZQogKiBjb250cm9sbGVyLgogKi8Kc3RhdGljIGludAptZWdhZGV2X2lvY3RsKHN0cnVjdCBpbm9kZSAqaW5vZGUsIHN0cnVjdCBmaWxlICpmaWxlcCwgdW5zaWduZWQgaW50IGNtZCwKCQl1bnNpZ25lZCBsb25nIGFyZykKewoJYWRhcHRlcl90CSphZGFwdGVyOwoJbml0aW9jdGxfdAl1aW9jOwoJaW50CQlhZGFwbm87CglpbnQJCXJ2YWw7CgltZWdhX3Bhc3N0aHJ1CV9fdXNlciAqdXB0aHJ1OwkvKiB1c2VyIGFkZHJlc3MgZm9yIHBhc3N0aHJ1ICovCgltZWdhX3Bhc3N0aHJ1CSpwdGhydTsJCS8qIGNvcHkgdXNlciBwYXNzdGhydSBoZXJlICovCglkbWFfYWRkcl90CXB0aHJ1X2RtYV9obmRsOwoJdm9pZAkJKmRhdGEgPSBOVUxMOwkvKiBkYXRhIHRvIGJlIHRyYW5zZmVycmVkICovCglkbWFfYWRkcl90CWRhdGFfZG1hX2huZGw7CS8qIGRtYSBoYW5kbGUgZm9yIGRhdGEgeGZlciBhcmVhICovCgltZWdhY21kX3QJbWM7CgltZWdhc3RhdF90CV9fdXNlciAqdXN0YXRzOwoJaW50CQludW1fbGRydjsKCXUzMgkJdXhmZXJhZGRyID0gMDsKCXN0cnVjdCBwY2lfZGV2CSpwZGV2OwoKCXVzdGF0cyA9IE5VTEw7IC8qIGF2b2lkIGNvbXBpbGF0aW9uIHdhcm5pbmdzICovCgludW1fbGRydiA9IDA7CgoJLyoKCSAqIE1ha2Ugc3VyZSBvbmx5IFVTQ1NJQ01EIGFyZSBpc3N1ZWQgdGhyb3VnaCB0aGlzIGludGVyZmFjZS4KCSAqIE1JTUQgYXBwbGljYXRpb24gd291bGQgc3RpbGwgZmlyZSBkaWZmZXJlbnQgY29tbWFuZC4KCSAqLwoJaWYoIChfSU9DX1RZUEUoY21kKSAhPSBNRUdBSU9DX01BR0lDKSAmJiAoY21kICE9IFVTQ1NJQ01EKSApIHsKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCgkvKgoJICogQ2hlY2sgYW5kIGNvbnZlcnQgYSBwb3NzaWJsZSBNSU1EIGNvbW1hbmQgdG8gTklUIGNvbW1hbmQuCgkgKiBtZWdhX21fdG9fbigpIGNvcGllcyB0aGUgZGF0YSBmcm9tIHRoZSB1c2VyIHNwYWNlLCBzbyB3ZSBkbyBub3QKCSAqIGhhdmUgdG8gZG8gaXQgaGVyZS4KCSAqIE5PVEU6IFdlIHdpbGwgbmVlZCBzb21lIHVzZXIgYWRkcmVzcyB0byBjb3B5b3V0IHRoZSBkYXRhLCB0aGVyZWZvcmUKCSAqIHRoZSBpbnRlZmFjZSBsYXllciB3aWxsIGFsc28gcHJvdmlkZSB1cyB3aXRoIHRoZSByZXF1aXJlZCB1c2VyCgkgKiBhZGRyZXNzZXMuCgkgKi8KCW1lbXNldCgmdWlvYywgMCwgc2l6ZW9mKG5pdGlvY3RsX3QpKTsKCWlmKCAocnZhbCA9IG1lZ2FfbV90b19uKCAodm9pZCBfX3VzZXIgKilhcmcsICZ1aW9jKSkgIT0gMCApCgkJcmV0dXJuIHJ2YWw7CgoKCXN3aXRjaCggdWlvYy5vcGNvZGUgKSB7CgoJY2FzZSBHRVRfRFJJVkVSX1ZFUjoKCQlpZiggcHV0X3VzZXIoZHJpdmVyX3ZlciwgKHUzMiBfX3VzZXIgKil1aW9jLnVpb2NfdWFkZHIpICkKCQkJcmV0dXJuICgtRUZBVUxUKTsKCgkJYnJlYWs7CgoJY2FzZSBHRVRfTl9BREFQOgoJCWlmKCBwdXRfdXNlcihoYmFfY291bnQsICh1MzIgX191c2VyICopdWlvYy51aW9jX3VhZGRyKSApCgkJCXJldHVybiAoLUVGQVVMVCk7CgoJCS8qCgkJICogU2h1Y2tzLiBNSU1EIGludGVyZmFjZSByZXR1cm5zIGEgcG9zaXRpdmUgdmFsdWUgZm9yIG51bWJlcgoJCSAqIG9mIGFkYXB0ZXJzLiBUT0RPOiBDaGFuZ2UgaXQgdG8gcmV0dXJuIDAgd2hlbiB0aGVyZSBpcyBubwoJCSAqIGFwcGxpY2F0aW8gdXNpbmcgbWltZCBpbnRlcmZhY2UuCgkJICovCgkJcmV0dXJuIGhiYV9jb3VudDsKCgljYXNlIEdFVF9BREFQX0lORk86CgoJCS8qCgkJICogV2hpY2ggYWRhcHRlcgoJCSAqLwoJCWlmKCAoYWRhcG5vID0gR0VUQURBUCh1aW9jLmFkYXBubykpID49IGhiYV9jb3VudCApCgkJCXJldHVybiAoLUVOT0RFVik7CgoJCWlmKCBjb3B5X3RvX3VzZXIodWlvYy51aW9jX3VhZGRyLCBtY29udHJvbGxlcithZGFwbm8sCgkJCQlzaXplb2Yoc3RydWN0IG1jb250cm9sbGVyKSkgKQoJCQlyZXR1cm4gKC1FRkFVTFQpOwoJCWJyZWFrOwoKI2lmIE1FR0FfSEFWRV9TVEFUUwoKCWNhc2UgR0VUX1NUQVRTOgoJCS8qCgkJICogV2hpY2ggYWRhcHRlcgoJCSAqLwoJCWlmKCAoYWRhcG5vID0gR0VUQURBUCh1aW9jLmFkYXBubykpID49IGhiYV9jb3VudCApCgkJCXJldHVybiAoLUVOT0RFVik7CgoJCWFkYXB0ZXIgPSBoYmFfc29mdF9zdGF0ZVthZGFwbm9dOwoKCQl1c3RhdHMgPSB1aW9jLnVpb2NfdWFkZHI7CgoJCWlmKCBjb3B5X2Zyb21fdXNlcigmbnVtX2xkcnYsICZ1c3RhdHMtPm51bV9sZHJ2LCBzaXplb2YoaW50KSkgKQoJCQlyZXR1cm4gKC1FRkFVTFQpOwoKCQkvKgoJCSAqIENoZWNrIGZvciB0aGUgdmFsaWRpdHkgb2YgdGhlIGxvZ2ljYWwgZHJpdmUgbnVtYmVyCgkJICovCgkJaWYoIG51bV9sZHJ2ID49IE1BWF9MT0dJQ0FMX0RSSVZFU180MExEICkgcmV0dXJuIC1FSU5WQUw7CgoJCWlmKCBjb3B5X3RvX3VzZXIodXN0YXRzLT5ucmVhZHMsIGFkYXB0ZXItPm5yZWFkcywKCQkJCQludW1fbGRydipzaXplb2YodTMyKSkgKQoJCQlyZXR1cm4gLUVGQVVMVDsKCgkJaWYoIGNvcHlfdG9fdXNlcih1c3RhdHMtPm5yZWFkYmxvY2tzLCBhZGFwdGVyLT5ucmVhZGJsb2NrcywKCQkJCQludW1fbGRydipzaXplb2YodTMyKSkgKQoJCQlyZXR1cm4gLUVGQVVMVDsKCgkJaWYoIGNvcHlfdG9fdXNlcih1c3RhdHMtPm53cml0ZXMsIGFkYXB0ZXItPm53cml0ZXMsCgkJCQkJbnVtX2xkcnYqc2l6ZW9mKHUzMikpICkKCQkJcmV0dXJuIC1FRkFVTFQ7CgoJCWlmKCBjb3B5X3RvX3VzZXIodXN0YXRzLT5ud3JpdGVibG9ja3MsIGFkYXB0ZXItPm53cml0ZWJsb2NrcywKCQkJCQludW1fbGRydipzaXplb2YodTMyKSkgKQoJCQlyZXR1cm4gLUVGQVVMVDsKCgkJaWYoIGNvcHlfdG9fdXNlcih1c3RhdHMtPnJkX2Vycm9ycywgYWRhcHRlci0+cmRfZXJyb3JzLAoJCQkJCW51bV9sZHJ2KnNpemVvZih1MzIpKSApCgkJCXJldHVybiAtRUZBVUxUOwoKCQlpZiggY29weV90b191c2VyKHVzdGF0cy0+d3JfZXJyb3JzLCBhZGFwdGVyLT53cl9lcnJvcnMsCgkJCQkJbnVtX2xkcnYqc2l6ZW9mKHUzMikpICkKCQkJcmV0dXJuIC1FRkFVTFQ7CgoJCXJldHVybiAwOwoKI2VuZGlmCgljYXNlIE1CT1hfQ01EOgoKCQkvKgoJCSAqIFdoaWNoIGFkYXB0ZXIKCQkgKi8KCQlpZiggKGFkYXBubyA9IEdFVEFEQVAodWlvYy5hZGFwbm8pKSA+PSBoYmFfY291bnQgKQoJCQlyZXR1cm4gKC1FTk9ERVYpOwoKCQlhZGFwdGVyID0gaGJhX3NvZnRfc3RhdGVbYWRhcG5vXTsKCgkJLyoKCQkgKiBEZWxldGlvbiBvZiBsb2dpY2FsIGRyaXZlIGlzIGEgc3BlY2lhbCBjYXNlLiBUaGUgYWRhcHRlcgoJCSAqIHNob3VsZCBiZSBxdWllc2NlbnQgYmVmb3JlIHRoaXMgY29tbWFuZCBpcyBpc3N1ZWQuCgkJICovCgkJaWYoIHVpb2MudWlvY19ybWJveFswXSA9PSBGQ19ERUxfTE9HRFJWICYmCgkJCQl1aW9jLnVpb2Nfcm1ib3hbMl0gPT0gT1BfREVMX0xPR0RSViApIHsKCgkJCS8qCgkJCSAqIERvIHdlIHN1cHBvcnQgdGhpcyBmZWF0dXJlCgkJCSAqLwoJCQlpZiggIWFkYXB0ZXItPnN1cHBvcnRfcmFuZG9tX2RlbCApIHsKCQkJCXByaW50ayhLRVJOX1dBUk5JTkcgIm1lZ2FyYWlkOiBsb2dkcnYgIik7CgkJCQlwcmludGsoImRlbGV0ZSBvbiBub24tc3VwcG9ydGluZyBGL1cuXG4iKTsKCgkJCQlyZXR1cm4gKC1FSU5WQUwpOwoJCQl9CgoJCQlydmFsID0gbWVnYV9kZWxfbG9nZHJ2KCBhZGFwdGVyLCB1aW9jLnVpb2Nfcm1ib3hbM10gKTsKCgkJCWlmKCBydmFsID09IDAgKSB7CgkJCQltZW1zZXQoJm1jLCAwLCBzaXplb2YobWVnYWNtZF90KSk7CgoJCQkJbWMuc3RhdHVzID0gcnZhbDsKCgkJCQlydmFsID0gbWVnYV9uX3RvX20oKHZvaWQgX191c2VyICopYXJnLCAmbWMpOwoJCQl9CgoJCQlyZXR1cm4gcnZhbDsKCQl9CgkJLyoKCQkgKiBUaGlzIGludGVyZmFjZSBvbmx5IHN1cHBvcnQgdGhlIHJlZ3VsYXIgcGFzc3RocnUgY29tbWFuZHMuCgkJICogUmVqZWN0IGV4dGVuZGVkIHBhc3N0aHJ1IGFuZCA2NC1iaXQgcGFzc3RocnUKCQkgKi8KCQlpZiggdWlvYy51aW9jX3JtYm94WzBdID09IE1FR0FfTUJPWENNRF9QQVNTVEhSVTY0IHx8CgkJCXVpb2MudWlvY19ybWJveFswXSA9PSBNRUdBX01CT1hDTURfRVhUUFRIUlUgKSB7CgoJCQlwcmludGsoS0VSTl9XQVJOSU5HICJtZWdhcmFpZDogcmVqZWN0ZWQgcGFzc3RocnUuXG4iKTsKCgkJCXJldHVybiAoLUVJTlZBTCk7CgkJfQoKCQkvKgoJCSAqIEZvciBhbGwgaW50ZXJuYWwgY29tbWFuZHMsIHRoZSBidWZmZXIgbXVzdCBiZSBhbGxvY2F0ZWQgaW4KCQkgKiA8NEdCIGFkZHJlc3MgcmFuZ2UKCQkgKi8KCQlpZiggbWFrZV9sb2NhbF9wZGV2KGFkYXB0ZXIsICZwZGV2KSAhPSAwICkKCQkJcmV0dXJuIC1FSU87CgoJCS8qIElzIGl0IGEgcGFzc3RocnUgY29tbWFuZCBvciBhIERDTUQgKi8KCQlpZiggdWlvYy51aW9jX3JtYm94WzBdID09IE1FR0FfTUJPWENNRF9QQVNTVEhSVSApIHsKCQkJLyogUGFzc3RocnUgY29tbWFuZHMgKi8KCgkJCXB0aHJ1ID0gcGNpX2FsbG9jX2NvbnNpc3RlbnQocGRldiwKCQkJCQlzaXplb2YobWVnYV9wYXNzdGhydSksCgkJCQkJJnB0aHJ1X2RtYV9obmRsKTsKCgkJCWlmKCBwdGhydSA9PSBOVUxMICkgewoJCQkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOwoJCQkJcmV0dXJuICgtRU5PTUVNKTsKCQkJfQoKCQkJLyoKCQkJICogVGhlIHVzZXIgcGFzc3RocnUgc3RydWN0dXJlCgkJCSAqLwoJCQl1cHRocnUgPSAobWVnYV9wYXNzdGhydSBfX3VzZXIgKilNQk9YKHVpb2MpLT54ZmVyYWRkcjsKCgkJCS8qCgkJCSAqIENvcHkgaW4gdGhlIHVzZXIgcGFzc3RocnUgaGVyZS4KCQkJICovCgkJCWlmKCBjb3B5X2Zyb21fdXNlcihwdGhydSwgdXB0aHJ1LAoJCQkJCQlzaXplb2YobWVnYV9wYXNzdGhydSkpICkgewoKCQkJCXBjaV9mcmVlX2NvbnNpc3RlbnQocGRldiwKCQkJCQkJc2l6ZW9mKG1lZ2FfcGFzc3RocnUpLCBwdGhydSwKCQkJCQkJcHRocnVfZG1hX2huZGwpOwoKCQkJCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKCgkJCQlyZXR1cm4gKC1FRkFVTFQpOwoJCQl9CgoJCQkvKgoJCQkgKiBJcyB0aGVyZSBhIGRhdGEgdHJhbnNmZXIKCQkJICovCgkJCWlmKCBwdGhydS0+ZGF0YXhmZXJsZW4gKSB7CgkJCQlkYXRhID0gcGNpX2FsbG9jX2NvbnNpc3RlbnQocGRldiwKCQkJCQkJcHRocnUtPmRhdGF4ZmVybGVuLAoJCQkJCQkmZGF0YV9kbWFfaG5kbCk7CgoJCQkJaWYoIGRhdGEgPT0gTlVMTCApIHsKCQkJCQlwY2lfZnJlZV9jb25zaXN0ZW50KHBkZXYsCgkJCQkJCQlzaXplb2YobWVnYV9wYXNzdGhydSksCgkJCQkJCQlwdGhydSwKCQkJCQkJCXB0aHJ1X2RtYV9obmRsKTsKCgkJCQkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOwoKCQkJCQlyZXR1cm4gKC1FTk9NRU0pOwoJCQkJfQoKCQkJCS8qCgkJCQkgKiBTYXZlIHRoZSB1c2VyIGFkZHJlc3MgYW5kIHBvaW50IHRoZSBrZXJuZWwKCQkJCSAqIGFkZHJlc3MgYXQganVzdCBhbGxvY2F0ZWQgbWVtb3J5CgkJCQkgKi8KCQkJCXV4ZmVyYWRkciA9IHB0aHJ1LT5kYXRheGZlcmFkZHI7CgkJCQlwdGhydS0+ZGF0YXhmZXJhZGRyID0gZGF0YV9kbWFfaG5kbDsKCQkJfQoKCgkJCS8qCgkJCSAqIElzIGRhdGEgY29taW5nIGRvd24tc3RyZWFtCgkJCSAqLwoJCQlpZiggcHRocnUtPmRhdGF4ZmVybGVuICYmICh1aW9jLmZsYWdzICYgVUlPQ19XUikgKSB7CgkJCQkvKgoJCQkJICogR2V0IHRoZSB1c2VyIGRhdGEKCQkJCSAqLwoJCQkJaWYoIGNvcHlfZnJvbV91c2VyKGRhdGEsIChjaGFyIF9fdXNlciAqKXV4ZmVyYWRkciwKCQkJCQkJCXB0aHJ1LT5kYXRheGZlcmxlbikgKSB7CgkJCQkJcnZhbCA9ICgtRUZBVUxUKTsKCQkJCQlnb3RvIGZyZWVtZW1fYW5kX3JldHVybjsKCQkJCX0KCQkJfQoKCQkJbWVtc2V0KCZtYywgMCwgc2l6ZW9mKG1lZ2FjbWRfdCkpOwoKCQkJbWMuY21kID0gTUVHQV9NQk9YQ01EX1BBU1NUSFJVOwoJCQltYy54ZmVyYWRkciA9ICh1MzIpcHRocnVfZG1hX2huZGw7CgoJCQkvKgoJCQkgKiBJc3N1ZSB0aGUgY29tbWFuZAoJCQkgKi8KCQkJbWVnYV9pbnRlcm5hbF9jb21tYW5kKGFkYXB0ZXIsIExPQ0tfSU5ULCAmbWMsIHB0aHJ1KTsKCgkJCXJ2YWwgPSBtZWdhX25fdG9fbSgodm9pZCBfX3VzZXIgKilhcmcsICZtYyk7CgoJCQlpZiggcnZhbCApIGdvdG8gZnJlZW1lbV9hbmRfcmV0dXJuOwoKCgkJCS8qCgkJCSAqIElzIGRhdGEgZ29pbmcgdXAtc3RyZWFtCgkJCSAqLwoJCQlpZiggcHRocnUtPmRhdGF4ZmVybGVuICYmICh1aW9jLmZsYWdzICYgVUlPQ19SRCkgKSB7CgkJCQlpZiggY29weV90b191c2VyKChjaGFyIF9fdXNlciAqKXV4ZmVyYWRkciwgZGF0YSwKCQkJCQkJCXB0aHJ1LT5kYXRheGZlcmxlbikgKSB7CgkJCQkJcnZhbCA9ICgtRUZBVUxUKTsKCQkJCX0KCQkJfQoKCQkJLyoKCQkJICogU2VuZCB0aGUgcmVxdWVzdCBzZW5zZSBkYXRhIGFsc28sIGlycmVzcGVjdGl2ZSBvZgoJCQkgKiB3aGV0aGVyIHRoZSB1c2VyIGhhcyBhc2tlZCBmb3IgaXQgb3Igbm90LgoJCQkgKi8KCQkJY29weV90b191c2VyKHVwdGhydS0+cmVxc2Vuc2VhcmVhLAoJCQkJCXB0aHJ1LT5yZXFzZW5zZWFyZWEsIDE0KTsKCmZyZWVtZW1fYW5kX3JldHVybjoKCQkJaWYoIHB0aHJ1LT5kYXRheGZlcmxlbiApIHsKCQkJCXBjaV9mcmVlX2NvbnNpc3RlbnQocGRldiwKCQkJCQkJcHRocnUtPmRhdGF4ZmVybGVuLCBkYXRhLAoJCQkJCQlkYXRhX2RtYV9obmRsKTsKCQkJfQoKCQkJcGNpX2ZyZWVfY29uc2lzdGVudChwZGV2LCBzaXplb2YobWVnYV9wYXNzdGhydSksCgkJCQkJcHRocnUsIHB0aHJ1X2RtYV9obmRsKTsKCgkJCWZyZWVfbG9jYWxfcGRldihwZGV2KTsKCgkJCXJldHVybiBydmFsOwoJCX0KCQllbHNlIHsKCQkJLyogRENNRCBjb21tYW5kcyAqLwoKCQkJLyoKCQkJICogSXMgdGhlcmUgYSBkYXRhIHRyYW5zZmVyCgkJCSAqLwoJCQlpZiggdWlvYy54ZmVybGVuICkgewoJCQkJZGF0YSA9IHBjaV9hbGxvY19jb25zaXN0ZW50KHBkZXYsCgkJCQkJCXVpb2MueGZlcmxlbiwgJmRhdGFfZG1hX2huZGwpOwoKCQkJCWlmKCBkYXRhID09IE5VTEwgKSB7CgkJCQkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOwoJCQkJCXJldHVybiAoLUVOT01FTSk7CgkJCQl9CgoJCQkJdXhmZXJhZGRyID0gTUJPWCh1aW9jKS0+eGZlcmFkZHI7CgkJCX0KCgkJCS8qCgkJCSAqIElzIGRhdGEgY29taW5nIGRvd24tc3RyZWFtCgkJCSAqLwoJCQlpZiggdWlvYy54ZmVybGVuICYmICh1aW9jLmZsYWdzICYgVUlPQ19XUikgKSB7CgkJCQkvKgoJCQkJICogR2V0IHRoZSB1c2VyIGRhdGEKCQkJCSAqLwoJCQkJaWYoIGNvcHlfZnJvbV91c2VyKGRhdGEsIChjaGFyIF9fdXNlciAqKXV4ZmVyYWRkciwKCQkJCQkJCXVpb2MueGZlcmxlbikgKSB7CgoJCQkJCXBjaV9mcmVlX2NvbnNpc3RlbnQocGRldiwKCQkJCQkJCXVpb2MueGZlcmxlbiwKCQkJCQkJCWRhdGEsIGRhdGFfZG1hX2huZGwpOwoKCQkJCQlmcmVlX2xvY2FsX3BkZXYocGRldik7CgoJCQkJCXJldHVybiAoLUVGQVVMVCk7CgkJCQl9CgkJCX0KCgkJCW1lbWNweSgmbWMsIE1CT1godWlvYyksIHNpemVvZihtZWdhY21kX3QpKTsKCgkJCW1jLnhmZXJhZGRyID0gKHUzMilkYXRhX2RtYV9obmRsOwoKCQkJLyoKCQkJICogSXNzdWUgdGhlIGNvbW1hbmQKCQkJICovCgkJCW1lZ2FfaW50ZXJuYWxfY29tbWFuZChhZGFwdGVyLCBMT0NLX0lOVCwgJm1jLCBOVUxMKTsKCgkJCXJ2YWwgPSBtZWdhX25fdG9fbSgodm9pZCBfX3VzZXIgKilhcmcsICZtYyk7CgoJCQlpZiggcnZhbCApIHsKCQkJCWlmKCB1aW9jLnhmZXJsZW4gKSB7CgkJCQkJcGNpX2ZyZWVfY29uc2lzdGVudChwZGV2LAoJCQkJCQkJdWlvYy54ZmVybGVuLCBkYXRhLAoJCQkJCQkJZGF0YV9kbWFfaG5kbCk7CgkJCQl9CgoJCQkJZnJlZV9sb2NhbF9wZGV2KHBkZXYpOwoKCQkJCXJldHVybiBydmFsOwoJCQl9CgoJCQkvKgoJCQkgKiBJcyBkYXRhIGdvaW5nIHVwLXN0cmVhbQoJCQkgKi8KCQkJaWYoIHVpb2MueGZlcmxlbiAmJiAodWlvYy5mbGFncyAmIFVJT0NfUkQpICkgewoJCQkJaWYoIGNvcHlfdG9fdXNlcigoY2hhciBfX3VzZXIgKil1eGZlcmFkZHIsIGRhdGEsCgkJCQkJCQl1aW9jLnhmZXJsZW4pICkgewoKCQkJCQlydmFsID0gKC1FRkFVTFQpOwoJCQkJfQoJCQl9CgoJCQlpZiggdWlvYy54ZmVybGVuICkgewoJCQkJcGNpX2ZyZWVfY29uc2lzdGVudChwZGV2LAoJCQkJCQl1aW9jLnhmZXJsZW4sIGRhdGEsCgkJCQkJCWRhdGFfZG1hX2huZGwpOwoJCQl9CgoJCQlmcmVlX2xvY2FsX3BkZXYocGRldik7CgoJCQlyZXR1cm4gcnZhbDsKCQl9CgoJZGVmYXVsdDoKCQlyZXR1cm4gKC1FSU5WQUwpOwoJfQoKCXJldHVybiAwOwp9CgovKioKICogbWVnYV9tX3RvX24oKQogKiBAYXJnIC0gdXNlciBhZGRyZXNzCiAqIEB1aW9jIC0gbmV3IGlvY3RsIHN0cnVjdHVyZQogKgogKiBBIHRoaW4gbGF5ZXIgdG8gY29udmVydCBvbGRlciBtaW1kIGludGVyZmFjZSBpb2N0bCBzdHJ1Y3R1cmUgdG8gTklUIGlvY3RsCiAqIHN0cnVjdHVyZQogKgogKiBDb252ZXJ0cyB0aGUgb2xkZXIgbWltZCBpb2N0bCBzdHJ1Y3R1cmUgdG8gbmV3ZXIgTklUIHN0cnVjdHVyZQogKi8Kc3RhdGljIGludAptZWdhX21fdG9fbih2b2lkIF9fdXNlciAqYXJnLCBuaXRpb2N0bF90ICp1aW9jKQp7CglzdHJ1Y3QgdWlvY3RsX3QJdWlvY19taW1kOwoJY2hhcglzaWduYXR1cmVbOF0gPSB7MH07Cgl1OAlvcGNvZGU7Cgl1OAlzdWJvcGNvZGU7CgoKCS8qCgkgKiBjaGVjayBpcyB0aGUgYXBwbGljYXRpb24gY29uZm9ybXMgdG8gTklULiBXZSBkbyBub3QgaGF2ZSB0byBkbyBtdWNoCgkgKiBpbiB0aGF0IGNhc2UuCgkgKiBXZSBleHBsb2l0IHRoZSBmYWN0IHRoYXQgdGhlIHNpZ25hdHVyZSBpcyBzdG9yZWQgaW4gdGhlIHZlcnkKCSAqIGJlZ2luaW5nIG9mIHRoZSBzdHJ1Y3R1cmUuCgkgKi8KCglpZiggY29weV9mcm9tX3VzZXIoc2lnbmF0dXJlLCBhcmcsIDcpICkKCQlyZXR1cm4gKC1FRkFVTFQpOwoKCWlmKCBtZW1jbXAoc2lnbmF0dXJlLCAiTUVHQU5JVCIsIDcpID09IDAgKSB7CgoJCS8qCgkJICogTk9URSBOT1RFOiBUaGUgbml0IGlvY3RsIGlzIHN0aWxsIHVuZGVyIGZsdXggYmVjYXVzZSBvZgoJCSAqIGNoYW5nZSBvZiBtYWlsYm94IGRlZmluaXRpb24sIGluIEhQRS4gTm8gYXBwbGljYXRpb25zIHlldAoJCSAqIHVzZSB0aGlzIGludGVyZmFjZSBhbmQgbGV0J3Mgbm90IGhhdmUgYXBwbGljYXRpb25zIHVzZSB0aGlzCgkJICogaW50ZXJmYWNlIHRpbGwgdGhlIG5ldyBzcGVjaWZpdGlvbnMgYXJlIGluIHBsYWNlLgoJCSAqLwoJCXJldHVybiAtRUlOVkFMOwojaWYgMAoJCWlmKCBjb3B5X2Zyb21fdXNlcih1aW9jLCBhcmcsIHNpemVvZihuaXRpb2N0bF90KSkgKQoJCQlyZXR1cm4gKC1FRkFVTFQpOwoJCXJldHVybiAwOwojZW5kaWYKCX0KCgkvKgoJICogRWxzZSBhc3N1bWUgd2UgaGF2ZSBtaW1kIHVpb2N0bF90IGFzIGFyZy4gQ29udmVydCB0byBuaXRpb2N0bF90CgkgKgoJICogR2V0IHRoZSB1c2VyIGlvY3RsIHN0cnVjdHVyZQoJICovCglpZiggY29weV9mcm9tX3VzZXIoJnVpb2NfbWltZCwgYXJnLCBzaXplb2Yoc3RydWN0IHVpb2N0bF90KSkgKQoJCXJldHVybiAoLUVGQVVMVCk7CgoKCS8qCgkgKiBHZXQgdGhlIG9wY29kZSBhbmQgc3Vib3Bjb2RlIGZvciB0aGUgY29tbWFuZHMKCSAqLwoJb3Bjb2RlID0gdWlvY19taW1kLnVpLmZjcy5vcGNvZGU7CglzdWJvcGNvZGUgPSB1aW9jX21pbWQudWkuZmNzLnN1Ym9wY29kZTsKCglzd2l0Y2ggKG9wY29kZSkgewoJY2FzZSAweDgyOgoKCQlzd2l0Y2ggKHN1Ym9wY29kZSkgewoKCQljYXNlIE1FR0FJT0NfUURSVlJWRVI6CS8qIFF1ZXJ5IGRyaXZlciB2ZXJzaW9uICovCgkJCXVpb2MtPm9wY29kZSA9IEdFVF9EUklWRVJfVkVSOwoJCQl1aW9jLT51aW9jX3VhZGRyID0gdWlvY19taW1kLmRhdGE7CgkJCWJyZWFrOwoKCQljYXNlIE1FR0FJT0NfUU5BREFQOgkvKiBHZXQgIyBvZiBhZGFwdGVycyAqLwoJCQl1aW9jLT5vcGNvZGUgPSBHRVRfTl9BREFQOwoJCQl1aW9jLT51aW9jX3VhZGRyID0gdWlvY19taW1kLmRhdGE7CgkJCWJyZWFrOwoKCQljYXNlIE1FR0FJT0NfUUFEQVBJTkZPOgkvKiBHZXQgYWRhcHRlciBpbmZvcm1hdGlvbiAqLwoJCQl1aW9jLT5vcGNvZGUgPSBHRVRfQURBUF9JTkZPOwoJCQl1aW9jLT5hZGFwbm8gPSB1aW9jX21pbWQudWkuZmNzLmFkYXBubzsKCQkJdWlvYy0+dWlvY191YWRkciA9IHVpb2NfbWltZC5kYXRhOwoJCQlicmVhazsKCgkJZGVmYXVsdDoKCQkJcmV0dXJuKC1FSU5WQUwpOwoJCX0KCgkJYnJlYWs7CgoKCWNhc2UgMHg4MToKCgkJdWlvYy0+b3Bjb2RlID0gTUJPWF9DTUQ7CgkJdWlvYy0+YWRhcG5vID0gdWlvY19taW1kLnVpLmZjcy5hZGFwbm87CgoJCW1lbWNweSh1aW9jLT51aW9jX3JtYm94LCB1aW9jX21pbWQubWJveCwgMTgpOwoKCQl1aW9jLT54ZmVybGVuID0gdWlvY19taW1kLnVpLmZjcy5sZW5ndGg7CgoJCWlmKCB1aW9jX21pbWQub3V0bGVuICkgdWlvYy0+ZmxhZ3MgPSBVSU9DX1JEOwoJCWlmKCB1aW9jX21pbWQuaW5sZW4gKSB1aW9jLT5mbGFncyB8PSBVSU9DX1dSOwoKCQlicmVhazsKCgljYXNlIDB4ODA6CgoJCXVpb2MtPm9wY29kZSA9IE1CT1hfQ01EOwoJCXVpb2MtPmFkYXBubyA9IHVpb2NfbWltZC51aS5mY3MuYWRhcG5vOwoKCQltZW1jcHkodWlvYy0+dWlvY19ybWJveCwgdWlvY19taW1kLm1ib3gsIDE4KTsKCgkJLyoKCQkgKiBDaG9vc2UgdGhlIHhmZXJsZW4gYmlnZ2VyIG9mIGlucHV0IGFuZCBvdXRwdXQgZGF0YQoJCSAqLwoJCXVpb2MtPnhmZXJsZW4gPSB1aW9jX21pbWQub3V0bGVuID4gdWlvY19taW1kLmlubGVuID8KCQkJdWlvY19taW1kLm91dGxlbiA6IHVpb2NfbWltZC5pbmxlbjsKCgkJaWYoIHVpb2NfbWltZC5vdXRsZW4gKSB1aW9jLT5mbGFncyA9IFVJT0NfUkQ7CgkJaWYoIHVpb2NfbWltZC5pbmxlbiApIHVpb2MtPmZsYWdzIHw9IFVJT0NfV1I7CgoJCWJyZWFrOwoKCWRlZmF1bHQ6CgkJcmV0dXJuICgtRUlOVkFMKTsKCgl9CgoJcmV0dXJuIDA7Cn0KCi8qCiAqIG1lZ2Ffbl90b19tKCkKICogQGFyZyAtIHVzZXIgYWRkcmVzcwogKiBAbWMgLSBtYWlsYm94IGNvbW1hbmQKICoKICogVXBkYXRlcyB0aGUgc3RhdHVzIGluZm9ybWF0aW9uIHRvIHRoZSBhcHBsaWNhdGlvbiwgZGVwZW5kaW5nIG9uIGFwcGxpY2F0aW9uCiAqIGNvbmZvcm1zIHRvIG9sZGVyIG1pbWQgaW9jdGwgaW50ZXJmYWNlIG9yIG5ld2VyIE5JVCBpb2N0bCBpbnRlcmZhY2UKICovCnN0YXRpYyBpbnQKbWVnYV9uX3RvX20odm9pZCBfX3VzZXIgKmFyZywgbWVnYWNtZF90ICptYykKewoJbml0aW9jdGxfdAlfX3VzZXIgKnVpb2NwOwoJbWVnYWNtZF90CV9fdXNlciAqdW1jOwoJbWVnYV9wYXNzdGhydQlfX3VzZXIgKnVwdGhydTsKCXN0cnVjdCB1aW9jdGxfdAlfX3VzZXIgKnVpb2NfbWltZDsKCWNoYXIJc2lnbmF0dXJlWzhdID0gezB9OwoKCS8qCgkgKiBjaGVjayBpcyB0aGUgYXBwbGljYXRpb24gY29uZm9ybXMgdG8gTklULgoJICovCglpZiggY29weV9mcm9tX3VzZXIoc2lnbmF0dXJlLCBhcmcsIDcpICkKCQlyZXR1cm4gLUVGQVVMVDsKCglpZiggbWVtY21wKHNpZ25hdHVyZSwgIk1FR0FOSVQiLCA3KSA9PSAwICkgewoKCQl1aW9jcCA9IGFyZzsKCgkJaWYoIHB1dF91c2VyKG1jLT5zdGF0dXMsICh1OCBfX3VzZXIgKikmTUJPWF9QKHVpb2NwKS0+c3RhdHVzKSApCgkJCXJldHVybiAoLUVGQVVMVCk7CgoJCWlmKCBtYy0+Y21kID09IE1FR0FfTUJPWENNRF9QQVNTVEhSVSApIHsKCgkJCXVtYyA9IE1CT1hfUCh1aW9jcCk7CgoJCQlpZiAoZ2V0X3VzZXIodXB0aHJ1LCAobWVnYV9wYXNzdGhydSBfX3VzZXIgKiBfX3VzZXIgKikmdW1jLT54ZmVyYWRkcikpCgkJCQlyZXR1cm4gLUVGQVVMVDsKCgkJCWlmKCBwdXRfdXNlcihtYy0+c3RhdHVzLCAodTggX191c2VyICopJnVwdGhydS0+c2NzaXN0YXR1cykpCgkJCQlyZXR1cm4gKC1FRkFVTFQpOwoJCX0KCX0KCWVsc2UgewoJCXVpb2NfbWltZCA9IGFyZzsKCgkJaWYoIHB1dF91c2VyKG1jLT5zdGF0dXMsICh1OCBfX3VzZXIgKikmdWlvY19taW1kLT5tYm94WzE3XSkgKQoJCQlyZXR1cm4gKC1FRkFVTFQpOwoKCQlpZiggbWMtPmNtZCA9PSBNRUdBX01CT1hDTURfUEFTU1RIUlUgKSB7CgoJCQl1bWMgPSAobWVnYWNtZF90IF9fdXNlciAqKXVpb2NfbWltZC0+bWJveDsKCgkJCWlmIChnZXRfdXNlcih1cHRocnUsIChtZWdhX3Bhc3N0aHJ1IF9fdXNlciAqIF9fdXNlciAqKSZ1bWMtPnhmZXJhZGRyKSkKCQkJCXJldHVybiAoLUVGQVVMVCk7CgoJCQlpZiggcHV0X3VzZXIobWMtPnN0YXR1cywgKHU4IF9fdXNlciAqKSZ1cHRocnUtPnNjc2lzdGF0dXMpICkKCQkJCXJldHVybiAoLUVGQVVMVCk7CgkJfQoJfQoKCXJldHVybiAwOwp9CgoKLyoKICogTUVHQVJBSUQgJ0ZXJyBjb21tYW5kcy4KICovCgovKioKICogbWVnYV9pc19iaW9zX2VuYWJsZWQoKQogKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICoKICogaXNzdWUgY29tbWFuZCB0byBmaW5kIG91dCBpZiB0aGUgQklPUyBpcyBlbmFibGVkIGZvciB0aGlzIGNvbnRyb2xsZXIKICovCnN0YXRpYyBpbnQKbWVnYV9pc19iaW9zX2VuYWJsZWQoYWRhcHRlcl90ICphZGFwdGVyKQp7Cgl1bnNpZ25lZCBjaGFyCXJhd19tYm94W3NpemVvZihzdHJ1Y3QgbWJveF9vdXQpXTsKCW1ib3hfdAkqbWJveDsKCWludAlyZXQ7CgoJbWJveCA9IChtYm94X3QgKilyYXdfbWJveDsKCgltZW1zZXQoJm1ib3gtPm1fb3V0LCAwLCBzaXplb2YocmF3X21ib3gpKTsKCgltZW1zZXQoKHZvaWQgKilhZGFwdGVyLT5tZWdhX2J1ZmZlciwgMCwgTUVHQV9CVUZGRVJfU0laRSk7CgoJbWJveC0+bV9vdXQueGZlcmFkZHIgPSAodTMyKWFkYXB0ZXItPmJ1Zl9kbWFfaGFuZGxlOwoKCXJhd19tYm94WzBdID0gSVNfQklPU19FTkFCTEVEOwoJcmF3X21ib3hbMl0gPSBHRVRfQklPUzsKCgoJcmV0ID0gaXNzdWVfc2NiX2Jsb2NrKGFkYXB0ZXIsIHJhd19tYm94KTsKCglyZXR1cm4gKihjaGFyICopYWRhcHRlci0+bWVnYV9idWZmZXI7Cn0KCgovKioKICogbWVnYV9lbnVtX3JhaWRfc2NzaSgpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBGaW5kIG91dCB3aGF0IGNoYW5uZWxzIGFyZSBSQUlEL1NDU0kuIFRoaXMgaW5mb3JtYXRpb24gaXMgdXNlZCB0bwogKiBkaWZmZXJlbnRpYXRlIHRoZSB2aXJ0dWFsIGNoYW5uZWxzIGFuZCBwaHlzaWNhbCBjaGFubmVscyBhbmQgdG8gc3VwcG9ydAogKiBST01CIGZlYXR1cmUgYW5kIG5vbi1kaXNrIGRldmljZXMuCiAqLwpzdGF0aWMgdm9pZAptZWdhX2VudW1fcmFpZF9zY3NpKGFkYXB0ZXJfdCAqYWRhcHRlcikKewoJdW5zaWduZWQgY2hhciByYXdfbWJveFtzaXplb2Yoc3RydWN0IG1ib3hfb3V0KV07CgltYm94X3QgKm1ib3g7CglpbnQgaTsKCgltYm94ID0gKG1ib3hfdCAqKXJhd19tYm94OwoKCW1lbXNldCgmbWJveC0+bV9vdXQsIDAsIHNpemVvZihyYXdfbWJveCkpOwoKCS8qCgkgKiBpc3N1ZSBjb21tYW5kIHRvIGZpbmQgb3V0IHdoYXQgY2hhbm5lbHMgYXJlIHJhaWQvc2NzaQoJICovCglyYXdfbWJveFswXSA9IENITkxfQ0xBU1M7CglyYXdfbWJveFsyXSA9IEdFVF9DSE5MX0NMQVNTOwoKCW1lbXNldCgodm9pZCAqKWFkYXB0ZXItPm1lZ2FfYnVmZmVyLCAwLCBNRUdBX0JVRkZFUl9TSVpFKTsKCgltYm94LT5tX291dC54ZmVyYWRkciA9ICh1MzIpYWRhcHRlci0+YnVmX2RtYV9oYW5kbGU7CgoJLyoKCSAqIE5vbi1ST01CIGZpcm13YXJlIGZhaWwgdGhpcyBjb21tYW5kLCBzbyBhbGwgY2hhbm5lbHMKCSAqIG11c3QgYmUgc2hvd24gUkFJRAoJICovCglhZGFwdGVyLT5tZWdhX2NoX2NsYXNzID0gMHhGRjsKCglpZighaXNzdWVfc2NiX2Jsb2NrKGFkYXB0ZXIsIHJhd19tYm94KSkgewoJCWFkYXB0ZXItPm1lZ2FfY2hfY2xhc3MgPSAqKChjaGFyICopYWRhcHRlci0+bWVnYV9idWZmZXIpOwoKCX0KCglmb3IoIGkgPSAwOyBpIDwgYWRhcHRlci0+cHJvZHVjdF9pbmZvLm5jaGFubmVsczsgaSsrICkgeyAKCQlpZiggKGFkYXB0ZXItPm1lZ2FfY2hfY2xhc3MgPj4gaSkgJiAweDAxICkgewoJCQlwcmludGsoS0VSTl9JTkZPICJtZWdhcmFpZDogY2hhbm5lbFslZF0gaXMgcmFpZC5cbiIsCgkJCQkJaSk7CgkJfQoJCWVsc2UgewoJCQlwcmludGsoS0VSTl9JTkZPICJtZWdhcmFpZDogY2hhbm5lbFslZF0gaXMgc2NzaS5cbiIsCgkJCQkJaSk7CgkJfQoJfQoKCXJldHVybjsKfQoKCi8qKgogKiBtZWdhX2dldF9ib290X2RydigpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBGaW5kIG91dCB3aGljaCBkZXZpY2UgaXMgdGhlIGJvb3QgZGV2aWNlLiBOb3RlLCBhbnkgbG9naWNhbCBkcml2ZSBvciBhbnkKICogcGh5aWNhbCBkZXZpY2UgKGUuZy4sIGEgQ0RST00pIGNhbiBiZSBkZXNpZ25hdGVkIGFzIGEgYm9vdCBkZXZpY2UuCiAqLwpzdGF0aWMgdm9pZAptZWdhX2dldF9ib290X2RydihhZGFwdGVyX3QgKmFkYXB0ZXIpCnsKCXN0cnVjdCBwcml2YXRlX2Jpb3NfZGF0YQkqcHJ2X2Jpb3NfZGF0YTsKCXVuc2lnbmVkIGNoYXIJcmF3X21ib3hbc2l6ZW9mKHN0cnVjdCBtYm94X291dCldOwoJbWJveF90CSptYm94OwoJdTE2CWNrc3VtID0gMDsKCXU4CSpja3N1bV9wOwoJdTgJYm9vdF9wZHJ2OwoJaW50CWk7CgoJbWJveCA9IChtYm94X3QgKilyYXdfbWJveDsKCgltZW1zZXQoJm1ib3gtPm1fb3V0LCAwLCBzaXplb2YocmF3X21ib3gpKTsKCglyYXdfbWJveFswXSA9IEJJT1NfUFZUX0RBVEE7CglyYXdfbWJveFsyXSA9IEdFVF9CSU9TX1BWVF9EQVRBOwoKCW1lbXNldCgodm9pZCAqKWFkYXB0ZXItPm1lZ2FfYnVmZmVyLCAwLCBNRUdBX0JVRkZFUl9TSVpFKTsKCgltYm94LT5tX291dC54ZmVyYWRkciA9ICh1MzIpYWRhcHRlci0+YnVmX2RtYV9oYW5kbGU7CgoJYWRhcHRlci0+Ym9vdF9sZHJ2X2VuYWJsZWQgPSAwOwoJYWRhcHRlci0+Ym9vdF9sZHJ2ID0gMDsKCglhZGFwdGVyLT5ib290X3BkcnZfZW5hYmxlZCA9IDA7CglhZGFwdGVyLT5ib290X3BkcnZfY2ggPSAwOwoJYWRhcHRlci0+Ym9vdF9wZHJ2X3RndCA9IDA7CgoJaWYoaXNzdWVfc2NiX2Jsb2NrKGFkYXB0ZXIsIHJhd19tYm94KSA9PSAwKSB7CgkJcHJ2X2Jpb3NfZGF0YSA9CgkJCShzdHJ1Y3QgcHJpdmF0ZV9iaW9zX2RhdGEgKilhZGFwdGVyLT5tZWdhX2J1ZmZlcjsKCgkJY2tzdW0gPSAwOwoJCWNrc3VtX3AgPSAoY2hhciAqKXBydl9iaW9zX2RhdGE7CgkJZm9yIChpID0gMDsgaSA8IDE0OyBpKysgKSB7CgkJCWNrc3VtICs9ICh1MTYpKCpja3N1bV9wKyspOwoJCX0KCgkJaWYgKHBydl9iaW9zX2RhdGEtPmNrc3VtID09ICh1MTYpKDAtY2tzdW0pICkgewoKCQkJLyoKCQkJICogSWYgTVNCIGlzIHNldCwgYSBwaHlzaWNhbCBkcml2ZSBpcyBzZXQgYXMgYm9vdAoJCQkgKiBkZXZpY2UKCQkJICovCgkJCWlmKCBwcnZfYmlvc19kYXRhLT5ib290X2RydiAmIDB4ODAgKSB7CgkJCQlhZGFwdGVyLT5ib290X3BkcnZfZW5hYmxlZCA9IDE7CgkJCQlib290X3BkcnYgPSBwcnZfYmlvc19kYXRhLT5ib290X2RydiAmIDB4N0Y7CgkJCQlhZGFwdGVyLT5ib290X3BkcnZfY2ggPSBib290X3BkcnYgLyAxNjsKCQkJCWFkYXB0ZXItPmJvb3RfcGRydl90Z3QgPSBib290X3BkcnYgJSAxNjsKCQkJfQoJCQllbHNlIHsKCQkJCWFkYXB0ZXItPmJvb3RfbGRydl9lbmFibGVkID0gMTsKCQkJCWFkYXB0ZXItPmJvb3RfbGRydiA9IHBydl9iaW9zX2RhdGEtPmJvb3RfZHJ2OwoJCQl9CgkJfQoJfQoKfQoKLyoqCiAqIG1lZ2Ffc3VwcG9ydF9yYW5kb21fZGVsKCkKICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqCiAqIEZpbmQgb3V0IGlmIHRoaXMgY29udHJvbGxlciBzdXBwb3J0cyByYW5kb20gZGVsZXRpb24gYW5kIGFkZGl0aW9uIG9mCiAqIGxvZ2ljYWwgZHJpdmVzCiAqLwpzdGF0aWMgaW50Cm1lZ2Ffc3VwcG9ydF9yYW5kb21fZGVsKGFkYXB0ZXJfdCAqYWRhcHRlcikKewoJdW5zaWduZWQgY2hhciByYXdfbWJveFtzaXplb2Yoc3RydWN0IG1ib3hfb3V0KV07CgltYm94X3QgKm1ib3g7CglpbnQgcnZhbDsKCgltYm94ID0gKG1ib3hfdCAqKXJhd19tYm94OwoKCW1lbXNldCgmbWJveC0+bV9vdXQsIDAsIHNpemVvZihyYXdfbWJveCkpOwoKCS8qCgkgKiBpc3N1ZSBjb21tYW5kCgkgKi8KCXJhd19tYm94WzBdID0gRkNfREVMX0xPR0RSVjsKCXJhd19tYm94WzJdID0gT1BfU1VQX0RFTF9MT0dEUlY7CgoJcnZhbCA9IGlzc3VlX3NjYl9ibG9jayhhZGFwdGVyLCByYXdfbWJveCk7CgoJcmV0dXJuICFydmFsOwp9CgoKLyoqCiAqIG1lZ2Ffc3VwcG9ydF9leHRfY2RiKCkKICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqCiAqIEZpbmQgb3V0IGlmIHRoaXMgZmlybXdhcmUgc3VwcG9ydCBjZGJsZW4gPiAxMAogKi8Kc3RhdGljIGludAptZWdhX3N1cHBvcnRfZXh0X2NkYihhZGFwdGVyX3QgKmFkYXB0ZXIpCnsKCXVuc2lnbmVkIGNoYXIgcmF3X21ib3hbc2l6ZW9mKHN0cnVjdCBtYm94X291dCldOwoJbWJveF90ICptYm94OwoJaW50IHJ2YWw7CgoJbWJveCA9IChtYm94X3QgKilyYXdfbWJveDsKCgltZW1zZXQoJm1ib3gtPm1fb3V0LCAwLCBzaXplb2YocmF3X21ib3gpKTsKCS8qCgkgKiBpc3N1ZSBjb21tYW5kIHRvIGZpbmQgb3V0IGlmIGNvbnRyb2xsZXIgc3VwcG9ydHMgZXh0ZW5kZWQgQ0RCcy4KCSAqLwoJcmF3X21ib3hbMF0gPSAweEE0OwoJcmF3X21ib3hbMl0gPSAweDE2OwoKCXJ2YWwgPSBpc3N1ZV9zY2JfYmxvY2soYWRhcHRlciwgcmF3X21ib3gpOwoKCXJldHVybiAhcnZhbDsKfQoKCi8qKgogKiBtZWdhX2RlbF9sb2dkcnYoKQogKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICogQGxvZ2RydiAtIGxvZ2ljYWwgZHJpdmUgdG8gYmUgZGVsZXRlZAogKgogKiBEZWxldGUgdGhlIHNwZWNpZmllZCBsb2dpY2FsIGRyaXZlLiBJdCBpcyB0aGUgcmVzcG9uc2liaWxpdHkgb2YgdGhlIHVzZXIKICogYXBwIHRvIGxldCB0aGUgT1Mga25vdyBhYm91dCB0aGlzIG9wZXJhdGlvbi4KICovCnN0YXRpYyBpbnQKbWVnYV9kZWxfbG9nZHJ2KGFkYXB0ZXJfdCAqYWRhcHRlciwgaW50IGxvZ2RydikKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCXNjYl90ICpzY2I7CglpbnQgcnZhbDsKCgkvKgoJICogU3RvcCBzZW5kaW5nIGNvbW1hbmRzIHRvIHRoZSBjb250cm9sbGVyLCBxdWV1ZSB0aGVtIGludGVybmFsbHkuCgkgKiBXaGVuIGRlbGV0aW9uIGlzIGNvbXBsZXRlLCBJU1Igd2lsbCBmbHVzaCB0aGUgcXVldWUuCgkgKi8KCWF0b21pY19zZXQoJmFkYXB0ZXItPnF1aWVzY2VudCwgMSk7CgoJLyoKCSAqIFdhaXQgdGlsbCBhbGwgdGhlIGlzc3VlZCBjb21tYW5kcyBhcmUgY29tcGxldGUgYW5kIHRoZXJlIGFyZSBubwoJICogY29tbWFuZHMgaW4gdGhlIHBlbmRpbmcgcXVldWUKCSAqLwoJd2hpbGUgKGF0b21pY19yZWFkKCZhZGFwdGVyLT5wZW5kX2NtZHMpID4gMCB8fAoJICAgICAgICFsaXN0X2VtcHR5KCZhZGFwdGVyLT5wZW5kaW5nX2xpc3QpKQoJCW1zbGVlcCgxMDAwKTsJLyogc2xlZXAgZm9yIDFzICovCgoJcnZhbCA9IG1lZ2FfZG9fZGVsX2xvZ2RydihhZGFwdGVyLCBsb2dkcnYpOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZhZGFwdGVyLT5sb2NrLCBmbGFncyk7CgoJLyoKCSAqIElmIGRlbGV0ZSBvcGVyYXRpb24gd2FzIHN1Y2Nlc3NmdWwsIGFkZCAweDgwIHRvIHRoZSBsb2dpY2FsIGRyaXZlCgkgKiBpZHMgZm9yIGNvbW1hbmRzIGluIHRoZSBwZW5kaW5nIHF1ZXVlLgoJICovCglpZiAoYWRhcHRlci0+cmVhZF9sZGlkbWFwKSB7CgkJc3RydWN0IGxpc3RfaGVhZCAqcG9zOwoJCWxpc3RfZm9yX2VhY2gocG9zLCAmYWRhcHRlci0+cGVuZGluZ19saXN0KSB7CgkJCXNjYiA9IGxpc3RfZW50cnkocG9zLCBzY2JfdCwgbGlzdCk7CgkJCWlmIChzY2ItPnB0aHJ1LT5sb2dkcnYgPCAweDgwICkKCQkJCXNjYi0+cHRocnUtPmxvZ2RydiArPSAweDgwOwoJCX0KCX0KCglhdG9taWNfc2V0KCZhZGFwdGVyLT5xdWllc2NlbnQsIDApOwoKCW1lZ2FfcnVucGVuZHEoYWRhcHRlcik7CgoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmYWRhcHRlci0+bG9jaywgZmxhZ3MpOwoKCXJldHVybiBydmFsOwp9CgoKc3RhdGljIGludAptZWdhX2RvX2RlbF9sb2dkcnYoYWRhcHRlcl90ICphZGFwdGVyLCBpbnQgbG9nZHJ2KQp7CgltZWdhY21kX3QJbWM7CglpbnQJcnZhbDsKCgltZW1zZXQoICZtYywgMCwgc2l6ZW9mKG1lZ2FjbWRfdCkpOwoKCW1jLmNtZCA9IEZDX0RFTF9MT0dEUlY7CgltYy5vcGNvZGUgPSBPUF9ERUxfTE9HRFJWOwoJbWMuc3Vib3Bjb2RlID0gbG9nZHJ2OwoKCXJ2YWwgPSBtZWdhX2ludGVybmFsX2NvbW1hbmQoYWRhcHRlciwgTE9DS19JTlQsICZtYywgTlVMTCk7CgoJLyogbG9nIHRoaXMgZXZlbnQgKi8KCWlmKHJ2YWwpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HICJtZWdhcmFpZDogRGVsZXRlIExELSVkIGZhaWxlZC4iLCBsb2dkcnYpOwoJCXJldHVybiBydmFsOwoJfQoKCS8qCgkgKiBBZnRlciBkZWxldGluZyBmaXJzdCBsb2dpY2FsIGRyaXZlLCB0aGUgbG9naWNhbCBkcml2ZXMgbXVzdCBiZQoJICogYWRkcmVzc2VkIGJ5IGFkZGluZyAweDgwIHRvIHRoZSBsb2dpY2FsIGRyaXZlIGlkLgoJICovCglhZGFwdGVyLT5yZWFkX2xkaWRtYXAgPSAxOwoKCXJldHVybiBydmFsOwp9CgoKLyoqCiAqIG1lZ2FfZ2V0X21heF9zZ2woKQogKiBAYWRhcHRlciAtIHBvaW50ZXIgdG8gb3VyIHNvZnQgc3RhdGUKICoKICogRmluZCBvdXQgdGhlIG1heGltdW0gbnVtYmVyIG9mIHNjYXR0ZXItZ2F0aGVyIGVsZW1lbnRzIHN1cHBvcnRlZCBieSB0aGlzCiAqIHZlcnNpb24gb2YgdGhlIGZpcm13YXJlCiAqLwpzdGF0aWMgdm9pZAptZWdhX2dldF9tYXhfc2dsKGFkYXB0ZXJfdCAqYWRhcHRlcikKewoJdW5zaWduZWQgY2hhcglyYXdfbWJveFtzaXplb2Yoc3RydWN0IG1ib3hfb3V0KV07CgltYm94X3QJKm1ib3g7CgoJbWJveCA9IChtYm94X3QgKilyYXdfbWJveDsKCgltZW1zZXQobWJveCwgMCwgc2l6ZW9mKHJhd19tYm94KSk7CgoJbWVtc2V0KCh2b2lkICopYWRhcHRlci0+bWVnYV9idWZmZXIsIDAsIE1FR0FfQlVGRkVSX1NJWkUpOwoKCW1ib3gtPm1fb3V0LnhmZXJhZGRyID0gKHUzMilhZGFwdGVyLT5idWZfZG1hX2hhbmRsZTsKCglyYXdfbWJveFswXSA9IE1BSU5fTUlTQ19PUENPREU7CglyYXdfbWJveFsyXSA9IEdFVF9NQVhfU0dfU1VQUE9SVDsKCgoJaWYoIGlzc3VlX3NjYl9ibG9jayhhZGFwdGVyLCByYXdfbWJveCkgKSB7CgkJLyoKCQkgKiBmL3cgZG9lcyBub3Qgc3VwcG9ydCB0aGlzIGNvbW1hbmQuIENob29zZSB0aGUgZGVmYXVsdCB2YWx1ZQoJCSAqLwoJCWFkYXB0ZXItPnNnbGVuID0gTUlOX1NHTElTVDsKCX0KCWVsc2UgewoJCWFkYXB0ZXItPnNnbGVuID0gKigoY2hhciAqKWFkYXB0ZXItPm1lZ2FfYnVmZmVyKTsKCQkKCQkvKgoJCSAqIE1ha2Ugc3VyZSB0aGlzIGlzIG5vdCBtb3JlIHRoYW4gdGhlIHJlc291cmNlcyB3ZSBhcmUKCQkgKiBwbGFubmluZyB0byBhbGxvY2F0ZQoJCSAqLwoJCWlmICggYWRhcHRlci0+c2dsZW4gPiBNQVhfU0dMSVNUICkKCQkJYWRhcHRlci0+c2dsZW4gPSBNQVhfU0dMSVNUOwoJfQoKCXJldHVybjsKfQoKCi8qKgogKiBtZWdhX3N1cHBvcnRfY2x1c3RlcigpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKgogKiBGaW5kIG91dCBpZiB0aGlzIGZpcm13YXJlIHN1cHBvcnQgY2x1c3RlciBjYWxscy4KICovCnN0YXRpYyBpbnQKbWVnYV9zdXBwb3J0X2NsdXN0ZXIoYWRhcHRlcl90ICphZGFwdGVyKQp7Cgl1bnNpZ25lZCBjaGFyCXJhd19tYm94W3NpemVvZihzdHJ1Y3QgbWJveF9vdXQpXTsKCW1ib3hfdAkqbWJveDsKCgltYm94ID0gKG1ib3hfdCAqKXJhd19tYm94OwoKCW1lbXNldChtYm94LCAwLCBzaXplb2YocmF3X21ib3gpKTsKCgltZW1zZXQoKHZvaWQgKilhZGFwdGVyLT5tZWdhX2J1ZmZlciwgMCwgTUVHQV9CVUZGRVJfU0laRSk7CgoJbWJveC0+bV9vdXQueGZlcmFkZHIgPSAodTMyKWFkYXB0ZXItPmJ1Zl9kbWFfaGFuZGxlOwoKCS8qCgkgKiBUcnkgdG8gZ2V0IHRoZSBpbml0aWF0b3IgaWQuIFRoaXMgY29tbWFuZCB3aWxsIHN1Y2NlZWQgaWZmIHRoZQoJICogY2x1c3RlcmluZyBpcyBhdmFpbGFibGUgb24gdGhpcyBIQkEuCgkgKi8KCXJhd19tYm94WzBdID0gTUVHQV9HRVRfVEFSR0VUX0lEOwoKCWlmKCBpc3N1ZV9zY2JfYmxvY2soYWRhcHRlciwgcmF3X21ib3gpID09IDAgKSB7CgoJCS8qCgkJICogQ2x1c3RlciBzdXBwb3J0IGF2YWlsYWJsZS4gR2V0IHRoZSBpbml0aWF0b3IgdGFyZ2V0IGlkLgoJCSAqIFRlbGwgb3VyIGlkIHRvIG1pZC1sYXllciB0b28uCgkJICovCgkJYWRhcHRlci0+dGhpc19pZCA9ICoodTMyICopYWRhcHRlci0+bWVnYV9idWZmZXI7CgkJYWRhcHRlci0+aG9zdC0+dGhpc19pZCA9IGFkYXB0ZXItPnRoaXNfaWQ7CgoJCXJldHVybiAxOwoJfQoKCXJldHVybiAwOwp9CgoKLyoqCiAqIG1lZ2FfYWRhcGlucSgpCiAqIEBhZGFwdGVyIC0gcG9pbnRlciB0byBvdXIgc29mdCBzdGF0ZQogKiBAZG1hX2hhbmRsZSAtIERNQSBhZGRyZXNzIG9mIHRoZSBidWZmZXIKICoKICogSXNzdWUgaW50ZXJuYWwgY29tYW1uZHMgd2hpbGUgaW50ZXJydXB0cyBhcmUgYXZhaWxhYmxlLgogKiBXZSBvbmx5IGlzc3VlIGRpcmVjdCBtYWlsYm94IGNvbW1hbmRzIGZyb20gd2l0aGluIHRoZSBkcml2ZXIuIGlvY3RsKCkKICogaW50ZXJmYWNlIHVzaW5nIHRoZXNlIHJvdXRpbmVzIGNhbiBpc3N1ZSBwYXNzdGhydSBjb21tYW5kcy4KICovCnN0YXRpYyBpbnQKbWVnYV9hZGFwaW5xKGFkYXB0ZXJfdCAqYWRhcHRlciwgZG1hX2FkZHJfdCBkbWFfaGFuZGxlKQp7CgltZWdhY21kX3QJbWM7CgoJbWVtc2V0KCZtYywgMCwgc2l6ZW9mKG1lZ2FjbWRfdCkpOwoKCWlmKCBhZGFwdGVyLT5mbGFnICYgQk9BUkRfNDBMRCApIHsKCQltYy5jbWQgPSBGQ19ORVdfQ09ORklHOwoJCW1jLm9wY29kZSA9IE5DX1NVQk9QX0VOUVVJUlkzOwoJCW1jLnN1Ym9wY29kZSA9IEVOUTNfR0VUX1NPTElDSVRFRF9GVUxMOwoJfQoJZWxzZSB7CgkJbWMuY21kID0gTUVHQV9NQk9YQ01EX0FEUEVYVElOUTsKCX0KCgltYy54ZmVyYWRkciA9ICh1MzIpZG1hX2hhbmRsZTsKCglpZiAoIG1lZ2FfaW50ZXJuYWxfY29tbWFuZChhZGFwdGVyLCBMT0NLX0lOVCwgJm1jLCBOVUxMKSAhPSAwICkgewoJCXJldHVybiAtMTsKCX0KCglyZXR1cm4gMDsKfQoKCi8qKiBtZWdhX2ludGVybmFsX2Rldl9pbnF1aXJ5KCkKICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqIEBjaCAtIGNoYW5uZWwgZm9yIHRoaXMgZGV2aWNlCiAqIEB0Z3QgLSBJRCBvZiB0aGlzIGRldmljZQogKiBAYnVmX2RtYV9oYW5kbGUgLSBETUEgYWRkcmVzcyBvZiB0aGUgYnVmZmVyCiAqCiAqIElzc3VlIHRoZSBzY3NpIGlucXVpcnkgZm9yIHRoZSBzcGVjaWZpZWQgZGV2aWNlLgogKi8Kc3RhdGljIGludAptZWdhX2ludGVybmFsX2Rldl9pbnF1aXJ5KGFkYXB0ZXJfdCAqYWRhcHRlciwgdTggY2gsIHU4IHRndCwKCQlkbWFfYWRkcl90IGJ1Zl9kbWFfaGFuZGxlKQp7CgltZWdhX3Bhc3N0aHJ1CSpwdGhydTsKCWRtYV9hZGRyX3QJcHRocnVfZG1hX2hhbmRsZTsKCW1lZ2FjbWRfdAltYzsKCWludAkJcnZhbDsKCXN0cnVjdCBwY2lfZGV2CSpwZGV2OwoKCgkvKgoJICogRm9yIGFsbCBpbnRlcm5hbCBjb21tYW5kcywgdGhlIGJ1ZmZlciBtdXN0IGJlIGFsbG9jYXRlZCBpbiA8NEdCCgkgKiBhZGRyZXNzIHJhbmdlCgkgKi8KCWlmKCBtYWtlX2xvY2FsX3BkZXYoYWRhcHRlciwgJnBkZXYpICE9IDAgKSByZXR1cm4gLTE7CgoJcHRocnUgPSBwY2lfYWxsb2NfY29uc2lzdGVudChwZGV2LCBzaXplb2YobWVnYV9wYXNzdGhydSksCgkJCSZwdGhydV9kbWFfaGFuZGxlKTsKCglpZiggcHRocnUgPT0gTlVMTCApIHsKCQlmcmVlX2xvY2FsX3BkZXYocGRldik7CgkJcmV0dXJuIC0xOwoJfQoKCXB0aHJ1LT50aW1lb3V0ID0gMjsKCXB0aHJ1LT5hcnMgPSAxOwoJcHRocnUtPnJlcXNlbnNlbGVuID0gMTQ7CglwdGhydS0+aXNsb2dpY2FsID0gMDsKCglwdGhydS0+Y2hhbm5lbCA9IChhZGFwdGVyLT5mbGFnICYgQk9BUkRfNDBMRCkgPyAwIDogY2g7CgoJcHRocnUtPnRhcmdldCA9IChhZGFwdGVyLT5mbGFnICYgQk9BUkRfNDBMRCkgPyAoY2ggPDwgNCl8dGd0IDogdGd0OwoKCXB0aHJ1LT5jZGJsZW4gPSA2OwoKCXB0aHJ1LT5jZGJbMF0gPSBJTlFVSVJZOwoJcHRocnUtPmNkYlsxXSA9IDA7CglwdGhydS0+Y2RiWzJdID0gMDsKCXB0aHJ1LT5jZGJbM10gPSAwOwoJcHRocnUtPmNkYls0XSA9IDI1NTsKCXB0aHJ1LT5jZGJbNV0gPSAwOwoKCglwdGhydS0+ZGF0YXhmZXJhZGRyID0gKHUzMilidWZfZG1hX2hhbmRsZTsKCXB0aHJ1LT5kYXRheGZlcmxlbiA9IDI1NjsKCgltZW1zZXQoJm1jLCAwLCBzaXplb2YobWVnYWNtZF90KSk7CgoJbWMuY21kID0gTUVHQV9NQk9YQ01EX1BBU1NUSFJVOwoJbWMueGZlcmFkZHIgPSAodTMyKXB0aHJ1X2RtYV9oYW5kbGU7CgoJcnZhbCA9IG1lZ2FfaW50ZXJuYWxfY29tbWFuZChhZGFwdGVyLCBMT0NLX0lOVCwgJm1jLCBwdGhydSk7CgoJcGNpX2ZyZWVfY29uc2lzdGVudChwZGV2LCBzaXplb2YobWVnYV9wYXNzdGhydSksIHB0aHJ1LAoJCQlwdGhydV9kbWFfaGFuZGxlKTsKCglmcmVlX2xvY2FsX3BkZXYocGRldik7CgoJcmV0dXJuIHJ2YWw7Cn0KCgovKioKICogbWVnYV9pbnRlcm5hbF9jb21tYW5kKCkKICogQGFkYXB0ZXIgLSBwb2ludGVyIHRvIG91ciBzb2Z0IHN0YXRlCiAqIEBscyAtIHRoZSBzY29wZSBvZiB0aGUgZXhjbHVzaW9uIGxvY2suCiAqIEBtYyAtIHRoZSBtYWlsYm94IGNvbW1hbmQKICogQHB0aHJ1IC0gUGFzc3RocnUgc3RydWN0dXJlIGZvciBEQ0RCIGNvbW1hbmRzCiAqCiAqIElzc3VlIHRoZSBpbnRlcm5hbCBjb21tYW5kcyBpbiBpbnRlcnJ1cHQgbW9kZS4KICogVGhlIGxhc3QgYXJndW1lbnQgaXMgdGhlIGFkZHJlc3Mgb2YgdGhlIHBhc3N0aHJ1IHN0cnVjdHVyZSBpZiB0aGUgY29tbWFuZAogKiB0byBiZSBmaXJlZCBpcyBhIHBhc3N0aHJ1IGNvbW1hbmQKICoKICogbG9ja3Njb3BlIHNwZWNpZmllcyB3aGV0aGVyIHRoZSBjYWxsZXIgaGFzIGFscmVhZHkgYWNxdWlyZWQgdGhlIGxvY2suIE9mCiAqIGNvdXJzZSwgdGhlIGNhbGxlciBtdXN0IGtub3cgd2hpY2ggbG9jayB3ZSBhcmUgdGFsa2luZyBhYm91dC4KICoKICogTm90ZTogcGFyYW1ldGVyICdwdGhydScgaXMgbnVsbCBmb3Igbm9uLXBhc3N0aHJ1IGNvbW1hbmRzLgogKi8Kc3RhdGljIGludAptZWdhX2ludGVybmFsX2NvbW1hbmQoYWRhcHRlcl90ICphZGFwdGVyLCBsb2Nrc2NvcGVfdCBscywgbWVnYWNtZF90ICptYywKCQltZWdhX3Bhc3N0aHJ1ICpwdGhydSApCnsKCVNjc2lfQ21uZAkqc2NtZDsKCXN0cnVjdAlzY3NpX2RldmljZSAqc2RldjsKCXVuc2lnbmVkIGxvbmcJZmxhZ3MgPSAwOwoJc2NiX3QJKnNjYjsKCWludAlydmFsOwoKCS8qCgkgKiBUaGUgaW50ZXJuYWwgY29tbWFuZHMgc2hhcmUgb25lIGNvbW1hbmQgaWQgYW5kIGhlbmNlIGFyZQoJICogc2VyaWFsaXplZC4gVGhpcyBpcyBzbyBiZWNhdXNlIHdlIHdhbnQgdG8gcmVzZXJ2ZSBtYXhpbXVtIG51bWJlciBvZgoJICogYXZhaWxhYmxlIGNvbW1hbmQgaWRzIGZvciB0aGUgSS9PIGNvbW1hbmRzLgoJICovCglkb3duKCZhZGFwdGVyLT5pbnRfbXR4KTsKCglzY2IgPSAmYWRhcHRlci0+aW50X3NjYjsKCW1lbXNldChzY2IsIDAsIHNpemVvZihzY2JfdCkpOwoKCXNjbWQgPSAmYWRhcHRlci0+aW50X3NjbWQ7CgltZW1zZXQoc2NtZCwgMCwgc2l6ZW9mKFNjc2lfQ21uZCkpOwoKCXNkZXYgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3Qgc2NzaV9kZXZpY2UpLCBHRlBfS0VSTkVMKTsKCW1lbXNldChzZGV2LCAwLCBzaXplb2Yoc3RydWN0IHNjc2lfZGV2aWNlKSk7CglzY21kLT5kZXZpY2UgPSBzZGV2OwoKCXNjbWQtPmRldmljZS0+aG9zdCA9IGFkYXB0ZXItPmhvc3Q7CglzY21kLT5idWZmZXIgPSAodm9pZCAqKXNjYjsKCXNjbWQtPmNtbmRbMF0gPSBNRUdBX0lOVEVSTkFMX0NNRDsKCglzY2ItPnN0YXRlIHw9IFNDQl9BQ1RJVkU7CglzY2ItPmNtZCA9IHNjbWQ7CgoJbWVtY3B5KHNjYi0+cmF3X21ib3gsIG1jLCBzaXplb2YobWVnYWNtZF90KSk7CgoJLyoKCSAqIElzIGl0IGEgcGFzc3RocnUgY29tbWFuZAoJICovCglpZiggbWMtPmNtZCA9PSBNRUdBX01CT1hDTURfUEFTU1RIUlUgKSB7CgoJCXNjYi0+cHRocnUgPSBwdGhydTsKCX0KCglzY2ItPmlkeCA9IENNRElEX0lOVF9DTURTOwoKCXNjbWQtPnN0YXRlID0gMDsKCgkvKgoJICogR2V0IHRoZSBsb2NrIG9ubHkgaWYgdGhlIGNhbGxlciBoYXMgbm90IGFjcXVpcmVkIGl0IGFscmVhZHkKCSAqLwoJaWYoIGxzID09IExPQ0tfSU5UICkgc3Bpbl9sb2NrX2lycXNhdmUoJmFkYXB0ZXItPmxvY2ssIGZsYWdzKTsKCgltZWdhcmFpZF9xdWV1ZShzY21kLCBtZWdhX2ludGVybmFsX2RvbmUpOwoKCWlmKCBscyA9PSBMT0NLX0lOVCApIHNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmFkYXB0ZXItPmxvY2ssIGZsYWdzKTsKCgkvKgoJICogV2FpdCB0aWxsIHRoaXMgY29tbWFuZCBmaW5pc2hlcy4gRG8gbm90IHVzZQoJICogd2FpdF9ldmVudF9pbnRlcnJ1cHRpYmxlKCkuIEl0IGNhdXNlcyBwYW5pYyBpZiBDVFJMLUMgaXMgaGl0IHdoZW4KCSAqIGR1bXBpbmcgZS5nLiwgcGh5c2ljYWwgZGlzayBpbmZvcm1hdGlvbiB0aHJvdWdoIC9wcm9jIGludGVyZmFjZS4KCSAqLwojaWYgMAoJd2FpdF9ldmVudF9pbnRlcnJ1cHRpYmxlKGFkYXB0ZXItPmludF93YWl0cSwgc2NtZC0+c3RhdGUpOwojZW5kaWYKCXdhaXRfZXZlbnQoYWRhcHRlci0+aW50X3dhaXRxLCBzY21kLT5zdGF0ZSk7CgoJcnZhbCA9IHNjbWQtPnJlc3VsdDsKCW1jLT5zdGF0dXMgPSBzY21kLT5yZXN1bHQ7CglrZnJlZShzZGV2KTsKCgkvKgoJICogUHJpbnQgYSBkZWJ1ZyBtZXNzYWdlIGZvciBhbGwgZmFpbGVkIGNvbW1hbmRzLiBBcHBsaWNhdGlvbnMgY2FuIHVzZQoJICogdGhpcyBpbmZvcm1hdGlvbi4KCSAqLwoJaWYoIHNjbWQtPnJlc3VsdCAmJiB0cmFjZV9sZXZlbCApIHsKCQlwcmludGsoIm1lZ2FyYWlkOiBjbWQgWyV4LCAleCwgJXhdIHN0YXR1czpbJXhdXG4iLAoJCQltYy0+Y21kLCBtYy0+b3Bjb2RlLCBtYy0+c3Vib3Bjb2RlLCBzY21kLT5yZXN1bHQpOwoJfQoKCXVwKCZhZGFwdGVyLT5pbnRfbXR4KTsKCglyZXR1cm4gcnZhbDsKfQoKCi8qKgogKiBtZWdhX2ludGVybmFsX2RvbmUoKQogKiBAc2NtZCAtIGludGVybmFsIHNjc2kgY29tbWFuZAogKgogKiBDYWxsYmFjayByb3V0aW5lIGZvciBpbnRlcm5hbCBjb21tYW5kcy4KICovCnN0YXRpYyB2b2lkCm1lZ2FfaW50ZXJuYWxfZG9uZShTY3NpX0NtbmQgKnNjbWQpCnsKCWFkYXB0ZXJfdAkqYWRhcHRlcjsKCglhZGFwdGVyID0gKGFkYXB0ZXJfdCAqKXNjbWQtPmRldmljZS0+aG9zdC0+aG9zdGRhdGE7CgoJc2NtZC0+c3RhdGUgPSAxOyAvKiB0aHJlYWQgd2FpdGluZyBmb3IgaXRzIGNvbW1hbmQgdG8gY29tcGxldGUgKi8KCgkvKgoJICogU2VlIGNvbW1lbnQgaW4gbWVnYV9pbnRlcm5hbF9jb21tYW5kKCkgcm91dGluZSBmb3IKCSAqIHdhaXRfZXZlbnRfaW50ZXJydXB0aWJsZSgpCgkgKi8KI2lmIDAKCXdha2VfdXBfaW50ZXJydXB0aWJsZSgmYWRhcHRlci0+aW50X3dhaXRxKTsKI2VuZGlmCgl3YWtlX3VwKCZhZGFwdGVyLT5pbnRfd2FpdHEpOwoKfQoKCnN0YXRpYyBzdHJ1Y3Qgc2NzaV9ob3N0X3RlbXBsYXRlIG1lZ2FyYWlkX3RlbXBsYXRlID0gewoJLm1vZHVsZQkJCQk9IFRISVNfTU9EVUxFLAoJLm5hbWUJCQkJPSAiTWVnYVJBSUQiLAoJLnByb2NfbmFtZQkJCT0gIm1lZ2FyYWlkIiwKCS5pbmZvCQkJCT0gbWVnYXJhaWRfaW5mbywKCS5xdWV1ZWNvbW1hbmQJCQk9IG1lZ2FyYWlkX3F1ZXVlLAkKCS5iaW9zX3BhcmFtCQkJPSBtZWdhcmFpZF9iaW9zcGFyYW0sCgkubWF4X3NlY3RvcnMJCQk9IE1BWF9TRUNUT1JTX1BFUl9JTywKCS5jYW5fcXVldWUJCQk9IE1BWF9DT01NQU5EUywKCS50aGlzX2lkCQkJPSBERUZBVUxUX0lOSVRJQVRPUl9JRCwKCS5zZ190YWJsZXNpemUJCQk9IE1BWF9TR0xJU1QsCgkuY21kX3Blcl9sdW4JCQk9IERFRl9DTURfUEVSX0xVTiwKCS51c2VfY2x1c3RlcmluZwkJCT0gRU5BQkxFX0NMVVNURVJJTkcsCgkuZWhfYWJvcnRfaGFuZGxlcgkJPSBtZWdhcmFpZF9hYm9ydCwKCS5laF9kZXZpY2VfcmVzZXRfaGFuZGxlcgk9IG1lZ2FyYWlkX3Jlc2V0LAoJLmVoX2J1c19yZXNldF9oYW5kbGVyCQk9IG1lZ2FyYWlkX3Jlc2V0LAoJLmVoX2hvc3RfcmVzZXRfaGFuZGxlcgkJPSBtZWdhcmFpZF9yZXNldCwKfTsKCnN0YXRpYyBpbnQgX19kZXZpbml0Cm1lZ2FyYWlkX3Byb2JlX29uZShzdHJ1Y3QgcGNpX2RldiAqcGRldiwgY29uc3Qgc3RydWN0IHBjaV9kZXZpY2VfaWQgKmlkKQp7CglzdHJ1Y3QgU2NzaV9Ib3N0ICpob3N0OwoJYWRhcHRlcl90ICphZGFwdGVyOwoJdW5zaWduZWQgbG9uZyBtZWdhX2Jhc2Vwb3J0LCB0YmFzZSwgZmxhZyA9IDA7Cgl1MTYgc3Vic3lzaWQsIHN1YnN5c3ZpZDsKCXU4IHBjaV9idXMsIHBjaV9kZXZfZnVuYzsKCWludCBpcnEsIGksIGo7CglpbnQgZXJyb3IgPSAtRU5PREVWOwoKCWlmIChwY2lfZW5hYmxlX2RldmljZShwZGV2KSkKCQlnb3RvIG91dDsKCXBjaV9zZXRfbWFzdGVyKHBkZXYpOwoKCXBjaV9idXMgPSBwZGV2LT5idXMtPm51bWJlcjsKCXBjaV9kZXZfZnVuYyA9IHBkZXYtPmRldmZuOwoKCS8qCgkgKiBUaGUgbWVnYXJhaWQzIHN0dWZmIHJlcG9ydHMgdGhlIElEIG9mIHRoZSBJbnRlbCBwYXJ0IHdoaWNoIGlzIG5vdAoJICogcmVtb3RlbHkgc3BlY2lmaWMgdG8gdGhlIG1lZ2FyYWlkCgkgKi8KCWlmIChwZGV2LT52ZW5kb3IgPT0gUENJX1ZFTkRPUl9JRF9JTlRFTCkgewoJCXUxNiBtYWdpYzsKCQkvKgoJCSAqIERvbid0IGZhbGwgb3ZlciB0aGUgQ29tcGFxIG1hbmFnZW1lbnQgY2FyZHMgdXNpbmcgdGhlIHNhbWUKCQkgKiBQQ0kgaWRlbnRpZmllcgoJCSAqLwoJCWlmIChwZGV2LT5zdWJzeXN0ZW1fdmVuZG9yID09IFBDSV9WRU5ET1JfSURfQ09NUEFRICYmCgkJICAgIHBkZXYtPnN1YnN5c3RlbV9kZXZpY2UgPT0gMHhDMDAwKQoJCSAgIAlyZXR1cm4gLUVOT0RFVjsKCQkvKiBOb3cgY2hlY2sgdGhlIG1hZ2ljIHNpZ25hdHVyZSBieXRlICovCgkJcGNpX3JlYWRfY29uZmlnX3dvcmQocGRldiwgUENJX0NPTkZfQU1JU0lHLCAmbWFnaWMpOwoJCWlmIChtYWdpYyAhPSBIQkFfU0lHTkFUVVJFXzQ3MSAmJiBtYWdpYyAhPSBIQkFfU0lHTkFUVVJFKQoJCQlyZXR1cm4gLUVOT0RFVjsKCQkvKiBPayBpdCBpcyBwcm9iYWJseSBhIG1lZ2FyYWlkICovCgl9CgoJLyoKCSAqIEZvciB0aGVzZSB2ZW5kb3IgYW5kIGRldmljZSBpZHMsIHNpZ25hdHVyZSBvZmZzZXRzIGFyZSBub3QKCSAqIHZhbGlkIGFuZCA2NCBiaXQgaXMgaW1wbGljaXQKCSAqLwoJaWYgKGlkLT5kcml2ZXJfZGF0YSAmIEJPQVJEXzY0QklUKQoJCWZsYWcgfD0gQk9BUkRfNjRCSVQ7CgllbHNlIHsKCQl1MzIgbWFnaWM2NDsKCgkJcGNpX3JlYWRfY29uZmlnX2R3b3JkKHBkZXYsIFBDSV9DT05GX0FNSVNJRzY0LCAmbWFnaWM2NCk7CgkJaWYgKG1hZ2ljNjQgPT0gSEJBX1NJR05BVFVSRV82NEJJVCkKCQkJZmxhZyB8PSBCT0FSRF82NEJJVDsKCX0KCglzdWJzeXN2aWQgPSBwZGV2LT5zdWJzeXN0ZW1fdmVuZG9yOwoJc3Vic3lzaWQgPSBwZGV2LT5zdWJzeXN0ZW1fZGV2aWNlOwoKCXByaW50ayhLRVJOX05PVElDRSAibWVnYXJhaWQ6IGZvdW5kIDB4JTQuMDR4OjB4JTQuMDR4OmJ1cyAlZDoiLAoJCWlkLT52ZW5kb3IsIGlkLT5kZXZpY2UsIHBjaV9idXMpOwoKCXByaW50aygic2xvdCAlZDpmdW5jICVkXG4iLAoJCVBDSV9TTE9UKHBjaV9kZXZfZnVuYyksIFBDSV9GVU5DKHBjaV9kZXZfZnVuYykpOwoKCS8qIFJlYWQgdGhlIGJhc2UgcG9ydCBhbmQgSVJRIGZyb20gUENJICovCgltZWdhX2Jhc2Vwb3J0ID0gcGNpX3Jlc291cmNlX3N0YXJ0KHBkZXYsIDApOwoJaXJxID0gcGRldi0+aXJxOwoKCXRiYXNlID0gbWVnYV9iYXNlcG9ydDsKCWlmIChwY2lfcmVzb3VyY2VfZmxhZ3MocGRldiwgMCkgJiBJT1JFU09VUkNFX01FTSkgewoJCWZsYWcgfD0gQk9BUkRfTUVNTUFQOwoKCQlpZiAoIXJlcXVlc3RfbWVtX3JlZ2lvbihtZWdhX2Jhc2Vwb3J0LCAxMjgsICJtZWdhcmFpZCIpKSB7CgkJCXByaW50ayhLRVJOX1dBUk5JTkcgIm1lZ2FyYWlkOiBtZW0gcmVnaW9uIGJ1c3khXG4iKTsKCQkJZ290byBvdXRfZGlzYWJsZV9kZXZpY2U7CgkJfQoKCQltZWdhX2Jhc2Vwb3J0ID0gKHVuc2lnbmVkIGxvbmcpaW9yZW1hcChtZWdhX2Jhc2Vwb3J0LCAxMjgpOwoJCWlmICghbWVnYV9iYXNlcG9ydCkgewoJCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCSAgICAgICAibWVnYXJhaWQ6IGNvdWxkIG5vdCBtYXAgaGJhIG1lbW9yeVxuIik7CgkJCWdvdG8gb3V0X3JlbGVhc2VfcmVnaW9uOwoJCX0KCX0gZWxzZSB7CgkJZmxhZyB8PSBCT0FSRF9JT01BUDsKCQltZWdhX2Jhc2Vwb3J0ICs9IDB4MTA7CgoJCWlmICghcmVxdWVzdF9yZWdpb24obWVnYV9iYXNlcG9ydCwgMTYsICJtZWdhcmFpZCIpKQoJCQlnb3RvIG91dF9kaXNhYmxlX2RldmljZTsKCX0KCgkvKiBJbml0aWFsaXplIFNDU0kgSG9zdCBzdHJ1Y3R1cmUgKi8KCWhvc3QgPSBzY3NpX2hvc3RfYWxsb2MoJm1lZ2FyYWlkX3RlbXBsYXRlLCBzaXplb2YoYWRhcHRlcl90KSk7CglpZiAoIWhvc3QpCgkJZ290byBvdXRfaW91bm1hcDsKCglhZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWhvc3QtPmhvc3RkYXRhOwoJbWVtc2V0KGFkYXB0ZXIsIDAsIHNpemVvZihhZGFwdGVyX3QpKTsKCglwcmludGsoS0VSTl9OT1RJQ0UKCQkic2NzaSVkOkZvdW5kIE1lZ2FSQUlEIGNvbnRyb2xsZXIgYXQgMHglbHgsIElSUTolZFxuIiwKCQlob3N0LT5ob3N0X25vLCBtZWdhX2Jhc2Vwb3J0LCBpcnEpOwoKCWFkYXB0ZXItPmJhc2UgPSBtZWdhX2Jhc2Vwb3J0OwoKCUlOSVRfTElTVF9IRUFEKCZhZGFwdGVyLT5mcmVlX2xpc3QpOwoJSU5JVF9MSVNUX0hFQUQoJmFkYXB0ZXItPnBlbmRpbmdfbGlzdCk7CglJTklUX0xJU1RfSEVBRCgmYWRhcHRlci0+Y29tcGxldGVkX2xpc3QpOwoKCWFkYXB0ZXItPmZsYWcgPSBmbGFnOwoJc3Bpbl9sb2NrX2luaXQoJmFkYXB0ZXItPmxvY2spOwoJc2NzaV9hc3NpZ25fbG9jayhob3N0LCAmYWRhcHRlci0+bG9jayk7CgoJaG9zdC0+Y21kX3Blcl9sdW4gPSBtYXhfY21kX3Blcl9sdW47Cglob3N0LT5tYXhfc2VjdG9ycyA9IG1heF9zZWN0b3JzX3Blcl9pbzsKCglhZGFwdGVyLT5kZXYgPSBwZGV2OwoJYWRhcHRlci0+aG9zdCA9IGhvc3Q7CgoJYWRhcHRlci0+aG9zdC0+aXJxID0gaXJxOwoKCWlmIChmbGFnICYgQk9BUkRfTUVNTUFQKQoJCWFkYXB0ZXItPmhvc3QtPmJhc2UgPSB0YmFzZTsKCWVsc2UgewoJCWFkYXB0ZXItPmhvc3QtPmlvX3BvcnQgPSB0YmFzZTsKCQlhZGFwdGVyLT5ob3N0LT5uX2lvX3BvcnQgPSAxNjsKCX0KCglhZGFwdGVyLT5ob3N0LT51bmlxdWVfaWQgPSAocGNpX2J1cyA8PCA4KSB8IHBjaV9kZXZfZnVuYzsKCgkvKgoJICogQWxsb2NhdGUgYnVmZmVyIHRvIGlzc3VlIGludGVybmFsIGNvbW1hbmRzLgoJICovCglhZGFwdGVyLT5tZWdhX2J1ZmZlciA9IHBjaV9hbGxvY19jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwKCQlNRUdBX0JVRkZFUl9TSVpFLCAmYWRhcHRlci0+YnVmX2RtYV9oYW5kbGUpOwoJaWYgKCFhZGFwdGVyLT5tZWdhX2J1ZmZlcikgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIm1lZ2FyYWlkOiBvdXQgb2YgUkFNLlxuIik7CgkJZ290byBvdXRfaG9zdF9wdXQ7Cgl9CgoJYWRhcHRlci0+c2NiX2xpc3QgPSBrbWFsbG9jKHNpemVvZihzY2JfdCkgKiBNQVhfQ09NTUFORFMsIEdGUF9LRVJORUwpOwoJaWYgKCFhZGFwdGVyLT5zY2JfbGlzdCkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcgIm1lZ2FyYWlkOiBvdXQgb2YgUkFNLlxuIik7CgkJZ290byBvdXRfZnJlZV9jbWRfYnVmZmVyOwoJfQoKCWlmIChyZXF1ZXN0X2lycShpcnEsIChhZGFwdGVyLT5mbGFnICYgQk9BUkRfTUVNTUFQKSA/CgkJCQltZWdhcmFpZF9pc3JfbWVtbWFwcGVkIDogbWVnYXJhaWRfaXNyX2lvbWFwcGVkLAoJCQkJCVNBX1NISVJRLCAibWVnYXJhaWQiLCBhZGFwdGVyKSkgewoJCXByaW50ayhLRVJOX1dBUk5JTkcKCQkJIm1lZ2FyYWlkOiBDb3VsZG4ndCByZWdpc3RlciBJUlEgJWQhXG4iLCBpcnEpOwoJCWdvdG8gb3V0X2ZyZWVfc2NiX2xpc3Q7Cgl9CgoJaWYgKG1lZ2Ffc2V0dXBfbWFpbGJveChhZGFwdGVyKSkKCQlnb3RvIG91dF9mcmVlX2lycTsKCglpZiAobWVnYV9xdWVyeV9hZGFwdGVyKGFkYXB0ZXIpKQoJCWdvdG8gb3V0X2ZyZWVfbWJveDsKCgkvKgoJICogSGF2ZSBjaGVja3MgZm9yIHNvbWUgYnVnZ3kgZi93CgkgKi8KCWlmICgoc3Vic3lzaWQgPT0gMHgxMTExKSAmJiAoc3Vic3lzdmlkID09IDB4MTExMSkpIHsKCQkvKgoJCSAqIFdoaWNoIGZpcm13YXJlCgkJICovCgkJaWYgKCFzdHJjbXAoYWRhcHRlci0+ZndfdmVyc2lvbiwgIjMuMDAiKSB8fAoJCQkJIXN0cmNtcChhZGFwdGVyLT5md192ZXJzaW9uLCAiMy4wMSIpKSB7CgoJCQlwcmludGsoIEtFUk5fV0FSTklORwoJCQkJIm1lZ2FyYWlkOiBZb3VyICBjYXJkIGlzIGEgRGVsbCBQRVJDICIKCQkJCSIyL1NDIFJBSUQgY29udHJvbGxlciB3aXRoICAiCgkJCQkiZmlybXdhcmVcbm1lZ2FyYWlkOiAzLjAwIG9yIDMuMDEuICAiCgkJCQkiVGhpcyBkcml2ZXIgaXMga25vd24gdG8gaGF2ZSAiCgkJCQkiY29ycnVwdGlvbiBpc3N1ZXNcbm1lZ2FyYWlkOiB3aXRoICIKCQkJCSJ0aG9zZSBmaXJtd2FyZSB2ZXJzaW9ucyBvbiB0aGlzICIKCQkJCSJzcGVjaWZpYyBjYXJkLiAgSW4gb3JkZXJcbm1lZ2FyYWlkOiAiCgkJCQkidG8gcHJvdGVjdCB5b3VyIGRhdGEsIHBsZWFzZSB1cGdyYWRlICIKCQkJCSJ5b3VyIGZpcm13YXJlIHRvIHZlcnNpb25cbm1lZ2FyYWlkOiAiCgkJCQkiMy4xMCBvciBsYXRlciwgYXZhaWxhYmxlIGZyb20gdGhlICIKCQkJCSJEZWxsIFRlY2huaWNhbCBTdXBwb3J0IHdlYlxuIgoJCQkJIm1lZ2FyYWlkOiBzaXRlIGF0XG5odHRwOi8vc3VwcG9ydC4iCgkJCQkiZGVsbC5jb20vdXMvZW4vZmlsZWxpYi9kb3dubG9hZC8iCgkJCQkiaW5kZXguYXNwP2ZpbGVpZD0yOTQwXG4iCgkJCSk7CgkJfQoJfQoKCS8qCgkgKiBJZiB3ZSBoYXZlIGEgSFAgMU0oMHg2MEU3KS8yTSgweDYwRTgpIGNvbnRyb2xsZXIgd2l0aAoJICogZmlybXdhcmUgSC4wMS4wNywgSC4wMS4wOCwgYW5kIEguMDEuMDkgZGlzYWJsZSA2NCBiaXQKCSAqIHN1cHBvcnQsIHNpbmNlIHRoaXMgZmlybXdhcmUgY2Fubm90IGhhbmRsZSA2NCBiaXQKCSAqIGFkZHJlc3NpbmcKCSAqLwoJaWYgKChzdWJzeXN2aWQgPT0gSFBfU1VCU1lTX1ZJRCkgJiYKCSAgICAoKHN1YnN5c2lkID09IDB4NjBFNykgfHwgKHN1YnN5c2lkID09IDB4NjBFOCkpKSB7CgkJLyoKCQkgKiB3aGljaCBmaXJtd2FyZQoJCSAqLwoJCWlmICghc3RyY21wKGFkYXB0ZXItPmZ3X3ZlcnNpb24sICJIMDEuMDciKSB8fAoJCSAgICAhc3RyY21wKGFkYXB0ZXItPmZ3X3ZlcnNpb24sICJIMDEuMDgiKSB8fAoJCSAgICAhc3RyY21wKGFkYXB0ZXItPmZ3X3ZlcnNpb24sICJIMDEuMDkiKSApIHsKCQkJcHJpbnRrKEtFUk5fV0FSTklORwoJCQkJIm1lZ2FyYWlkOiBGaXJtd2FyZSBILjAxLjA3LCAiCgkJCQkiSC4wMS4wOCwgYW5kIEguMDEuMDkgb24gMU0vMk0gIgoJCQkJImNvbnRyb2xsZXJzXG4iCgkJCQkibWVnYXJhaWQ6IGRvIG5vdCBzdXBwb3J0IDY0IGJpdCAiCgkJCQkiYWRkcmVzc2luZy5cbm1lZ2FyYWlkOiBESVNBQkxJTkcgIgoJCQkJIjY0IGJpdCBzdXBwb3J0LlxuIik7CgkJCWFkYXB0ZXItPmZsYWcgJj0gfkJPQVJEXzY0QklUOwoJCX0KCX0KCglpZiAobWVnYV9pc19iaW9zX2VuYWJsZWQoYWRhcHRlcikpCgkJbWVnYV9oYmFzW2hiYV9jb3VudF0uaXNfYmlvc19lbmFibGVkID0gMTsKCW1lZ2FfaGJhc1toYmFfY291bnRdLmhvc3RkYXRhX2FkZHIgPSBhZGFwdGVyOwoKCS8qCgkgKiBGaW5kIG91dCB3aGljaCBjaGFubmVsIGlzIHJhaWQgYW5kIHdoaWNoIGlzIHNjc2kuIFRoaXMgaXMKCSAqIGZvciBST01CIHN1cHBvcnQuCgkgKi8KCW1lZ2FfZW51bV9yYWlkX3Njc2koYWRhcHRlcik7CgoJLyoKCSAqIEZpbmQgb3V0IGlmIGEgbG9naWNhbCBkcml2ZSBpcyBzZXQgYXMgdGhlIGJvb3QgZHJpdmUuIElmCgkgKiB0aGVyZSBpcyBvbmUsIHdpbGwgbWFrZSB0aGF0IGFzIHRoZSBmaXJzdCBsb2dpY2FsIGRyaXZlLgoJICogUk9NQjogRG8gd2UgaGF2ZSB0byBib290IGZyb20gYSBwaHlzaWNhbCBkcml2ZS4gVGhlbiBhbGwKCSAqIHRoZSBwaHlzaWNhbCBkcml2ZXMgd291bGQgYXBwZWFyIGJlZm9yZSB0aGUgbG9naWNhbCBkaXNrcy4KCSAqIEVsc2UsIGFsbCB0aGUgcGh5c2ljYWwgZHJpdmVzIHdvdWxkIGJlIGV4cG9ydGVkIHRvIHRoZSBtaWQKCSAqIGxheWVyIGFmdGVyIGxvZ2ljYWwgZHJpdmVzLgoJICovCgltZWdhX2dldF9ib290X2RydihhZGFwdGVyKTsKCglpZiAoYWRhcHRlci0+Ym9vdF9wZHJ2X2VuYWJsZWQpIHsKCQlqID0gYWRhcHRlci0+cHJvZHVjdF9pbmZvLm5jaGFubmVsczsKCQlmb3IoIGkgPSAwOyBpIDwgajsgaSsrICkKCQkJYWRhcHRlci0+bG9nZHJ2X2NoYW5baV0gPSAwOwoJCWZvciggaSA9IGo7IGkgPCBOVklSVF9DSEFOICsgajsgaSsrICkKCQkJYWRhcHRlci0+bG9nZHJ2X2NoYW5baV0gPSAxOwoJfSBlbHNlIHsKCQlmb3IgKGkgPSAwOyBpIDwgTlZJUlRfQ0hBTjsgaSsrKQoJCQlhZGFwdGVyLT5sb2dkcnZfY2hhbltpXSA9IDE7CgkJZm9yIChpID0gTlZJUlRfQ0hBTjsgaSA8IE1BWF9DSEFOTkVMUytOVklSVF9DSEFOOyBpKyspCgkJCWFkYXB0ZXItPmxvZ2Rydl9jaGFuW2ldID0gMDsKCQlhZGFwdGVyLT5tZWdhX2NoX2NsYXNzIDw8PSBOVklSVF9DSEFOOwoJfQoKCS8qCgkgKiBEbyB3ZSBzdXBwb3J0IHJhbmRvbSBkZWxldGlvbiBhbmQgYWRkaXRpb24gb2YgbG9naWNhbAoJICogZHJpdmVzCgkgKi8KCWFkYXB0ZXItPnJlYWRfbGRpZG1hcCA9IDA7CS8qIHNldCBpdCBhZnRlciBmaXJzdCBsb2dkcnYKCQkJCQkJICAgZGVsZXRlIGNtZCAqLwoJYWRhcHRlci0+c3VwcG9ydF9yYW5kb21fZGVsID0gbWVnYV9zdXBwb3J0X3JhbmRvbV9kZWwoYWRhcHRlcik7CgoJLyogSW5pdGlhbGl6ZSBTQ0JzICovCglpZiAobWVnYV9pbml0X3NjYihhZGFwdGVyKSkKCQlnb3RvIG91dF9mcmVlX21ib3g7CgoJLyoKCSAqIFJlc2V0IHRoZSBwZW5kaW5nIGNvbW1hbmRzIGNvdW50ZXIKCSAqLwoJYXRvbWljX3NldCgmYWRhcHRlci0+cGVuZF9jbWRzLCAwKTsKCgkvKgoJICogUmVzZXQgdGhlIGFkYXB0ZXIgcXVpZXNjZW50IGZsYWcKCSAqLwoJYXRvbWljX3NldCgmYWRhcHRlci0+cXVpZXNjZW50LCAwKTsKCgloYmFfc29mdF9zdGF0ZVtoYmFfY291bnRdID0gYWRhcHRlcjsKCgkvKgoJICogRmlsbCBpbiB0aGUgc3RydWN0dXJlIHdoaWNoIG5lZWRzIHRvIGJlIHBhc3NlZCBiYWNrIHRvIHRoZQoJICogYXBwbGljYXRpb24gd2hlbiBpdCBkb2VzIGFuIGlvY3RsKCkgZm9yIGNvbnRyb2xsZXIgcmVsYXRlZAoJICogaW5mb3JtYXRpb24uCgkgKi8KCWkgPSBoYmFfY291bnQ7CgoJbWNvbnRyb2xsZXJbaV0uYmFzZSA9IG1lZ2FfYmFzZXBvcnQ7CgltY29udHJvbGxlcltpXS5pcnEgPSBpcnE7CgltY29udHJvbGxlcltpXS5udW1sZHJ2ID0gYWRhcHRlci0+bnVtbGRydjsKCW1jb250cm9sbGVyW2ldLnBjaWJ1cyA9IHBjaV9idXM7CgltY29udHJvbGxlcltpXS5wY2lkZXYgPSBpZC0+ZGV2aWNlOwoJbWNvbnRyb2xsZXJbaV0ucGNpZnVuID0gUENJX0ZVTkMgKHBjaV9kZXZfZnVuYyk7CgltY29udHJvbGxlcltpXS5wY2lpZCA9IC0xOwoJbWNvbnRyb2xsZXJbaV0ucGNpdmVuZG9yID0gaWQtPnZlbmRvcjsKCW1jb250cm9sbGVyW2ldLnBjaXNsb3QgPSBQQ0lfU0xPVChwY2lfZGV2X2Z1bmMpOwoJbWNvbnRyb2xsZXJbaV0udWlkID0gKHBjaV9idXMgPDwgOCkgfCBwY2lfZGV2X2Z1bmM7CgoKCS8qIFNldCB0aGUgTW9kZSBvZiBhZGRyZXNzaW5nIHRvIDY0IGJpdCBpZiB3ZSBjYW4gKi8KCWlmICgoYWRhcHRlci0+ZmxhZyAmIEJPQVJEXzY0QklUKSAmJiAoc2l6ZW9mKGRtYV9hZGRyX3QpID09IDgpKSB7CgkJcGNpX3NldF9kbWFfbWFzayhwZGV2LCAweGZmZmZmZmZmZmZmZmZmZmZVTEwpOwoJCWFkYXB0ZXItPmhhc182NGJpdF9hZGRyID0gMTsKCX0gZWxzZSAgewoJCXBjaV9zZXRfZG1hX21hc2socGRldiwgMHhmZmZmZmZmZik7CgkJYWRhcHRlci0+aGFzXzY0Yml0X2FkZHIgPSAwOwoJfQoJCQoJaW5pdF9NVVRFWCgmYWRhcHRlci0+aW50X210eCk7Cglpbml0X3dhaXRxdWV1ZV9oZWFkKCZhZGFwdGVyLT5pbnRfd2FpdHEpOwoKCWFkYXB0ZXItPnRoaXNfaWQgPSBERUZBVUxUX0lOSVRJQVRPUl9JRDsKCWFkYXB0ZXItPmhvc3QtPnRoaXNfaWQgPSBERUZBVUxUX0lOSVRJQVRPUl9JRDsKCiNpZiBNRUdBX0hBVkVfQ0xVU1RFUklORwoJLyoKCSAqIElzIGNsdXN0ZXIgc3VwcG9ydCBlbmFibGVkIG9uIHRoaXMgY29udHJvbGxlcgoJICogTm90ZTogSW4gYSBjbHVzdGVyIHRoZSBIQkFzICggdGhlIGluaXRpYXRvcnMgKSB3aWxsIGhhdmUKCSAqIGRpZmZlcmVudCB0YXJnZXQgSURzIGFuZCB3ZSBjYW5ub3QgYXNzdW1lIGl0IHRvIGJlIDcuIENhbGwKCSAqIHRvIG1lZ2Ffc3VwcG9ydF9jbHVzdGVyKCkgd2lsbCBnZXQgdGhlIHRhcmdldCBpZHMgYWxzbyBpZgoJICogdGhlIGNsdXN0ZXIgc3VwcG9ydCBpcyBhdmFpbGFibGUKCSAqLwoJYWRhcHRlci0+aGFzX2NsdXN0ZXIgPSBtZWdhX3N1cHBvcnRfY2x1c3RlcihhZGFwdGVyKTsKCWlmIChhZGFwdGVyLT5oYXNfY2x1c3RlcikgewoJCXByaW50ayhLRVJOX05PVElDRQoJCQkibWVnYXJhaWQ6IENsdXN0ZXIgZHJpdmVyLCBpbml0aWF0b3IgaWQ6JWRcbiIsCgkJCWFkYXB0ZXItPnRoaXNfaWQpOwoJfQojZW5kaWYKCglwY2lfc2V0X2RydmRhdGEocGRldiwgaG9zdCk7CgoJbWVnYV9jcmVhdGVfcHJvY19lbnRyeShoYmFfY291bnQsIG1lZ2FfcHJvY19kaXJfZW50cnkpOwoKCWVycm9yID0gc2NzaV9hZGRfaG9zdChob3N0LCAmcGRldi0+ZGV2KTsKCWlmIChlcnJvcikKCQlnb3RvIG91dF9mcmVlX21ib3g7CgoJc2NzaV9zY2FuX2hvc3QoaG9zdCk7CgloYmFfY291bnQrKzsKCXJldHVybiAwOwoKIG91dF9mcmVlX21ib3g6CglwY2lfZnJlZV9jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwgc2l6ZW9mKG1ib3g2NF90KSwKCQkJYWRhcHRlci0+dW5hX21ib3g2NCwgYWRhcHRlci0+dW5hX21ib3g2NF9kbWEpOwogb3V0X2ZyZWVfaXJxOgoJZnJlZV9pcnEoYWRhcHRlci0+aG9zdC0+aXJxLCBhZGFwdGVyKTsKIG91dF9mcmVlX3NjYl9saXN0OgoJa2ZyZWUoYWRhcHRlci0+c2NiX2xpc3QpOwogb3V0X2ZyZWVfY21kX2J1ZmZlcjoKCXBjaV9mcmVlX2NvbnNpc3RlbnQoYWRhcHRlci0+ZGV2LCBNRUdBX0JVRkZFUl9TSVpFLAoJCQlhZGFwdGVyLT5tZWdhX2J1ZmZlciwgYWRhcHRlci0+YnVmX2RtYV9oYW5kbGUpOwogb3V0X2hvc3RfcHV0OgoJc2NzaV9ob3N0X3B1dChob3N0KTsKIG91dF9pb3VubWFwOgoJaWYgKGZsYWcgJiBCT0FSRF9NRU1NQVApCgkJaW91bm1hcCgodm9pZCAqKW1lZ2FfYmFzZXBvcnQpOwogb3V0X3JlbGVhc2VfcmVnaW9uOgoJaWYgKGZsYWcgJiBCT0FSRF9NRU1NQVApCgkJcmVsZWFzZV9tZW1fcmVnaW9uKHRiYXNlLCAxMjgpOwoJZWxzZQoJCXJlbGVhc2VfcmVnaW9uKG1lZ2FfYmFzZXBvcnQsIDE2KTsKIG91dF9kaXNhYmxlX2RldmljZToKCXBjaV9kaXNhYmxlX2RldmljZShwZGV2KTsKIG91dDoKCXJldHVybiBlcnJvcjsKfQoKc3RhdGljIHZvaWQKX19tZWdhcmFpZF9zaHV0ZG93bihhZGFwdGVyX3QgKmFkYXB0ZXIpCnsKCXVfY2hhcglyYXdfbWJveFtzaXplb2Yoc3RydWN0IG1ib3hfb3V0KV07CgltYm94X3QJKm1ib3ggPSAobWJveF90ICopcmF3X21ib3g7CglpbnQJaTsKCgkvKiBGbHVzaCBhZGFwdGVyIGNhY2hlICovCgltZW1zZXQoJm1ib3gtPm1fb3V0LCAwLCBzaXplb2YocmF3X21ib3gpKTsKCXJhd19tYm94WzBdID0gRkxVU0hfQURBUFRFUjsKCglmcmVlX2lycShhZGFwdGVyLT5ob3N0LT5pcnEsIGFkYXB0ZXIpOwoKCS8qIElzc3VlIGEgYmxvY2tpbmcgKGludGVycnVwdHMgZGlzYWJsZWQpIGNvbW1hbmQgdG8gdGhlIGNhcmQgKi8KCWlzc3VlX3NjYl9ibG9jayhhZGFwdGVyLCByYXdfbWJveCk7CgoJLyogRmx1c2ggZGlza3MgY2FjaGUgKi8KCW1lbXNldCgmbWJveC0+bV9vdXQsIDAsIHNpemVvZihyYXdfbWJveCkpOwoJcmF3X21ib3hbMF0gPSBGTFVTSF9TWVNURU07CgoJLyogSXNzdWUgYSBibG9ja2luZyAoaW50ZXJydXB0cyBkaXNhYmxlZCkgY29tbWFuZCB0byB0aGUgY2FyZCAqLwoJaXNzdWVfc2NiX2Jsb2NrKGFkYXB0ZXIsIHJhd19tYm94KTsKCQoJaWYgKGF0b21pY19yZWFkKCZhZGFwdGVyLT5wZW5kX2NtZHMpID4gMCkKCQlwcmludGsoS0VSTl9XQVJOSU5HICJtZWdhcmFpZDogcGVuZGluZyBjb21tYW5kcyEhXG4iKTsKCgkvKgoJICogSGF2ZSBhIGRlbGlicmF0ZSBkZWxheSB0byBtYWtlIHN1cmUgYWxsIHRoZSBjYWNoZXMgYXJlCgkgKiBhY3R1YWxseSBmbHVzaGVkLgoJICovCglmb3IgKGkgPSAwOyBpIDw9IDEwOyBpKyspCgkJbWRlbGF5KDEwMDApOwp9CgpzdGF0aWMgdm9pZAptZWdhcmFpZF9yZW1vdmVfb25lKHN0cnVjdCBwY2lfZGV2ICpwZGV2KQp7CglzdHJ1Y3QgU2NzaV9Ib3N0ICpob3N0ID0gcGNpX2dldF9kcnZkYXRhKHBkZXYpOwoJYWRhcHRlcl90ICphZGFwdGVyID0gKGFkYXB0ZXJfdCAqKWhvc3QtPmhvc3RkYXRhOwoJY2hhcglidWZbMTJdID0geyAwIH07CgoJc2NzaV9yZW1vdmVfaG9zdChob3N0KTsKCglfX21lZ2FyYWlkX3NodXRkb3duKGFkYXB0ZXIpOwoKCS8qIEZyZWUgb3VyIHJlc291cmNlcyAqLwoJaWYgKGFkYXB0ZXItPmZsYWcgJiBCT0FSRF9NRU1NQVApIHsKCQlpb3VubWFwKCh2b2lkICopYWRhcHRlci0+YmFzZSk7CgkJcmVsZWFzZV9tZW1fcmVnaW9uKGFkYXB0ZXItPmhvc3QtPmJhc2UsIDEyOCk7Cgl9IGVsc2UKCQlyZWxlYXNlX3JlZ2lvbihhZGFwdGVyLT5iYXNlLCAxNik7CgoJbWVnYV9mcmVlX3NnbChhZGFwdGVyKTsKCiNpZmRlZiBDT05GSUdfUFJPQ19GUwoJaWYgKGFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpIHsKCQlyZW1vdmVfcHJvY19lbnRyeSgic3RhdCIsIGFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpOwoJCXJlbW92ZV9wcm9jX2VudHJ5KCJjb25maWciLAoJCQkJYWRhcHRlci0+Y29udHJvbGxlcl9wcm9jX2Rpcl9lbnRyeSk7CgkJcmVtb3ZlX3Byb2NfZW50cnkoIm1haWxib3giLAoJCQkJYWRhcHRlci0+Y29udHJvbGxlcl9wcm9jX2Rpcl9lbnRyeSk7CiNpZiBNRUdBX0hBVkVfRU5IX1BST0MKCQlyZW1vdmVfcHJvY19lbnRyeSgicmVidWlsZC1yYXRlIiwKCQkJCWFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpOwoJCXJlbW92ZV9wcm9jX2VudHJ5KCJiYXR0ZXJ5LXN0YXR1cyIsCgkJCQlhZGFwdGVyLT5jb250cm9sbGVyX3Byb2NfZGlyX2VudHJ5KTsKCgkJcmVtb3ZlX3Byb2NfZW50cnkoImRpc2tkcml2ZXMtY2gwIiwKCQkJCWFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpOwoJCXJlbW92ZV9wcm9jX2VudHJ5KCJkaXNrZHJpdmVzLWNoMSIsCgkJCQlhZGFwdGVyLT5jb250cm9sbGVyX3Byb2NfZGlyX2VudHJ5KTsKCQlyZW1vdmVfcHJvY19lbnRyeSgiZGlza2RyaXZlcy1jaDIiLAoJCQkJYWRhcHRlci0+Y29udHJvbGxlcl9wcm9jX2Rpcl9lbnRyeSk7CgkJcmVtb3ZlX3Byb2NfZW50cnkoImRpc2tkcml2ZXMtY2gzIiwKCQkJCWFkYXB0ZXItPmNvbnRyb2xsZXJfcHJvY19kaXJfZW50cnkpOwoKCQlyZW1vdmVfcHJvY19lbnRyeSgicmFpZGRyaXZlcy0wLTkiLAoJCQkJYWRhcHRlci0+Y29udHJvbGxlcl9wcm9jX2Rpcl9lbnRyeSk7CgkJcmVtb3ZlX3Byb2NfZW50cnkoInJhaWRkcml2ZXMtMTAtMTkiLAoJCQkJYWRhcHRlci0+Y29udHJvbGxlcl9wcm9jX2Rpcl9lbnRyeSk7CgkJcmVtb3ZlX3Byb2NfZW50cnkoInJhaWRkcml2ZXMtMjAtMjkiLAoJCQkJYWRhcHRlci0+Y29udHJvbGxlcl9wcm9jX2Rpcl9lbnRyeSk7CgkJcmVtb3ZlX3Byb2NfZW50cnkoInJhaWRkcml2ZXMtMzAtMzkiLAoJCQkJYWRhcHRlci0+Y29udHJvbGxlcl9wcm9jX2Rpcl9lbnRyeSk7CiNlbmRpZgoJCXNwcmludGYoYnVmLCAiaGJhJWQiLCBhZGFwdGVyLT5ob3N0LT5ob3N0X25vKTsKCQlyZW1vdmVfcHJvY19lbnRyeShidWYsIG1lZ2FfcHJvY19kaXJfZW50cnkpOwoJfQojZW5kaWYKCglwY2lfZnJlZV9jb25zaXN0ZW50KGFkYXB0ZXItPmRldiwgTUVHQV9CVUZGRVJfU0laRSwKCQkJYWRhcHRlci0+bWVnYV9idWZmZXIsIGFkYXB0ZXItPmJ1Zl9kbWFfaGFuZGxlKTsKCWtmcmVlKGFkYXB0ZXItPnNjYl9saXN0KTsKCXBjaV9mcmVlX2NvbnNpc3RlbnQoYWRhcHRlci0+ZGV2LCBzaXplb2YobWJveDY0X3QpLAoJCQlhZGFwdGVyLT51bmFfbWJveDY0LCBhZGFwdGVyLT51bmFfbWJveDY0X2RtYSk7CgoJc2NzaV9ob3N0X3B1dChob3N0KTsKCXBjaV9kaXNhYmxlX2RldmljZShwZGV2KTsKCgloYmFfY291bnQtLTsKfQoKc3RhdGljIHZvaWQKbWVnYXJhaWRfc2h1dGRvd24oc3RydWN0IGRldmljZSAqZGV2KQp7CglzdHJ1Y3QgU2NzaV9Ib3N0ICpob3N0ID0gcGNpX2dldF9kcnZkYXRhKHRvX3BjaV9kZXYoZGV2KSk7CglhZGFwdGVyX3QgKmFkYXB0ZXIgPSAoYWRhcHRlcl90ICopaG9zdC0+aG9zdGRhdGE7CgoJX19tZWdhcmFpZF9zaHV0ZG93bihhZGFwdGVyKTsKfQoKc3RhdGljIHN0cnVjdCBwY2lfZGV2aWNlX2lkIG1lZ2FyYWlkX3BjaV90YmxbXSA9IHsKCXtQQ0lfVkVORE9SX0lEX0RFTEwsIFBDSV9ERVZJQ0VfSURfRElTQ09WRVJZLAoJCVBDSV9BTllfSUQsIFBDSV9BTllfSUQsIDAsIDAsIDB9LAoJe1BDSV9WRU5ET1JfSURfREVMTCwgUENJX0RFVklDRV9JRF9QRVJDNF9ESSwKCQlQQ0lfQU5ZX0lELCBQQ0lfQU5ZX0lELCAwLCAwLCBCT0FSRF82NEJJVH0sCgl7UENJX1ZFTkRPUl9JRF9MU0lfTE9HSUMsIFBDSV9ERVZJQ0VfSURfUEVSQzRfUUNfVkVSREUsCgkJUENJX0FOWV9JRCwgUENJX0FOWV9JRCwgMCwgMCwgQk9BUkRfNjRCSVR9LAoJe1BDSV9WRU5ET1JfSURfQU1JLCBQQ0lfREVWSUNFX0lEX0FNSV9NRUdBUkFJRCwKCQlQQ0lfQU5ZX0lELCBQQ0lfQU5ZX0lELCAwLCAwLCAwfSwKCXtQQ0lfVkVORE9SX0lEX0FNSSwgUENJX0RFVklDRV9JRF9BTUlfTUVHQVJBSUQyLAoJCVBDSV9BTllfSUQsIFBDSV9BTllfSUQsIDAsIDAsIDB9LAoJe1BDSV9WRU5ET1JfSURfQU1JLCBQQ0lfREVWSUNFX0lEX0FNSV9NRUdBUkFJRDMsCgkJUENJX0FOWV9JRCwgUENJX0FOWV9JRCwgMCwgMCwgMH0sCgl7UENJX1ZFTkRPUl9JRF9JTlRFTCwgUENJX0RFVklDRV9JRF9BTUlfTUVHQVJBSUQzLAoJCVBDSV9BTllfSUQsIFBDSV9BTllfSUQsIDAsIDAsIDB9LAoJe1BDSV9WRU5ET1JfSURfTFNJX0xPR0lDLCBQQ0lfREVWSUNFX0lEX0FNSV9NRUdBUkFJRDMsCgkJUENJX0FOWV9JRCwgUENJX0FOWV9JRCwgMCwgMCwgMH0sCgl7MCx9Cn07Ck1PRFVMRV9ERVZJQ0VfVEFCTEUocGNpLCBtZWdhcmFpZF9wY2lfdGJsKTsKCnN0YXRpYyBzdHJ1Y3QgcGNpX2RyaXZlciBtZWdhcmFpZF9wY2lfZHJpdmVyID0gewoJLm5hbWUJCT0gIm1lZ2FyYWlkIiwKCS5pZF90YWJsZQk9IG1lZ2FyYWlkX3BjaV90YmwsCgkucHJvYmUJCT0gbWVnYXJhaWRfcHJvYmVfb25lLAoJLnJlbW92ZQkJPSBfX2RldmV4aXRfcChtZWdhcmFpZF9yZW1vdmVfb25lKSwKCS5kcml2ZXIJCT0gewoJCS5zaHV0ZG93biA9IG1lZ2FyYWlkX3NodXRkb3duLAoJfSwKfTsKCnN0YXRpYyBpbnQgX19pbml0IG1lZ2FyYWlkX2luaXQodm9pZCkKewoJaW50IGVycm9yOwoKCWlmICgobWF4X2NtZF9wZXJfbHVuIDw9IDApIHx8IChtYXhfY21kX3Blcl9sdW4gPiBNQVhfQ01EX1BFUl9MVU4pKQoJCW1heF9jbWRfcGVyX2x1biA9IE1BWF9DTURfUEVSX0xVTjsKCWlmIChtYXhfbWJveF9idXN5X3dhaXQgPiBNQk9YX0JVU1lfV0FJVCkKCQltYXhfbWJveF9idXN5X3dhaXQgPSBNQk9YX0JVU1lfV0FJVDsKCiNpZmRlZiBDT05GSUdfUFJPQ19GUwoJbWVnYV9wcm9jX2Rpcl9lbnRyeSA9IHByb2NfbWtkaXIoIm1lZ2FyYWlkIiwgJnByb2Nfcm9vdCk7CglpZiAoIW1lZ2FfcHJvY19kaXJfZW50cnkpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCQkibWVnYXJhaWQ6IGZhaWxlZCB0byBjcmVhdGUgbWVnYXJhaWQgcm9vdFxuIik7Cgl9CiNlbmRpZgoJZXJyb3IgPSBwY2lfbW9kdWxlX2luaXQoJm1lZ2FyYWlkX3BjaV9kcml2ZXIpOwoJaWYgKGVycm9yKSB7CiNpZmRlZiBDT05GSUdfUFJPQ19GUwoJCXJlbW92ZV9wcm9jX2VudHJ5KCJtZWdhcmFpZCIsICZwcm9jX3Jvb3QpOwojZW5kaWYKCQlyZXR1cm4gZXJyb3I7Cgl9CgoJLyoKCSAqIFJlZ2lzdGVyIHRoZSBkcml2ZXIgYXMgYSBjaGFyYWN0ZXIgZGV2aWNlLCBmb3IgYXBwbGljYXRpb25zCgkgKiB0byBhY2Nlc3MgaXQgZm9yIGlvY3Rscy4KCSAqIEZpcnN0IGFyZ3VtZW50IChtYWpvcikgdG8gcmVnaXN0ZXJfY2hyZGV2IGltcGxpZXMgYSBkeW5hbWljCgkgKiBtYWpvciBudW1iZXIgYWxsb2NhdGlvbi4KCSAqLwoJbWFqb3IgPSByZWdpc3Rlcl9jaHJkZXYoMCwgIm1lZ2FkZXYiLCAmbWVnYWRldl9mb3BzKTsKCWlmICghbWFqb3IpIHsKCQlwcmludGsoS0VSTl9XQVJOSU5HCgkJCQkibWVnYXJhaWQ6IGZhaWxlZCB0byByZWdpc3RlciBjaGFyIGRldmljZVxuIik7Cgl9CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIF9fZXhpdCBtZWdhcmFpZF9leGl0KHZvaWQpCnsKCS8qCgkgKiBVbnJlZ2lzdGVyIHRoZSBjaGFyYWN0ZXIgZGV2aWNlIGludGVyZmFjZSB0byB0aGUgZHJpdmVyLgoJICovCgl1bnJlZ2lzdGVyX2NocmRldihtYWpvciwgIm1lZ2FkZXYiKTsKCglwY2lfdW5yZWdpc3Rlcl9kcml2ZXIoJm1lZ2FyYWlkX3BjaV9kcml2ZXIpOwoKI2lmZGVmIENPTkZJR19QUk9DX0ZTCglyZW1vdmVfcHJvY19lbnRyeSgibWVnYXJhaWQiLCAmcHJvY19yb290KTsKI2VuZGlmCn0KCm1vZHVsZV9pbml0KG1lZ2FyYWlkX2luaXQpOwptb2R1bGVfZXhpdChtZWdhcmFpZF9leGl0KTsKCi8qIHZpOiBzZXQgdHM9OCBzdz04IHR3PTc4OiAqLwo=