LyogCiAgIEJORVAgaW1wbGVtZW50YXRpb24gZm9yIExpbnV4IEJsdWV0b290aCBzdGFjayAoQmx1ZVopLgogICBDb3B5cmlnaHQgKEMpIDIwMDEtMjAwMiBJbnZlbnRlbCBTeXN0ZW1lcwogICBXcml0dGVuIDIwMDEtMjAwMiBieQoJQ2zpbWVudCBNb3JlYXUgPGNsZW1lbnQubW9yZWF1QGludmVudGVsLmZyPgoJRGF2aWQgTGliYXVsdCAgPGRhdmlkLmxpYmF1bHRAaW52ZW50ZWwuZnI+CgogICBDb3B5cmlnaHQgKEMpIDIwMDIgTWF4aW0gS3Jhc255YW5za3kgPG1heGtAcXVhbGNvbW0uY29tPgoKICAgVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU7IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnkKICAgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSB2ZXJzaW9uIDIgYXMKICAgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247CgogICBUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUwogICBPUiBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKICAgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVCBPRiBUSElSRCBQQVJUWSBSSUdIVFMuCiAgIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQgSE9MREVSKFMpIEFORCBBVVRIT1IoUykgQkUgTElBQkxFIEZPUiBBTlkKICAgQ0xBSU0sIE9SIEFOWSBTUEVDSUFMIElORElSRUNUIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUywgT1IgQU5ZIERBTUFHRVMgCiAgIFdIQVRTT0VWRVIgUkVTVUxUSU5HIEZST00gTE9TUyBPRiBVU0UsIERBVEEgT1IgUFJPRklUUywgV0hFVEhFUiBJTiBBTiAKICAgQUNUSU9OIE9GIENPTlRSQUNULCBORUdMSUdFTkNFIE9SIE9USEVSIFRPUlRJT1VTIEFDVElPTiwgQVJJU0lORyBPVVQgT0YgCiAgIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgVVNFIE9SIFBFUkZPUk1BTkNFIE9GIFRISVMgU09GVFdBUkUuCgogICBBTEwgTElBQklMSVRZLCBJTkNMVURJTkcgTElBQklMSVRZIEZPUiBJTkZSSU5HRU1FTlQgT0YgQU5ZIFBBVEVOVFMsIAogICBDT1BZUklHSFRTLCBUUkFERU1BUktTIE9SIE9USEVSIFJJR0hUUywgUkVMQVRJTkcgVE8gVVNFIE9GIFRISVMgCiAgIFNPRlRXQVJFIElTIERJU0NMQUlNRUQuCiovCgovKgogKiAkSWQ6IGNvcmUuYyx2IDEuMjAgMjAwMi8wOC8wNCAyMToyMzo1OCBtYXhrIEV4cCAkCiAqLyAKCiNpbmNsdWRlIDxsaW51eC9jb25maWcuaD4KI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgoKI2luY2x1ZGUgPGxpbnV4L2tlcm5lbC5oPgojaW5jbHVkZSA8bGludXgvc2NoZWQuaD4KI2luY2x1ZGUgPGxpbnV4L3NpZ25hbC5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvd2FpdC5oPgojaW5jbHVkZSA8bGludXgvZXJybm8uaD4KI2luY2x1ZGUgPGxpbnV4L3NtcF9sb2NrLmg+CiNpbmNsdWRlIDxsaW51eC9uZXQuaD4KI2luY2x1ZGUgPG5ldC9zb2NrLmg+CgojaW5jbHVkZSA8bGludXgvc29ja2V0Lmg+CiNpbmNsdWRlIDxsaW51eC9maWxlLmg+CgojaW5jbHVkZSA8bGludXgvbmV0ZGV2aWNlLmg+CiNpbmNsdWRlIDxsaW51eC9ldGhlcmRldmljZS5oPgojaW5jbHVkZSA8bGludXgvc2tidWZmLmg+CgojaW5jbHVkZSA8YXNtL3VuYWxpZ25lZC5oPgoKI2luY2x1ZGUgPG5ldC9ibHVldG9vdGgvYmx1ZXRvb3RoLmg+CiNpbmNsdWRlIDxuZXQvYmx1ZXRvb3RoL2wyY2FwLmg+CgojaW5jbHVkZSAiYm5lcC5oIgoKI2lmbmRlZiBDT05GSUdfQlRfQk5FUF9ERUJVRwojdW5kZWYgIEJUX0RCRwojZGVmaW5lIEJUX0RCRyhELi4uKQojZW5kaWYKCiNkZWZpbmUgVkVSU0lPTiAiMS4yIgoKc3RhdGljIExJU1RfSEVBRChibmVwX3Nlc3Npb25fbGlzdCk7CnN0YXRpYyBERUNMQVJFX1JXU0VNKGJuZXBfc2Vzc2lvbl9zZW0pOwoKc3RhdGljIHN0cnVjdCBibmVwX3Nlc3Npb24gKl9fYm5lcF9nZXRfc2Vzc2lvbih1OCAqZHN0KQp7CglzdHJ1Y3QgYm5lcF9zZXNzaW9uICpzOwoJc3RydWN0IGxpc3RfaGVhZCAqcDsKCglCVF9EQkcoIiIpOwoKCWxpc3RfZm9yX2VhY2gocCwgJmJuZXBfc2Vzc2lvbl9saXN0KSB7CgkJcyA9IGxpc3RfZW50cnkocCwgc3RydWN0IGJuZXBfc2Vzc2lvbiwgbGlzdCk7CQoJCWlmICghbWVtY21wKGRzdCwgcy0+ZWguaF9zb3VyY2UsIEVUSF9BTEVOKSkKCQkJcmV0dXJuIHM7Cgl9CglyZXR1cm4gTlVMTDsKfQoKc3RhdGljIHZvaWQgX19ibmVwX2xpbmtfc2Vzc2lvbihzdHJ1Y3QgYm5lcF9zZXNzaW9uICpzKQp7CgkvKiBJdCdzIHNhZmUgdG8gY2FsbCBfX21vZHVsZV9nZXQoKSBoZXJlIGJlY2F1c2Ugc2Vzc2lvbnMgYXJlIGFkZGVkCgkgICBieSB0aGUgc29ja2V0IGxheWVyIHdoaWNoIGhhcyB0byBob2xkIHRoZSByZWZmZXJlbmNlIHRvIHRoaXMgbW9kdWxlLgoJICovCglfX21vZHVsZV9nZXQoVEhJU19NT0RVTEUpOwoJbGlzdF9hZGQoJnMtPmxpc3QsICZibmVwX3Nlc3Npb25fbGlzdCk7CQp9CgpzdGF0aWMgdm9pZCBfX2JuZXBfdW5saW5rX3Nlc3Npb24oc3RydWN0IGJuZXBfc2Vzc2lvbiAqcykKewoJbGlzdF9kZWwoJnMtPmxpc3QpOwoJbW9kdWxlX3B1dChUSElTX01PRFVMRSk7Cn0KCnN0YXRpYyBpbnQgYm5lcF9zZW5kKHN0cnVjdCBibmVwX3Nlc3Npb24gKnMsIHZvaWQgKmRhdGEsIHNpemVfdCBsZW4pCnsKCXN0cnVjdCBzb2NrZXQgKnNvY2sgPSBzLT5zb2NrOwoJc3RydWN0IGt2ZWMgaXYgPSB7IGRhdGEsIGxlbiB9OwoKCXJldHVybiBrZXJuZWxfc2VuZG1zZyhzb2NrLCAmcy0+bXNnLCAmaXYsIDEsIGxlbik7Cn0KCnN0YXRpYyBpbnQgYm5lcF9zZW5kX3JzcChzdHJ1Y3QgYm5lcF9zZXNzaW9uICpzLCB1OCBjdHJsLCB1MTYgcmVzcCkKewoJc3RydWN0IGJuZXBfY29udHJvbF9yc3AgcnNwOwoJcnNwLnR5cGUgPSBCTkVQX0NPTlRST0w7Cglyc3AuY3RybCA9IGN0cmw7Cglyc3AucmVzcCA9IGh0b25zKHJlc3ApOwoJcmV0dXJuIGJuZXBfc2VuZChzLCAmcnNwLCBzaXplb2YocnNwKSk7Cn0KCiNpZmRlZiBDT05GSUdfQlRfQk5FUF9QUk9UT19GSUxURVIKc3RhdGljIGlubGluZSB2b2lkIGJuZXBfc2V0X2RlZmF1bHRfcHJvdG9fZmlsdGVyKHN0cnVjdCBibmVwX3Nlc3Npb24gKnMpCnsKCS8qIChJUHY0LCBBUlApICAqLwoJcy0+cHJvdG9fZmlsdGVyWzBdLnN0YXJ0ID0gaHRvbnMoMHgwODAwKTsKCXMtPnByb3RvX2ZpbHRlclswXS5lbmQgICA9IGh0b25zKDB4MDgwNik7CgkvKiAoUkFSUCwgQXBwbGVUYWxrKSAqLwoJcy0+cHJvdG9fZmlsdGVyWzFdLnN0YXJ0ID0gaHRvbnMoMHg4MDM1KTsKCXMtPnByb3RvX2ZpbHRlclsxXS5lbmQgICA9IGh0b25zKDB4ODBGMyk7CgkvKiAoSVBYLCBJUHY2KSAqLwoJcy0+cHJvdG9fZmlsdGVyWzJdLnN0YXJ0ID0gaHRvbnMoMHg4MTM3KTsKCXMtPnByb3RvX2ZpbHRlclsyXS5lbmQgICA9IGh0b25zKDB4ODZERCk7Cn0KI2VuZGlmCgpzdGF0aWMgaW50IGJuZXBfY3RybF9zZXRfbmV0ZmlsdGVyKHN0cnVjdCBibmVwX3Nlc3Npb24gKnMsIHUxNiAqZGF0YSwgaW50IGxlbikKewoJaW50IG47CgoJaWYgKGxlbiA8IDIpCgkJcmV0dXJuIC1FSUxTRVE7CgoJbiA9IG50b2hzKGdldF91bmFsaWduZWQoZGF0YSkpOwoJZGF0YSsrOyBsZW4gLT0gMjsKCglpZiAobGVuIDwgbikKCQlyZXR1cm4gLUVJTFNFUTsKCglCVF9EQkcoImZpbHRlciBsZW4gJWQiLCBuKTsKCiNpZmRlZiBDT05GSUdfQlRfQk5FUF9QUk9UT19GSUxURVIKCW4gLz0gNDsKCWlmIChuIDw9IEJORVBfTUFYX1BST1RPX0ZJTFRFUlMpIHsKCQlzdHJ1Y3QgYm5lcF9wcm90b19maWx0ZXIgKmYgPSBzLT5wcm90b19maWx0ZXI7CgkJaW50IGk7CgoJCWZvciAoaSA9IDA7IGkgPCBuOyBpKyspIHsKCQkJZltpXS5zdGFydCA9IGdldF91bmFsaWduZWQoZGF0YSsrKTsKCQkJZltpXS5lbmQgICA9IGdldF91bmFsaWduZWQoZGF0YSsrKTsKCgkJCUJUX0RCRygicHJvdG8gZmlsdGVyIHN0YXJ0ICVkIGVuZCAlZCIsCgkJCQlmW2ldLnN0YXJ0LCBmW2ldLmVuZCk7CgkJfQoKCQlpZiAoaSA8IEJORVBfTUFYX1BST1RPX0ZJTFRFUlMpCgkJCW1lbXNldChmICsgaSwgMCwgc2l6ZW9mKCpmKSk7CgoJCWlmIChuID09IDApCgkJCWJuZXBfc2V0X2RlZmF1bHRfcHJvdG9fZmlsdGVyKHMpOwoKCQlibmVwX3NlbmRfcnNwKHMsIEJORVBfRklMVEVSX05FVF9UWVBFX1JTUCwgQk5FUF9TVUNDRVNTKTsKCX0gZWxzZSB7CgkJYm5lcF9zZW5kX3JzcChzLCBCTkVQX0ZJTFRFUl9ORVRfVFlQRV9SU1AsIEJORVBfRklMVEVSX0xJTUlUX1JFQUNIRUQpOwoJfQojZWxzZQoJYm5lcF9zZW5kX3JzcChzLCBCTkVQX0ZJTFRFUl9ORVRfVFlQRV9SU1AsIEJORVBfRklMVEVSX1VOU1VQUE9SVEVEX1JFUSk7CiNlbmRpZgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgYm5lcF9jdHJsX3NldF9tY2ZpbHRlcihzdHJ1Y3QgYm5lcF9zZXNzaW9uICpzLCB1OCAqZGF0YSwgaW50IGxlbikKewoJaW50IG47CgoJaWYgKGxlbiA8IDIpCgkJcmV0dXJuIC1FSUxTRVE7CgoJbiA9IG50b2hzKGdldF91bmFsaWduZWQoKHUxNiAqKSBkYXRhKSk7IAoJZGF0YSArPSAyOyBsZW4gLT0gMjsKCglpZiAobGVuIDwgbikKCQlyZXR1cm4gLUVJTFNFUTsKCglCVF9EQkcoImZpbHRlciBsZW4gJWQiLCBuKTsKCiNpZmRlZiBDT05GSUdfQlRfQk5FUF9NQ19GSUxURVIKCW4gLz0gKEVUSF9BTEVOICogMik7CgoJaWYgKG4gPiAwKSB7CgkJcy0+bWNfZmlsdGVyID0gMDsKCgkJLyogQWx3YXlzIHNlbmQgYnJvYWRjYXN0ICovCgkJc2V0X2JpdChibmVwX21jX2hhc2gocy0+ZGV2LT5icm9hZGNhc3QpLCAodWxvbmcgKikgJnMtPm1jX2ZpbHRlcik7CgoJCS8qIEFkZCBhZGRyZXNzIHJhbmdlcyB0byB0aGUgbXVsdGljYXN0IGhhc2ggKi8KCQlmb3IgKDsgbiA+IDA7IG4tLSkgewoJCQl1OCBhMVs2XSwgKmEyOwoKCQkJbWVtY3B5KGExLCBkYXRhLCBFVEhfQUxFTik7IGRhdGEgKz0gRVRIX0FMRU47CgkJCWEyID0gZGF0YTsgZGF0YSArPSBFVEhfQUxFTjsKCQoJCQlCVF9EQkcoIm1jIGZpbHRlciAlcyAtPiAlcyIsCgkJCQliYXRvc3RyKCh2b2lkICopIGExKSwgYmF0b3N0cigodm9pZCAqKSBhMikpOwoKCQkJI2RlZmluZSBJTkNBKGEpIHsgaW50IGkgPSA1OyB3aGlsZSAoaSA+PTAgJiYgKythW2ktLV0gPT0gMCk7IH0KCgkJCS8qIEl0ZXJhdGUgZnJvbSBhMSB0byBhMiAqLwoJCQlzZXRfYml0KGJuZXBfbWNfaGFzaChhMSksICh1bG9uZyAqKSAmcy0+bWNfZmlsdGVyKTsKCQkJd2hpbGUgKG1lbWNtcChhMSwgYTIsIDYpIDwgMCAmJiBzLT5tY19maWx0ZXIgIT0gfjBMTCkgewoJCQkJSU5DQShhMSk7CgkJCQlzZXRfYml0KGJuZXBfbWNfaGFzaChhMSksICh1bG9uZyAqKSAmcy0+bWNfZmlsdGVyKTsKCQkJfQoJCX0KCX0KCglCVF9EQkcoIm1jIGZpbHRlciBoYXNoIDB4JWxseCIsIHMtPm1jX2ZpbHRlcik7CgoJYm5lcF9zZW5kX3JzcChzLCBCTkVQX0ZJTFRFUl9NVUxUSV9BRERSX1JTUCwgQk5FUF9TVUNDRVNTKTsKI2Vsc2UKCWJuZXBfc2VuZF9yc3AocywgQk5FUF9GSUxURVJfTVVMVElfQUREUl9SU1AsIEJORVBfRklMVEVSX1VOU1VQUE9SVEVEX1JFUSk7CiNlbmRpZgoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgYm5lcF9yeF9jb250cm9sKHN0cnVjdCBibmVwX3Nlc3Npb24gKnMsIHZvaWQgKmRhdGEsIGludCBsZW4pCnsKCXU4ICBjbWQgPSAqKHU4ICopZGF0YTsKCWludCBlcnIgPSAwOwoKCWRhdGErKzsgbGVuLS07CgoJc3dpdGNoIChjbWQpIHsKCWNhc2UgQk5FUF9DTURfTk9UX1VOREVSU1RPT0Q6CgljYXNlIEJORVBfU0VUVVBfQ09OTl9SRVE6CgljYXNlIEJORVBfU0VUVVBfQ09OTl9SU1A6CgljYXNlIEJORVBfRklMVEVSX05FVF9UWVBFX1JTUDoKCWNhc2UgQk5FUF9GSUxURVJfTVVMVElfQUREUl9SU1A6CgkJLyogSWdub3JlIHRoZXNlIGZvciBub3cgKi8KCQlicmVhazsKCgljYXNlIEJORVBfRklMVEVSX05FVF9UWVBFX1NFVDoKCQllcnIgPSBibmVwX2N0cmxfc2V0X25ldGZpbHRlcihzLCBkYXRhLCBsZW4pOwoJCWJyZWFrOwoKCWNhc2UgQk5FUF9GSUxURVJfTVVMVElfQUREUl9TRVQ6CgkJZXJyID0gYm5lcF9jdHJsX3NldF9tY2ZpbHRlcihzLCBkYXRhLCBsZW4pOwoJCWJyZWFrOwoKCWRlZmF1bHQ6IHsKCQkJdTggcGt0WzNdOwoJCQlwa3RbMF0gPSBCTkVQX0NPTlRST0w7CgkJCXBrdFsxXSA9IEJORVBfQ01EX05PVF9VTkRFUlNUT09EOwoJCQlwa3RbMl0gPSBjbWQ7CgkJCWJuZXBfc2VuZChzLCBwa3QsIHNpemVvZihwa3QpKTsKCQl9CgkJYnJlYWs7Cgl9CgoJcmV0dXJuIGVycjsKfQoKc3RhdGljIGludCBibmVwX3J4X2V4dGVuc2lvbihzdHJ1Y3QgYm5lcF9zZXNzaW9uICpzLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CglzdHJ1Y3QgYm5lcF9leHRfaGRyICpoOwoJaW50IGVyciA9IDA7CgoJZG8gewoJCWggPSAodm9pZCAqKSBza2ItPmRhdGE7CgkJaWYgKCFza2JfcHVsbChza2IsIHNpemVvZigqaCkpKSB7CgkJCWVyciA9IC1FSUxTRVE7CgkJCWJyZWFrOwoJCX0KCgkJQlRfREJHKCJ0eXBlIDB4JXggbGVuICVkIiwgaC0+dHlwZSwgaC0+bGVuKTsKCQoJCXN3aXRjaCAoaC0+dHlwZSAmIEJORVBfVFlQRV9NQVNLKSB7CgkJY2FzZSBCTkVQX0VYVF9DT05UUk9MOgoJCQlibmVwX3J4X2NvbnRyb2wocywgc2tiLT5kYXRhLCBza2ItPmxlbik7CgkJCWJyZWFrOwoKCQlkZWZhdWx0OgoJCQkvKiBVbmtub3duIGV4dGVuc2lvbiwgc2tpcCBpdC4gKi8KCQkJYnJlYWs7CgkJfQoKCQlpZiAoIXNrYl9wdWxsKHNrYiwgaC0+bGVuKSkgewoJCQllcnIgPSAtRUlMU0VROwoJCQlicmVhazsKCQl9Cgl9IHdoaWxlICghZXJyICYmIChoLT50eXBlICYgQk5FUF9FWFRfSEVBREVSKSk7CgkKCXJldHVybiBlcnI7Cn0KCnN0YXRpYyB1OCBfX2JuZXBfcnhfaGxlbltdID0gewoJRVRIX0hMRU4sICAgICAvKiBCTkVQX0dFTkVSQUwgKi8KCTAsICAgICAgICAgICAgLyogQk5FUF9DT05UUk9MICovCgkyLCAgICAgICAgICAgIC8qIEJORVBfQ09NUFJFU1NFRCAqLwoJRVRIX0FMRU4gKyAyLCAvKiBCTkVQX0NPTVBSRVNTRURfU1JDX09OTFkgKi8KCUVUSF9BTEVOICsgMiAgLyogQk5FUF9DT01QUkVTU0VEX0RTVF9PTkxZICovCn07CiNkZWZpbmUgQk5FUF9SWF9UWVBFUwkoc2l6ZW9mKF9fYm5lcF9yeF9obGVuKSAtIDEpCgpzdGF0aWMgaW5saW5lIGludCBibmVwX3J4X2ZyYW1lKHN0cnVjdCBibmVwX3Nlc3Npb24gKnMsIHN0cnVjdCBza19idWZmICpza2IpCnsKCXN0cnVjdCBuZXRfZGV2aWNlICpkZXYgPSBzLT5kZXY7CglzdHJ1Y3Qgc2tfYnVmZiAqbnNrYjsKCXU4IHR5cGU7CgoJZGV2LT5sYXN0X3J4ID0gamlmZmllczsKCXMtPnN0YXRzLnJ4X2J5dGVzICs9IHNrYi0+bGVuOwoKCXR5cGUgPSAqKHU4ICopIHNrYi0+ZGF0YTsgc2tiX3B1bGwoc2tiLCAxKTsKCglpZiAoKHR5cGUgJiBCTkVQX1RZUEVfTUFTSykgPiBCTkVQX1JYX1RZUEVTKQoJCWdvdG8gYmFkZnJhbWU7CgkKCWlmICgodHlwZSAmIEJORVBfVFlQRV9NQVNLKSA9PSBCTkVQX0NPTlRST0wpIHsKCQlibmVwX3J4X2NvbnRyb2wocywgc2tiLT5kYXRhLCBza2ItPmxlbik7CgkJa2ZyZWVfc2tiKHNrYik7CgkJcmV0dXJuIDA7Cgl9CgoJc2tiLT5tYWMucmF3ID0gc2tiLT5kYXRhOwoKCS8qIFZlcmlmeSBhbmQgcHVsbCBvdXQgaGVhZGVyICovCglpZiAoIXNrYl9wdWxsKHNrYiwgX19ibmVwX3J4X2hsZW5bdHlwZSAmIEJORVBfVFlQRV9NQVNLXSkpCgkJZ290byBiYWRmcmFtZTsKCglzLT5laC5oX3Byb3RvID0gZ2V0X3VuYWxpZ25lZCgodTE2ICopIChza2ItPmRhdGEgLSAyKSk7CgoJaWYgKHR5cGUgJiBCTkVQX0VYVF9IRUFERVIpIHsKCQlpZiAoYm5lcF9yeF9leHRlbnNpb24ocywgc2tiKSA8IDApCgkJCWdvdG8gYmFkZnJhbWU7Cgl9CgoJLyogU3RyaXAgODAyLjFwIGhlYWRlciAqLwoJaWYgKG50b2hzKHMtPmVoLmhfcHJvdG8pID09IDB4ODEwMCkgewoJCWlmICghc2tiX3B1bGwoc2tiLCA0KSkKCQkJZ290byBiYWRmcmFtZTsKCQlzLT5laC5oX3Byb3RvID0gZ2V0X3VuYWxpZ25lZCgodTE2ICopIChza2ItPmRhdGEgLSAyKSk7Cgl9CgkKCS8qIFdlIGhhdmUgdG8gYWxsb2MgbmV3IHNrYiBhbmQgY29weSBkYXRhIGhlcmUgOiguIEJlY2F1c2Ugb3JpZ2luYWwgc2tiCgkgKiBtYXkgbm90IGJlIG1vZGlmaWVkIGFuZCBiZWNhdXNlIG9mIHRoZSBhbGlnbm1lbnQgcmVxdWlyZW1lbnRzLiAqLwoJbnNrYiA9IGFsbG9jX3NrYigyICsgRVRIX0hMRU4gKyBza2ItPmxlbiwgR0ZQX0tFUk5FTCk7CglpZiAoIW5za2IpIHsKCQlzLT5zdGF0cy5yeF9kcm9wcGVkKys7CgkJa2ZyZWVfc2tiKHNrYik7CgkJcmV0dXJuIC1FTk9NRU07Cgl9Cglza2JfcmVzZXJ2ZShuc2tiLCAyKTsKCgkvKiBEZWNvbXByZXNzIGhlYWRlciBhbmQgY29uc3RydWN0IGV0aGVyIGZyYW1lICovCglzd2l0Y2ggKHR5cGUgJiBCTkVQX1RZUEVfTUFTSykgewoJY2FzZSBCTkVQX0NPTVBSRVNTRUQ6CgkJbWVtY3B5KF9fc2tiX3B1dChuc2tiLCBFVEhfSExFTiksICZzLT5laCwgRVRIX0hMRU4pOwoJCWJyZWFrOwoJCgljYXNlIEJORVBfQ09NUFJFU1NFRF9TUkNfT05MWToKCQltZW1jcHkoX19za2JfcHV0KG5za2IsIEVUSF9BTEVOKSwgcy0+ZWguaF9kZXN0LCBFVEhfQUxFTik7CgkJbWVtY3B5KF9fc2tiX3B1dChuc2tiLCBFVEhfQUxFTiksIHNrYi0+bWFjLnJhdywgRVRIX0FMRU4pOwoJCXB1dF91bmFsaWduZWQocy0+ZWguaF9wcm90bywgKHUxNiAqKSBfX3NrYl9wdXQobnNrYiwgMikpOwoJCWJyZWFrOwoKCWNhc2UgQk5FUF9DT01QUkVTU0VEX0RTVF9PTkxZOgoJCW1lbWNweShfX3NrYl9wdXQobnNrYiwgRVRIX0FMRU4pLCBza2ItPm1hYy5yYXcsIEVUSF9BTEVOKTsKCQltZW1jcHkoX19za2JfcHV0KG5za2IsIEVUSF9BTEVOICsgMiksIHMtPmVoLmhfc291cmNlLCBFVEhfQUxFTiArIDIpOwoJCWJyZWFrOwoKCWNhc2UgQk5FUF9HRU5FUkFMOgoJCW1lbWNweShfX3NrYl9wdXQobnNrYiwgRVRIX0FMRU4gKiAyKSwgc2tiLT5tYWMucmF3LCBFVEhfQUxFTiAqIDIpOwoJCXB1dF91bmFsaWduZWQocy0+ZWguaF9wcm90bywgKHUxNiAqKSBfX3NrYl9wdXQobnNrYiwgMikpOwoJCWJyZWFrOwoJfQoKCW1lbWNweShfX3NrYl9wdXQobnNrYiwgc2tiLT5sZW4pLCBza2ItPmRhdGEsIHNrYi0+bGVuKTsKCWtmcmVlX3NrYihza2IpOwoJCglzLT5zdGF0cy5yeF9wYWNrZXRzKys7Cgluc2tiLT5kZXYgICAgICAgPSBkZXY7Cgluc2tiLT5pcF9zdW1tZWQgPSBDSEVDS1NVTV9OT05FOwoJbnNrYi0+cHJvdG9jb2wgID0gZXRoX3R5cGVfdHJhbnMobnNrYiwgZGV2KTsKCW5ldGlmX3J4X25pKG5za2IpOwoJcmV0dXJuIDA7CgpiYWRmcmFtZToKCXMtPnN0YXRzLnJ4X2Vycm9ycysrOwoJa2ZyZWVfc2tiKHNrYik7CglyZXR1cm4gMDsKfQoKc3RhdGljIHU4IF9fYm5lcF90eF90eXBlc1tdID0gewoJQk5FUF9HRU5FUkFMLAoJQk5FUF9DT01QUkVTU0VEX1NSQ19PTkxZLAoJQk5FUF9DT01QUkVTU0VEX0RTVF9PTkxZLAoJQk5FUF9DT01QUkVTU0VECn07CgpzdGF0aWMgaW5saW5lIGludCBibmVwX3R4X2ZyYW1lKHN0cnVjdCBibmVwX3Nlc3Npb24gKnMsIHN0cnVjdCBza19idWZmICpza2IpCnsKCXN0cnVjdCBldGhoZHIgKmVoID0gKHZvaWQgKikgc2tiLT5kYXRhOwoJc3RydWN0IHNvY2tldCAqc29jayA9IHMtPnNvY2s7CglzdHJ1Y3Qga3ZlYyBpdlszXTsKCWludCBsZW4gPSAwLCBpbCA9IDA7Cgl1OCB0eXBlID0gMDsKCglCVF9EQkcoInNrYiAlcCBkZXYgJXAgdHlwZSAlZCIsIHNrYiwgc2tiLT5kZXYsIHNrYi0+cGt0X3R5cGUpOwoKCWlmICghc2tiLT5kZXYpIHsKCQkvKiBDb250cm9sIGZyYW1lIHNlbnQgYnkgdXMgKi8KCQlnb3RvIHNlbmQ7Cgl9CgoJaXZbaWwrK10gPSAoc3RydWN0IGt2ZWMpIHsgJnR5cGUsIDEgfTsKCWxlbisrOwoKCWlmICghbWVtY21wKGVoLT5oX2Rlc3QsIHMtPmVoLmhfc291cmNlLCBFVEhfQUxFTikpCgkJdHlwZSB8PSAweDAxOwoKCWlmICghbWVtY21wKGVoLT5oX3NvdXJjZSwgcy0+ZWguaF9kZXN0LCBFVEhfQUxFTikpCgkJdHlwZSB8PSAweDAyOwoKCWlmICh0eXBlKQoJCXNrYl9wdWxsKHNrYiwgRVRIX0FMRU4gKiAyKTsKCgl0eXBlID0gX19ibmVwX3R4X3R5cGVzW3R5cGVdOwoJc3dpdGNoICh0eXBlKSB7CgljYXNlIEJORVBfQ09NUFJFU1NFRF9TUkNfT05MWToKCQlpdltpbCsrXSA9IChzdHJ1Y3Qga3ZlYykgeyBlaC0+aF9zb3VyY2UsIEVUSF9BTEVOIH07CgkJbGVuICs9IEVUSF9BTEVOOwoJCWJyZWFrOwoJCQoJY2FzZSBCTkVQX0NPTVBSRVNTRURfRFNUX09OTFk6CgkJaXZbaWwrK10gPSAoc3RydWN0IGt2ZWMpIHsgZWgtPmhfZGVzdCwgRVRIX0FMRU4gfTsKCQlsZW4gKz0gRVRIX0FMRU47CgkJYnJlYWs7Cgl9CgpzZW5kOgoJaXZbaWwrK10gPSAoc3RydWN0IGt2ZWMpIHsgc2tiLT5kYXRhLCBza2ItPmxlbiB9OwoJbGVuICs9IHNrYi0+bGVuOwoJCgkvKiBGSVhNRTogbGluZWFyaXplIHNrYiAqLwoJewoJCWxlbiA9IGtlcm5lbF9zZW5kbXNnKHNvY2ssICZzLT5tc2csIGl2LCBpbCwgbGVuKTsKCX0KCWtmcmVlX3NrYihza2IpOwoKCWlmIChsZW4gPiAwKSB7CgkJcy0+c3RhdHMudHhfYnl0ZXMgKz0gbGVuOwoJCXMtPnN0YXRzLnR4X3BhY2tldHMrKzsKCQlyZXR1cm4gMDsKCX0KCglyZXR1cm4gbGVuOwp9CgpzdGF0aWMgaW50IGJuZXBfc2Vzc2lvbih2b2lkICphcmcpCnsKCXN0cnVjdCBibmVwX3Nlc3Npb24gKnMgPSBhcmc7CglzdHJ1Y3QgbmV0X2RldmljZSAqZGV2ID0gcy0+ZGV2OwoJc3RydWN0IHNvY2sgKnNrID0gcy0+c29jay0+c2s7CglzdHJ1Y3Qgc2tfYnVmZiAqc2tiOwoJd2FpdF9xdWV1ZV90IHdhaXQ7CgoJQlRfREJHKCIiKTsKCiAgICAgICAgZGFlbW9uaXplKCJrYm5lcGQgJXMiLCBkZXYtPm5hbWUpOwoJc2V0X3VzZXJfbmljZShjdXJyZW50LCAtMTUpOwoJY3VycmVudC0+ZmxhZ3MgfD0gUEZfTk9GUkVFWkU7CgoJaW5pdF93YWl0cXVldWVfZW50cnkoJndhaXQsIGN1cnJlbnQpOwoJYWRkX3dhaXRfcXVldWUoc2stPnNrX3NsZWVwLCAmd2FpdCk7Cgl3aGlsZSAoIWF0b21pY19yZWFkKCZzLT5raWxsZWQpKSB7CgkJc2V0X2N1cnJlbnRfc3RhdGUoVEFTS19JTlRFUlJVUFRJQkxFKTsKCgkJLy8gUlgKCQl3aGlsZSAoKHNrYiA9IHNrYl9kZXF1ZXVlKCZzay0+c2tfcmVjZWl2ZV9xdWV1ZSkpKSB7CgkJCXNrYl9vcnBoYW4oc2tiKTsKCQkJYm5lcF9yeF9mcmFtZShzLCBza2IpOwoJCX0KCgkJaWYgKHNrLT5za19zdGF0ZSAhPSBCVF9DT05ORUNURUQpCgkJCWJyZWFrOwoJCgkJLy8gVFgKCQl3aGlsZSAoKHNrYiA9IHNrYl9kZXF1ZXVlKCZzay0+c2tfd3JpdGVfcXVldWUpKSkKCQkJaWYgKGJuZXBfdHhfZnJhbWUocywgc2tiKSkKCQkJCWJyZWFrOwoJCW5ldGlmX3dha2VfcXVldWUoZGV2KTsKCQoJCXNjaGVkdWxlKCk7Cgl9CglzZXRfY3VycmVudF9zdGF0ZShUQVNLX1JVTk5JTkcpOwoJcmVtb3ZlX3dhaXRfcXVldWUoc2stPnNrX3NsZWVwLCAmd2FpdCk7CgoJLyogQ2xlYW51cCBzZXNzaW9uICovCglkb3duX3dyaXRlKCZibmVwX3Nlc3Npb25fc2VtKTsKCgkvKiBEZWxldGUgbmV0d29yayBkZXZpY2UgKi8KCXVucmVnaXN0ZXJfbmV0ZGV2KGRldik7CgoJLyogUmVsZWFzZSB0aGUgc29ja2V0ICovCglmcHV0KHMtPnNvY2stPmZpbGUpOwoKCV9fYm5lcF91bmxpbmtfc2Vzc2lvbihzKTsKCgl1cF93cml0ZSgmYm5lcF9zZXNzaW9uX3NlbSk7CglmcmVlX25ldGRldihkZXYpOwoJcmV0dXJuIDA7Cn0KCmludCBibmVwX2FkZF9jb25uZWN0aW9uKHN0cnVjdCBibmVwX2Nvbm5hZGRfcmVxICpyZXEsIHN0cnVjdCBzb2NrZXQgKnNvY2spCnsKCXN0cnVjdCBuZXRfZGV2aWNlICpkZXY7CglzdHJ1Y3QgYm5lcF9zZXNzaW9uICpzLCAqc3M7Cgl1OCBkc3RbRVRIX0FMRU5dLCBzcmNbRVRIX0FMRU5dOwoJaW50IGVycjsKCglCVF9EQkcoIiIpOwoKCWJhc3dhcCgodm9pZCAqKSBkc3QsICZidF9zayhzb2NrLT5zayktPmRzdCk7CgliYXN3YXAoKHZvaWQgKikgc3JjLCAmYnRfc2soc29jay0+c2spLT5zcmMpOwoKCS8qIHNlc3Npb24gc3RydWN0IGFsbG9jYXRlZCBhcyBwcml2YXRlIHBhcnQgb2YgbmV0X2RldmljZSAqLwoJZGV2ID0gYWxsb2NfbmV0ZGV2KHNpemVvZihzdHJ1Y3QgYm5lcF9zZXNzaW9uKSwKCQkJICAgKCpyZXEtPmRldmljZSkgPyByZXEtPmRldmljZSA6ICJibmVwJWQiLAoJCQkgICBibmVwX25ldF9zZXR1cCk7CglpZiAoIWRldikgCgkJcmV0dXJuIEVOT01FTTsKCgoJZG93bl93cml0ZSgmYm5lcF9zZXNzaW9uX3NlbSk7CgoJc3MgPSBfX2JuZXBfZ2V0X3Nlc3Npb24oZHN0KTsKCWlmIChzcyAmJiBzcy0+c3RhdGUgPT0gQlRfQ09OTkVDVEVEKSB7CgkJZXJyID0gLUVFWElTVDsKCQlnb3RvIGZhaWxlZDsKCX0KCglzID0gZGV2LT5wcml2OwoKCS8qIFRoaXMgaXMgcnggaGVhZGVyIHRoZXJlZm9yZSBhZGRyZXNzZXMgYXJlIHN3YXBwZWQuCgkgKiBpZSBlaC5oX2Rlc3QgaXMgb3VyIGxvY2FsIGFkZHJlc3MuICovCgltZW1jcHkocy0+ZWguaF9kZXN0LCAgICZzcmMsIEVUSF9BTEVOKTsKCW1lbWNweShzLT5laC5oX3NvdXJjZSwgJmRzdCwgRVRIX0FMRU4pOwoJbWVtY3B5KGRldi0+ZGV2X2FkZHIsIHMtPmVoLmhfZGVzdCwgRVRIX0FMRU4pOwoKCXMtPmRldiA9IGRldjsKCXMtPnNvY2sgID0gc29jazsKCXMtPnJvbGUgID0gcmVxLT5yb2xlOwoJcy0+c3RhdGUgPSBCVF9DT05ORUNURUQ7CgkKCXMtPm1zZy5tc2dfZmxhZ3MgPSBNU0dfTk9TSUdOQUw7CgojaWZkZWYgQ09ORklHX0JUX0JORVBfTUNfRklMVEVSCgkvKiBTZXQgZGVmYXVsdCBtYyBmaWx0ZXIgKi8KCXNldF9iaXQoYm5lcF9tY19oYXNoKGRldi0+YnJvYWRjYXN0KSwgKHVsb25nICopICZzLT5tY19maWx0ZXIpOwojZW5kaWYKCiNpZmRlZiBDT05GSUdfQlRfQk5FUF9QUk9UT19GSUxURVIKCS8qIFNldCBkZWZhdWx0IHByb3RvY29sIGZpbHRlciAqLwoJYm5lcF9zZXRfZGVmYXVsdF9wcm90b19maWx0ZXIocyk7CiNlbmRpZgoKCWVyciA9IHJlZ2lzdGVyX25ldGRldihkZXYpOwoJaWYgKGVycikgewoJCWdvdG8gZmFpbGVkOwoJfQoKCV9fYm5lcF9saW5rX3Nlc3Npb24ocyk7CgkKCWVyciA9IGtlcm5lbF90aHJlYWQoYm5lcF9zZXNzaW9uLCBzLCBDTE9ORV9LRVJORUwpOwoJaWYgKGVyciA8IDApIHsKCQkvKiBTZXNzaW9uIHRocmVhZCBzdGFydCBmYWlsZWQsIGdvdHRhIGNsZWFudXAuICovCgkJdW5yZWdpc3Rlcl9uZXRkZXYoZGV2KTsKCQlfX2JuZXBfdW5saW5rX3Nlc3Npb24ocyk7CgkJZ290byBmYWlsZWQ7Cgl9CgoJdXBfd3JpdGUoJmJuZXBfc2Vzc2lvbl9zZW0pOwoJc3RyY3B5KHJlcS0+ZGV2aWNlLCBkZXYtPm5hbWUpOwoJcmV0dXJuIDA7CgpmYWlsZWQ6Cgl1cF93cml0ZSgmYm5lcF9zZXNzaW9uX3NlbSk7CglmcmVlX25ldGRldihkZXYpOwoJcmV0dXJuIGVycjsKfQoKaW50IGJuZXBfZGVsX2Nvbm5lY3Rpb24oc3RydWN0IGJuZXBfY29ubmRlbF9yZXEgKnJlcSkKewoJc3RydWN0IGJuZXBfc2Vzc2lvbiAqczsKCWludCAgZXJyID0gMDsKCglCVF9EQkcoIiIpOwoKCWRvd25fcmVhZCgmYm5lcF9zZXNzaW9uX3NlbSk7CgoJcyA9IF9fYm5lcF9nZXRfc2Vzc2lvbihyZXEtPmRzdCk7CglpZiAocykgewoJCS8qIFdha2V1cCB1c2VyLXNwYWNlIHdoaWNoIGlzIHBvbGxpbmcgZm9yIHNvY2tldCBlcnJvcnMuCgkJICogVGhpcyBpcyB0ZW1wb3JhcnkgaGFjayB1bnRpbGwgd2UgaGF2ZSBzaHV0ZG93biBpbiBMMkNBUCAqLwoJCXMtPnNvY2stPnNrLT5za19lcnIgPSBFVU5BVENIOwoJCQoJCS8qIEtpbGwgc2Vzc2lvbiB0aHJlYWQgKi8KCQlhdG9taWNfaW5jKCZzLT5raWxsZWQpOwoJCXdha2VfdXBfaW50ZXJydXB0aWJsZShzLT5zb2NrLT5zay0+c2tfc2xlZXApOwoJfSBlbHNlCgkJZXJyID0gLUVOT0VOVDsKCgl1cF9yZWFkKCZibmVwX3Nlc3Npb25fc2VtKTsKCXJldHVybiBlcnI7Cn0KCnN0YXRpYyB2b2lkIF9fYm5lcF9jb3B5X2NpKHN0cnVjdCBibmVwX2Nvbm5pbmZvICpjaSwgc3RydWN0IGJuZXBfc2Vzc2lvbiAqcykKewoJbWVtY3B5KGNpLT5kc3QsIHMtPmVoLmhfc291cmNlLCBFVEhfQUxFTik7CglzdHJjcHkoY2ktPmRldmljZSwgcy0+ZGV2LT5uYW1lKTsKCWNpLT5mbGFncyA9IHMtPmZsYWdzOwoJY2ktPnN0YXRlID0gcy0+c3RhdGU7CgljaS0+cm9sZSAgPSBzLT5yb2xlOwp9CgppbnQgYm5lcF9nZXRfY29ubmxpc3Qoc3RydWN0IGJuZXBfY29ubmxpc3RfcmVxICpyZXEpCnsKCXN0cnVjdCBsaXN0X2hlYWQgKnA7CglpbnQgZXJyID0gMCwgbiA9IDA7CgoJZG93bl9yZWFkKCZibmVwX3Nlc3Npb25fc2VtKTsKCglsaXN0X2Zvcl9lYWNoKHAsICZibmVwX3Nlc3Npb25fbGlzdCkgewoJCXN0cnVjdCBibmVwX3Nlc3Npb24gKnM7CgkJc3RydWN0IGJuZXBfY29ubmluZm8gY2k7CgoJCXMgPSBsaXN0X2VudHJ5KHAsIHN0cnVjdCBibmVwX3Nlc3Npb24sIGxpc3QpOwoKCQlfX2JuZXBfY29weV9jaSgmY2ksIHMpOwoJCQoJCWlmIChjb3B5X3RvX3VzZXIocmVxLT5jaSwgJmNpLCBzaXplb2YoY2kpKSkgewoJCQllcnIgPSAtRUZBVUxUOwoJCQlicmVhazsKCQl9CgoJCWlmICgrK24gPj0gcmVxLT5jbnVtKQoJCQlicmVhazsKCgkJcmVxLT5jaSsrOwoJfQoJcmVxLT5jbnVtID0gbjsKCgl1cF9yZWFkKCZibmVwX3Nlc3Npb25fc2VtKTsKCXJldHVybiBlcnI7Cn0KCmludCBibmVwX2dldF9jb25uaW5mbyhzdHJ1Y3QgYm5lcF9jb25uaW5mbyAqY2kpCnsKCXN0cnVjdCBibmVwX3Nlc3Npb24gKnM7CglpbnQgZXJyID0gMDsKCglkb3duX3JlYWQoJmJuZXBfc2Vzc2lvbl9zZW0pOwoKCXMgPSBfX2JuZXBfZ2V0X3Nlc3Npb24oY2ktPmRzdCk7CglpZiAocykKCQlfX2JuZXBfY29weV9jaShjaSwgcyk7CgllbHNlCgkJZXJyID0gLUVOT0VOVDsKCgl1cF9yZWFkKCZibmVwX3Nlc3Npb25fc2VtKTsKCXJldHVybiBlcnI7Cn0KCnN0YXRpYyBpbnQgX19pbml0IGJuZXBfaW5pdCh2b2lkKQp7CQoJY2hhciBmbHRbNTBdID0gIiI7CgoJbDJjYXBfbG9hZCgpOwoKI2lmZGVmIENPTkZJR19CVF9CTkVQX1BST1RPX0ZJTFRFUgoJc3RyY2F0KGZsdCwgInByb3RvY29sICIpOwojZW5kaWYKCiNpZmRlZiBDT05GSUdfQlRfQk5FUF9NQ19GSUxURVIKCXN0cmNhdChmbHQsICJtdWx0aWNhc3QiKTsKI2VuZGlmCgoJQlRfSU5GTygiQk5FUCAoRXRoZXJuZXQgRW11bGF0aW9uKSB2ZXIgJXMiLCBWRVJTSU9OKTsKCWlmIChmbHRbMF0pCgkJQlRfSU5GTygiQk5FUCBmaWx0ZXJzOiAlcyIsIGZsdCk7CgoJYm5lcF9zb2NrX2luaXQoKTsKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgYm5lcF9leGl0KHZvaWQpCnsKCWJuZXBfc29ja19jbGVhbnVwKCk7Cn0KCm1vZHVsZV9pbml0KGJuZXBfaW5pdCk7Cm1vZHVsZV9leGl0KGJuZXBfZXhpdCk7CgpNT0RVTEVfQVVUSE9SKCJEYXZpZCBMaWJhdWx0IDxkYXZpZC5saWJhdWx0QGludmVudGVsLmZyPiwgTWF4aW0gS3Jhc255YW5za3kgPG1heGtAcXVhbGNvbW0uY29tPiIpOwpNT0RVTEVfREVTQ1JJUFRJT04oIkJsdWV0b290aCBCTkVQIHZlciAiIFZFUlNJT04pOwpNT0RVTEVfVkVSU0lPTihWRVJTSU9OKTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwpNT0RVTEVfQUxJQVMoImJ0LXByb3RvLTQiKTsK