LyoKICogJElkOiBibG9jazJtdGQuYyx2IDEuMjkgMjAwNS8xMS8wNyAxMToxNDoyNCBnbGVpeG5lciBFeHAgJAogKgogKiBibG9jazJtdGQuYyAtIGNyZWF0ZSBhbiBtdGQgZnJvbSBhIGJsb2NrIGRldmljZQogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDEsMjAwMglTaW1vbiBFdmFucyA8c3BzZUBzZWNyZXQub3JnLnVrPgogKiBDb3B5cmlnaHQgKEMpIDIwMDQsMjAwNQlK9nJuIEVuZ2VsIDxqb2VybkB3aC5maC13ZWRlbC5kZT4KICoKICogTGljZW5jZTogR1BMCiAqLwojaW5jbHVkZSA8bGludXgvY29uZmlnLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2ZzLmg+CiNpbmNsdWRlIDxsaW51eC9ibGtkZXYuaD4KI2luY2x1ZGUgPGxpbnV4L2Jpby5oPgojaW5jbHVkZSA8bGludXgvcGFnZW1hcC5oPgojaW5jbHVkZSA8bGludXgvbGlzdC5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvbXRkL210ZC5oPgojaW5jbHVkZSA8bGludXgvYnVmZmVyX2hlYWQuaD4KCiNkZWZpbmUgVkVSU0lPTiAiJFJldmlzaW9uOiAxLjI5ICQiCgoKI2RlZmluZSBFUlJPUihmbXQsIGFyZ3MuLi4pIHByaW50ayhLRVJOX0VSUiAiYmxvY2sybXRkOiAiIGZtdCAiXG4iICwgIyMgYXJncykKI2RlZmluZSBJTkZPKGZtdCwgYXJncy4uLikgcHJpbnRrKEtFUk5fSU5GTyAiYmxvY2sybXRkOiAiIGZtdCAiXG4iICwgIyMgYXJncykKCgovKiBJbmZvIGZvciB0aGUgYmxvY2sgZGV2aWNlICovCnN0cnVjdCBibG9jazJtdGRfZGV2IHsKCXN0cnVjdCBsaXN0X2hlYWQgbGlzdDsKCXN0cnVjdCBibG9ja19kZXZpY2UgKmJsa2RldjsKCXN0cnVjdCBtdGRfaW5mbyBtdGQ7CglzdHJ1Y3Qgc2VtYXBob3JlIHdyaXRlX211dGV4Owp9OwoKCi8qIFN0YXRpYyBpbmZvIGFib3V0IHRoZSBNVEQsIHVzZWQgaW4gY2xlYW51cF9tb2R1bGUgKi8Kc3RhdGljIExJU1RfSEVBRChibGttdGRfZGV2aWNlX2xpc3QpOwoKCiNkZWZpbmUgUEFHRV9SRUFEQUhFQUQgNjQKdm9pZCBjYWNoZV9yZWFkYWhlYWQoc3RydWN0IGFkZHJlc3Nfc3BhY2UgKm1hcHBpbmcsIGludCBpbmRleCkKewoJZmlsbGVyX3QgKmZpbGxlciA9IChmaWxsZXJfdCopbWFwcGluZy0+YV9vcHMtPnJlYWRwYWdlOwoJaW50IGksIHBhZ2VpOwoJdW5zaWduZWQgcmV0ID0gMDsKCXVuc2lnbmVkIGxvbmcgZW5kX2luZGV4OwoJc3RydWN0IHBhZ2UgKnBhZ2U7CglMSVNUX0hFQUQocGFnZV9wb29sKTsKCXN0cnVjdCBpbm9kZSAqaW5vZGUgPSBtYXBwaW5nLT5ob3N0OwoJbG9mZl90IGlzaXplID0gaV9zaXplX3JlYWQoaW5vZGUpOwoKCWlmICghaXNpemUpIHsKCQlJTkZPKCJpU2l6ZT0wIGluIGNhY2hlX3JlYWRhaGVhZFxuIik7CgkJcmV0dXJuOwoJfQoKCWVuZF9pbmRleCA9ICgoaXNpemUgLSAxKSA+PiBQQUdFX0NBQ0hFX1NISUZUKTsKCglyZWFkX2xvY2tfaXJxKCZtYXBwaW5nLT50cmVlX2xvY2spOwoJZm9yIChpID0gMDsgaSA8IFBBR0VfUkVBREFIRUFEOyBpKyspIHsKCQlwYWdlaSA9IGluZGV4ICsgaTsKCQlpZiAocGFnZWkgPiBlbmRfaW5kZXgpIHsKCQkJSU5GTygiT3ZlcnJ1biBlbmQgb2YgZGlzayBpbiBjYWNoZSByZWFkYWhlYWRcbiIpOwoJCQlicmVhazsKCQl9CgkJcGFnZSA9IHJhZGl4X3RyZWVfbG9va3VwKCZtYXBwaW5nLT5wYWdlX3RyZWUsIHBhZ2VpKTsKCQlpZiAocGFnZSAmJiAoIWkpKQoJCQlicmVhazsKCQlpZiAocGFnZSkKCQkJY29udGludWU7CgkJcmVhZF91bmxvY2tfaXJxKCZtYXBwaW5nLT50cmVlX2xvY2spOwoJCXBhZ2UgPSBwYWdlX2NhY2hlX2FsbG9jX2NvbGQobWFwcGluZyk7CgkJcmVhZF9sb2NrX2lycSgmbWFwcGluZy0+dHJlZV9sb2NrKTsKCQlpZiAoIXBhZ2UpCgkJCWJyZWFrOwoJCXBhZ2UtPmluZGV4ID0gcGFnZWk7CgkJbGlzdF9hZGQoJnBhZ2UtPmxydSwgJnBhZ2VfcG9vbCk7CgkJcmV0Kys7Cgl9CglyZWFkX3VubG9ja19pcnEoJm1hcHBpbmctPnRyZWVfbG9jayk7CglpZiAocmV0KQoJCXJlYWRfY2FjaGVfcGFnZXMobWFwcGluZywgJnBhZ2VfcG9vbCwgZmlsbGVyLCBOVUxMKTsKfQoKCnN0YXRpYyBzdHJ1Y3QgcGFnZSogcGFnZV9yZWFkYWhlYWQoc3RydWN0IGFkZHJlc3Nfc3BhY2UgKm1hcHBpbmcsIGludCBpbmRleCkKewoJZmlsbGVyX3QgKmZpbGxlciA9IChmaWxsZXJfdCopbWFwcGluZy0+YV9vcHMtPnJlYWRwYWdlOwoJY2FjaGVfcmVhZGFoZWFkKG1hcHBpbmcsIGluZGV4KTsKCXJldHVybiByZWFkX2NhY2hlX3BhZ2UobWFwcGluZywgaW5kZXgsIGZpbGxlciwgTlVMTCk7Cn0KCgovKiBlcmFzZSBhIHNwZWNpZmllZCBwYXJ0IG9mIHRoZSBkZXZpY2UgKi8Kc3RhdGljIGludCBfYmxvY2sybXRkX2VyYXNlKHN0cnVjdCBibG9jazJtdGRfZGV2ICpkZXYsIGxvZmZfdCB0bywgc2l6ZV90IGxlbikKewoJc3RydWN0IGFkZHJlc3Nfc3BhY2UgKm1hcHBpbmcgPSBkZXYtPmJsa2Rldi0+YmRfaW5vZGUtPmlfbWFwcGluZzsKCXN0cnVjdCBwYWdlICpwYWdlOwoJaW50IGluZGV4ID0gdG8gPj4gUEFHRV9TSElGVDsJLy8gcGFnZSBpbmRleAoJaW50IHBhZ2VzID0gbGVuID4+IFBBR0VfU0hJRlQ7Cgl1X2xvbmcgKnA7Cgl1X2xvbmcgKm1heDsKCgl3aGlsZSAocGFnZXMpIHsKCQlwYWdlID0gcGFnZV9yZWFkYWhlYWQobWFwcGluZywgaW5kZXgpOwoJCWlmICghcGFnZSkKCQkJcmV0dXJuIC1FTk9NRU07CgkJaWYgKElTX0VSUihwYWdlKSkKCQkJcmV0dXJuIFBUUl9FUlIocGFnZSk7CgoJCW1heCA9ICh1X2xvbmcqKXBhZ2VfYWRkcmVzcyhwYWdlKSArIFBBR0VfU0laRTsKCQlmb3IgKHA9KHVfbG9uZyopcGFnZV9hZGRyZXNzKHBhZ2UpOyBwPG1heDsgcCsrKQoJCQlpZiAoKnAgIT0gLTFVTCkgewoJCQkJbG9ja19wYWdlKHBhZ2UpOwoJCQkJbWVtc2V0KHBhZ2VfYWRkcmVzcyhwYWdlKSwgMHhmZiwgUEFHRV9TSVpFKTsKCQkJCXNldF9wYWdlX2RpcnR5KHBhZ2UpOwoJCQkJdW5sb2NrX3BhZ2UocGFnZSk7CgkJCQlicmVhazsKCQkJfQoKCQlwYWdlX2NhY2hlX3JlbGVhc2UocGFnZSk7CgkJcGFnZXMtLTsKCQlpbmRleCsrOwoJfQoJcmV0dXJuIDA7Cn0Kc3RhdGljIGludCBibG9jazJtdGRfZXJhc2Uoc3RydWN0IG10ZF9pbmZvICptdGQsIHN0cnVjdCBlcmFzZV9pbmZvICppbnN0cikKewoJc3RydWN0IGJsb2NrMm10ZF9kZXYgKmRldiA9IG10ZC0+cHJpdjsKCXNpemVfdCBmcm9tID0gaW5zdHItPmFkZHI7CglzaXplX3QgbGVuID0gaW5zdHItPmxlbjsKCWludCBlcnI7CgoJaW5zdHItPnN0YXRlID0gTVREX0VSQVNJTkc7Cglkb3duKCZkZXYtPndyaXRlX211dGV4KTsKCWVyciA9IF9ibG9jazJtdGRfZXJhc2UoZGV2LCBmcm9tLCBsZW4pOwoJdXAoJmRldi0+d3JpdGVfbXV0ZXgpOwoJaWYgKGVycikgewoJCUVSUk9SKCJlcmFzZSBmYWlsZWQgZXJyID0gJWQiLCBlcnIpOwoJCWluc3RyLT5zdGF0ZSA9IE1URF9FUkFTRV9GQUlMRUQ7Cgl9IGVsc2UKCQlpbnN0ci0+c3RhdGUgPSBNVERfRVJBU0VfRE9ORTsKCglpbnN0ci0+c3RhdGUgPSBNVERfRVJBU0VfRE9ORTsKCW10ZF9lcmFzZV9jYWxsYmFjayhpbnN0cik7CglyZXR1cm4gZXJyOwp9CgoKc3RhdGljIGludCBibG9jazJtdGRfcmVhZChzdHJ1Y3QgbXRkX2luZm8gKm10ZCwgbG9mZl90IGZyb20sIHNpemVfdCBsZW4sCgkJc2l6ZV90ICpyZXRsZW4sIHVfY2hhciAqYnVmKQp7CglzdHJ1Y3QgYmxvY2sybXRkX2RldiAqZGV2ID0gbXRkLT5wcml2OwoJc3RydWN0IHBhZ2UgKnBhZ2U7CglpbnQgaW5kZXggPSBmcm9tID4+IFBBR0VfU0hJRlQ7CglpbnQgb2Zmc2V0ID0gZnJvbSAmIChQQUdFX1NJWkUtMSk7CglpbnQgY3B5bGVuOwoKCWlmIChmcm9tID4gbXRkLT5zaXplKQoJCXJldHVybiAtRUlOVkFMOwoJaWYgKGZyb20gKyBsZW4gPiBtdGQtPnNpemUpCgkJbGVuID0gbXRkLT5zaXplIC0gZnJvbTsKCglpZiAocmV0bGVuKQoJCSpyZXRsZW4gPSAwOwoKCXdoaWxlIChsZW4pIHsKCQlpZiAoKG9mZnNldCArIGxlbikgPiBQQUdFX1NJWkUpCgkJCWNweWxlbiA9IFBBR0VfU0laRSAtIG9mZnNldDsJLy8gbXVsdGlwbGUgcGFnZXMKCQllbHNlCgkJCWNweWxlbiA9IGxlbjsJLy8gdGhpcyBwYWdlCgkJbGVuID0gbGVuIC0gY3B5bGVuOwoKCQkvLyAgICAgIEdldCBwYWdlCgkJcGFnZSA9IHBhZ2VfcmVhZGFoZWFkKGRldi0+YmxrZGV2LT5iZF9pbm9kZS0+aV9tYXBwaW5nLCBpbmRleCk7CgkJaWYgKCFwYWdlKQoJCQlyZXR1cm4gLUVOT01FTTsKCQlpZiAoSVNfRVJSKHBhZ2UpKQoJCQlyZXR1cm4gUFRSX0VSUihwYWdlKTsKCgkJbWVtY3B5KGJ1ZiwgcGFnZV9hZGRyZXNzKHBhZ2UpICsgb2Zmc2V0LCBjcHlsZW4pOwoJCXBhZ2VfY2FjaGVfcmVsZWFzZShwYWdlKTsKCgkJaWYgKHJldGxlbikKCQkJKnJldGxlbiArPSBjcHlsZW47CgkJYnVmICs9IGNweWxlbjsKCQlvZmZzZXQgPSAwOwoJCWluZGV4Kys7Cgl9CglyZXR1cm4gMDsKfQoKCi8qIHdyaXRlIGRhdGEgdG8gdGhlIHVuZGVybHlpbmcgZGV2aWNlICovCnN0YXRpYyBpbnQgX2Jsb2NrMm10ZF93cml0ZShzdHJ1Y3QgYmxvY2sybXRkX2RldiAqZGV2LCBjb25zdCB1X2NoYXIgKmJ1ZiwKCQlsb2ZmX3QgdG8sIHNpemVfdCBsZW4sIHNpemVfdCAqcmV0bGVuKQp7CglzdHJ1Y3QgcGFnZSAqcGFnZTsKCXN0cnVjdCBhZGRyZXNzX3NwYWNlICptYXBwaW5nID0gZGV2LT5ibGtkZXYtPmJkX2lub2RlLT5pX21hcHBpbmc7CglpbnQgaW5kZXggPSB0byA+PiBQQUdFX1NISUZUOwkvLyBwYWdlIGluZGV4CglpbnQgb2Zmc2V0ID0gdG8gJiB+UEFHRV9NQVNLOwkvLyBwYWdlIG9mZnNldAoJaW50IGNweWxlbjsKCglpZiAocmV0bGVuKQoJCSpyZXRsZW4gPSAwOwoJd2hpbGUgKGxlbikgewoJCWlmICgob2Zmc2V0K2xlbikgPiBQQUdFX1NJWkUpCgkJCWNweWxlbiA9IFBBR0VfU0laRSAtIG9mZnNldDsJLy8gbXVsdGlwbGUgcGFnZXMKCQllbHNlCgkJCWNweWxlbiA9IGxlbjsJCQkvLyB0aGlzIHBhZ2UKCQlsZW4gPSBsZW4gLSBjcHlsZW47CgoJCS8vCUdldCBwYWdlCgkJcGFnZSA9IHBhZ2VfcmVhZGFoZWFkKG1hcHBpbmcsIGluZGV4KTsKCQlpZiAoIXBhZ2UpCgkJCXJldHVybiAtRU5PTUVNOwoJCWlmIChJU19FUlIocGFnZSkpCgkJCXJldHVybiBQVFJfRVJSKHBhZ2UpOwoKCQlpZiAobWVtY21wKHBhZ2VfYWRkcmVzcyhwYWdlKStvZmZzZXQsIGJ1ZiwgY3B5bGVuKSkgewoJCQlsb2NrX3BhZ2UocGFnZSk7CgkJCW1lbWNweShwYWdlX2FkZHJlc3MocGFnZSkgKyBvZmZzZXQsIGJ1ZiwgY3B5bGVuKTsKCQkJc2V0X3BhZ2VfZGlydHkocGFnZSk7CgkJCXVubG9ja19wYWdlKHBhZ2UpOwoJCX0KCQlwYWdlX2NhY2hlX3JlbGVhc2UocGFnZSk7CgoJCWlmIChyZXRsZW4pCgkJCSpyZXRsZW4gKz0gY3B5bGVuOwoKCQlidWYgKz0gY3B5bGVuOwoJCW9mZnNldCA9IDA7CgkJaW5kZXgrKzsKCX0KCXJldHVybiAwOwp9CnN0YXRpYyBpbnQgYmxvY2sybXRkX3dyaXRlKHN0cnVjdCBtdGRfaW5mbyAqbXRkLCBsb2ZmX3QgdG8sIHNpemVfdCBsZW4sCgkJc2l6ZV90ICpyZXRsZW4sIGNvbnN0IHVfY2hhciAqYnVmKQp7CglzdHJ1Y3QgYmxvY2sybXRkX2RldiAqZGV2ID0gbXRkLT5wcml2OwoJaW50IGVycjsKCglpZiAoIWxlbikKCQlyZXR1cm4gMDsKCWlmICh0byA+PSBtdGQtPnNpemUpCgkJcmV0dXJuIC1FTk9TUEM7CglpZiAodG8gKyBsZW4gPiBtdGQtPnNpemUpCgkJbGVuID0gbXRkLT5zaXplIC0gdG87CgoJZG93bigmZGV2LT53cml0ZV9tdXRleCk7CgllcnIgPSBfYmxvY2sybXRkX3dyaXRlKGRldiwgYnVmLCB0bywgbGVuLCByZXRsZW4pOwoJdXAoJmRldi0+d3JpdGVfbXV0ZXgpOwoJaWYgKGVyciA+IDApCgkJZXJyID0gMDsKCXJldHVybiBlcnI7Cn0KCgovKiBzeW5jIHRoZSBkZXZpY2UgLSB3YWl0IHVudGlsIHRoZSB3cml0ZSBxdWV1ZSBpcyBlbXB0eSAqLwpzdGF0aWMgdm9pZCBibG9jazJtdGRfc3luYyhzdHJ1Y3QgbXRkX2luZm8gKm10ZCkKewoJc3RydWN0IGJsb2NrMm10ZF9kZXYgKmRldiA9IG10ZC0+cHJpdjsKCXN5bmNfYmxvY2tkZXYoZGV2LT5ibGtkZXYpOwoJcmV0dXJuOwp9CgoKc3RhdGljIHZvaWQgYmxvY2sybXRkX2ZyZWVfZGV2aWNlKHN0cnVjdCBibG9jazJtdGRfZGV2ICpkZXYpCnsKCWlmICghZGV2KQoJCXJldHVybjsKCglrZnJlZShkZXYtPm10ZC5uYW1lKTsKCglpZiAoZGV2LT5ibGtkZXYpIHsKCQlpbnZhbGlkYXRlX2lub2RlX3BhZ2VzKGRldi0+YmxrZGV2LT5iZF9pbm9kZS0+aV9tYXBwaW5nKTsKCQljbG9zZV9iZGV2X2V4Y2woZGV2LT5ibGtkZXYpOwoJfQoKCWtmcmVlKGRldik7Cn0KCgovKiBGSVhNRTogZW5zdXJlIHRoYXQgbXRkLT5zaXplICUgZXJhc2Vfc2l6ZSA9PSAwICovCnN0YXRpYyBzdHJ1Y3QgYmxvY2sybXRkX2RldiAqYWRkX2RldmljZShjaGFyICpkZXZuYW1lLCBpbnQgZXJhc2Vfc2l6ZSkKewoJc3RydWN0IGJsb2NrX2RldmljZSAqYmRldjsKCXN0cnVjdCBibG9jazJtdGRfZGV2ICpkZXY7CgoJaWYgKCFkZXZuYW1lKQoJCXJldHVybiBOVUxMOwoKCWRldiA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBibG9jazJtdGRfZGV2KSwgR0ZQX0tFUk5FTCk7CglpZiAoIWRldikKCQlyZXR1cm4gTlVMTDsKCW1lbXNldChkZXYsIDAsIHNpemVvZigqZGV2KSk7CgoJLyogR2V0IGEgaGFuZGxlIG9uIHRoZSBkZXZpY2UgKi8KCWJkZXYgPSBvcGVuX2JkZXZfZXhjbChkZXZuYW1lLCBPX1JEV1IsIE5VTEwpOwoJaWYgKElTX0VSUihiZGV2KSkgewoJCUVSUk9SKCJlcnJvcjogY2Fubm90IG9wZW4gZGV2aWNlICVzIiwgZGV2bmFtZSk7CgkJZ290byBkZXZpbml0X2VycjsKCX0KCWRldi0+YmxrZGV2ID0gYmRldjsKCglpZiAoTUFKT1IoYmRldi0+YmRfZGV2KSA9PSBNVERfQkxPQ0tfTUFKT1IpIHsKCQlFUlJPUigiYXR0ZW1wdGluZyB0byB1c2UgYW4gTVREIGRldmljZSBhcyBhIGJsb2NrIGRldmljZSIpOwoJCWdvdG8gZGV2aW5pdF9lcnI7Cgl9CgoJaW5pdF9NVVRFWCgmZGV2LT53cml0ZV9tdXRleCk7CgoJLyogU2V0dXAgdGhlIE1URCBzdHJ1Y3R1cmUgKi8KCS8qIG1ha2UgdGhlIG5hbWUgY29udGFpbiB0aGUgYmxvY2sgZGV2aWNlIGluICovCglkZXYtPm10ZC5uYW1lID0ga21hbGxvYyhzaXplb2YoImJsb2NrMm10ZDogIikgKyBzdHJsZW4oZGV2bmFtZSksCgkJCUdGUF9LRVJORUwpOwoJaWYgKCFkZXYtPm10ZC5uYW1lKQoJCWdvdG8gZGV2aW5pdF9lcnI7CgoJc3ByaW50ZihkZXYtPm10ZC5uYW1lLCAiYmxvY2sybXRkOiAlcyIsIGRldm5hbWUpOwoKCWRldi0+bXRkLnNpemUgPSBkZXYtPmJsa2Rldi0+YmRfaW5vZGUtPmlfc2l6ZSAmIFBBR0VfTUFTSzsKCWRldi0+bXRkLmVyYXNlc2l6ZSA9IGVyYXNlX3NpemU7CglkZXYtPm10ZC50eXBlID0gTVREX1JBTTsKCWRldi0+bXRkLmZsYWdzID0gTVREX0NBUF9SQU07CglkZXYtPm10ZC5lcmFzZSA9IGJsb2NrMm10ZF9lcmFzZTsKCWRldi0+bXRkLndyaXRlID0gYmxvY2sybXRkX3dyaXRlOwoJZGV2LT5tdGQud3JpdGV2ID0gZGVmYXVsdF9tdGRfd3JpdGV2OwoJZGV2LT5tdGQuc3luYyA9IGJsb2NrMm10ZF9zeW5jOwoJZGV2LT5tdGQucmVhZCA9IGJsb2NrMm10ZF9yZWFkOwoJZGV2LT5tdGQucmVhZHYgPSBkZWZhdWx0X210ZF9yZWFkdjsKCWRldi0+bXRkLnByaXYgPSBkZXY7CglkZXYtPm10ZC5vd25lciA9IFRISVNfTU9EVUxFOwoKCWlmIChhZGRfbXRkX2RldmljZSgmZGV2LT5tdGQpKSB7CgkJLyogRGV2aWNlIGRpZG50IGdldCBhZGRlZCwgc28gZnJlZSB0aGUgZW50cnkgKi8KCQlnb3RvIGRldmluaXRfZXJyOwoJfQoJbGlzdF9hZGQoJmRldi0+bGlzdCwgJmJsa210ZF9kZXZpY2VfbGlzdCk7CglJTkZPKCJtdGQlZDogWyVzXSBlcmFzZV9zaXplID0gJWRLaUIgWyVkXSIsIGRldi0+bXRkLmluZGV4LAoJCQlkZXYtPm10ZC5uYW1lICsgc3RybGVuKCJibGttdGQ6ICIpLAoJCQlkZXYtPm10ZC5lcmFzZXNpemUgPj4gMTAsIGRldi0+bXRkLmVyYXNlc2l6ZSk7CglyZXR1cm4gZGV2OwoKZGV2aW5pdF9lcnI6CglibG9jazJtdGRfZnJlZV9kZXZpY2UoZGV2KTsKCXJldHVybiBOVUxMOwp9CgoKc3RhdGljIGludCB1c3RydG91bChjb25zdCBjaGFyICpjcCwgY2hhciAqKmVuZHAsIHVuc2lnbmVkIGludCBiYXNlKQp7Cgl1bnNpZ25lZCBsb25nIHJlc3VsdCA9IHNpbXBsZV9zdHJ0b3VsKGNwLCBlbmRwLCBiYXNlKTsKCXN3aXRjaCAoKiplbmRwKSB7CgljYXNlICdHJyA6CgkJcmVzdWx0ICo9IDEwMjQ7CgljYXNlICdNJzoKCQlyZXN1bHQgKj0gMTAyNDsKCWNhc2UgJ2snOgoJCXJlc3VsdCAqPSAxMDI0OwoJLyogQnkgZHdtdzIgZWRpdG9yaWFsIGRlY3JlZSwgImtpIiwgIk1pIiBvciAiR2kiIGFyZSB0byBiZSB1c2VkLiAqLwoJCWlmICgoKmVuZHApWzFdID09ICdpJykKCQkJKCplbmRwKSArPSAyOwoJfQoJcmV0dXJuIHJlc3VsdDsKfQoKCnN0YXRpYyBpbnQgcGFyc2VfbnVtKHNpemVfdCAqbnVtLCBjb25zdCBjaGFyICp0b2tlbikKewoJY2hhciAqZW5kcDsKCXNpemVfdCBuOwoKCW4gPSAoc2l6ZV90KSB1c3RydG91bCh0b2tlbiwgJmVuZHAsIDApOwoJaWYgKCplbmRwKQoJCXJldHVybiAtRUlOVkFMOwoKCSpudW0gPSBuOwoJcmV0dXJuIDA7Cn0KCgpzdGF0aWMgaW50IHBhcnNlX25hbWUoY2hhciAqKnBuYW1lLCBjb25zdCBjaGFyICp0b2tlbiwgc2l6ZV90IGxpbWl0KQp7CglzaXplX3QgbGVuOwoJY2hhciAqbmFtZTsKCglsZW4gPSBzdHJsZW4odG9rZW4pICsgMTsKCWlmIChsZW4gPiBsaW1pdCkKCQlyZXR1cm4gLUVOT1NQQzsKCgluYW1lID0ga21hbGxvYyhsZW4sIEdGUF9LRVJORUwpOwoJaWYgKCFuYW1lKQoJCXJldHVybiAtRU5PTUVNOwoKCXN0cmNweShuYW1lLCB0b2tlbik7CgoJKnBuYW1lID0gbmFtZTsKCXJldHVybiAwOwp9CgoKc3RhdGljIGlubGluZSB2b2lkIGtpbGxfZmluYWxfbmV3bGluZShjaGFyICpzdHIpCnsKCWNoYXIgKm5ld2xpbmUgPSBzdHJyY2hyKHN0ciwgJ1xuJyk7CglpZiAobmV3bGluZSAmJiAhbmV3bGluZVsxXSkKCQkqbmV3bGluZSA9IDA7Cn0KCgojZGVmaW5lIHBhcnNlX2VycihmbXQsIGFyZ3MuLi4pIGRvIHsJCVwKCUVSUk9SKCJibG9jazJtdGQ6ICIgZm10ICJcbiIsICMjIGFyZ3MpOwlcCglyZXR1cm4gMDsJCQkJXAp9IHdoaWxlICgwKQoKc3RhdGljIGludCBibG9jazJtdGRfc2V0dXAoY29uc3QgY2hhciAqdmFsLCBzdHJ1Y3Qga2VybmVsX3BhcmFtICprcCkKewoJY2hhciBidWZbODArMTJdLCAqc3RyPWJ1ZjsgLyogODAgZm9yIGRldmljZSwgMTIgZm9yIGVyYXNlIHNpemUgKi8KCWNoYXIgKnRva2VuWzJdOwoJY2hhciAqbmFtZTsKCXNpemVfdCBlcmFzZV9zaXplID0gUEFHRV9TSVpFOwoJaW50IGksIHJldDsKCglpZiAoc3Rybmxlbih2YWwsIHNpemVvZihidWYpKSA+PSBzaXplb2YoYnVmKSkKCQlwYXJzZV9lcnIoInBhcmFtZXRlciB0b28gbG9uZyIpOwoKCXN0cmNweShzdHIsIHZhbCk7CglraWxsX2ZpbmFsX25ld2xpbmUoc3RyKTsKCglmb3IgKGk9MDsgaTwyOyBpKyspCgkJdG9rZW5baV0gPSBzdHJzZXAoJnN0ciwgIiwiKTsKCglpZiAoc3RyKQoJCXBhcnNlX2VycigidG9vIG1hbnkgYXJndW1lbnRzIik7CgoJaWYgKCF0b2tlblswXSkKCQlwYXJzZV9lcnIoIm5vIGFyZ3VtZW50Iik7CgoJcmV0ID0gcGFyc2VfbmFtZSgmbmFtZSwgdG9rZW5bMF0sIDgwKTsKCWlmIChyZXQgPT0gLUVOT01FTSkKCQlwYXJzZV9lcnIoIm91dCBvZiBtZW1vcnkiKTsKCWlmIChyZXQgPT0gLUVOT1NQQykKCQlwYXJzZV9lcnIoIm5hbWUgdG9vIGxvbmciKTsKCWlmIChyZXQpCgkJcmV0dXJuIDA7CgoJaWYgKHRva2VuWzFdKSB7CgkJcmV0ID0gcGFyc2VfbnVtKCZlcmFzZV9zaXplLCB0b2tlblsxXSk7CgkJaWYgKHJldCkKCQkJcGFyc2VfZXJyKCJpbGxlZ2FsIGVyYXNlIHNpemUiKTsKCX0KCglhZGRfZGV2aWNlKG5hbWUsIGVyYXNlX3NpemUpOwoKCXJldHVybiAwOwp9CgoKbW9kdWxlX3BhcmFtX2NhbGwoYmxvY2sybXRkLCBibG9jazJtdGRfc2V0dXAsIE5VTEwsIE5VTEwsIDAyMDApOwpNT0RVTEVfUEFSTV9ERVNDKGJsb2NrMm10ZCwgIkRldmljZSB0byB1c2UuIFwiYmxvY2sybXRkPTxkZXY+Wyw8ZXJhc2VzaXplPl1cIiIpOwoKc3RhdGljIGludCBfX2luaXQgYmxvY2sybXRkX2luaXQodm9pZCkKewoJSU5GTygidmVyc2lvbiAiIFZFUlNJT04pOwoJcmV0dXJuIDA7Cn0KCgpzdGF0aWMgdm9pZCBfX2RldmV4aXQgYmxvY2sybXRkX2V4aXQodm9pZCkKewoJc3RydWN0IGxpc3RfaGVhZCAqcG9zLCAqbmV4dDsKCgkvKiBSZW1vdmUgdGhlIE1URCBkZXZpY2VzICovCglsaXN0X2Zvcl9lYWNoX3NhZmUocG9zLCBuZXh0LCAmYmxrbXRkX2RldmljZV9saXN0KSB7CgkJc3RydWN0IGJsb2NrMm10ZF9kZXYgKmRldiA9IGxpc3RfZW50cnkocG9zLCB0eXBlb2YoKmRldiksIGxpc3QpOwoJCWJsb2NrMm10ZF9zeW5jKCZkZXYtPm10ZCk7CgkJZGVsX210ZF9kZXZpY2UoJmRldi0+bXRkKTsKCQlJTkZPKCJtdGQlZDogWyVzXSByZW1vdmVkIiwgZGV2LT5tdGQuaW5kZXgsCgkJCQlkZXYtPm10ZC5uYW1lICsgc3RybGVuKCJibGttdGQ6ICIpKTsKCQlsaXN0X2RlbCgmZGV2LT5saXN0KTsKCQlibG9jazJtdGRfZnJlZV9kZXZpY2UoZGV2KTsKCX0KfQoKCm1vZHVsZV9pbml0KGJsb2NrMm10ZF9pbml0KTsKbW9kdWxlX2V4aXQoYmxvY2sybXRkX2V4aXQpOwoKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwpNT0RVTEVfQVVUSE9SKCJTaW1vbiBFdmFucyA8c3BzZUBzZWNyZXQub3JnLnVrPiBhbmQgb3RoZXJzIik7Ck1PRFVMRV9ERVNDUklQVElPTigiRW11bGF0ZSBhbiBNVEQgdXNpbmcgYSBibG9jayBkZXZpY2UiKTsK