LyoKICogJElkOiBibG9jazJtdGQuYyx2IDEuMjggMjAwNS8wMy8xOSAyMjo0MDo0NCBnbGVpeG5lciBFeHAgJAogKgogKiBibG9jazJtdGQuYyAtIGNyZWF0ZSBhbiBtdGQgZnJvbSBhIGJsb2NrIGRldmljZQogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDEsMjAwMglTaW1vbiBFdmFucyA8c3BzZUBzZWNyZXQub3JnLnVrPgogKiBDb3B5cmlnaHQgKEMpIDIwMDQsMjAwNQlK9nJuIEVuZ2VsIDxqb2VybkB3aC5maC13ZWRlbC5kZT4KICoKICogTGljZW5jZTogR1BMCiAqLwojaW5jbHVkZSA8bGludXgvY29uZmlnLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2ZzLmg+CiNpbmNsdWRlIDxsaW51eC9ibGtkZXYuaD4KI2luY2x1ZGUgPGxpbnV4L2Jpby5oPgojaW5jbHVkZSA8bGludXgvcGFnZW1hcC5oPgojaW5jbHVkZSA8bGludXgvbGlzdC5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvbXRkL210ZC5oPgojaW5jbHVkZSA8bGludXgvYnVmZmVyX2hlYWQuaD4KCiNkZWZpbmUgVkVSU0lPTiAiJFJldmlzaW9uOiAxLjI4ICQiCgoKI2RlZmluZSBFUlJPUihmbXQsIGFyZ3MuLi4pIHByaW50ayhLRVJOX0VSUiAiYmxvY2sybXRkOiAiIGZtdCAiXG4iICwgIyMgYXJncykKI2RlZmluZSBJTkZPKGZtdCwgYXJncy4uLikgcHJpbnRrKEtFUk5fSU5GTyAiYmxvY2sybXRkOiAiIGZtdCAiXG4iICwgIyMgYXJncykKCgovKiBJbmZvIGZvciB0aGUgYmxvY2sgZGV2aWNlICovCnN0cnVjdCBibG9jazJtdGRfZGV2IHsKCXN0cnVjdCBsaXN0X2hlYWQgbGlzdDsKCXN0cnVjdCBibG9ja19kZXZpY2UgKmJsa2RldjsKCXN0cnVjdCBtdGRfaW5mbyBtdGQ7CglzdHJ1Y3Qgc2VtYXBob3JlIHdyaXRlX211dGV4Owp9OwoKCi8qIFN0YXRpYyBpbmZvIGFib3V0IHRoZSBNVEQsIHVzZWQgaW4gY2xlYW51cF9tb2R1bGUgKi8Kc3RhdGljIExJU1RfSEVBRChibGttdGRfZGV2aWNlX2xpc3QpOwoKCiNkZWZpbmUgUEFHRV9SRUFEQUhFQUQgNjQKdm9pZCBjYWNoZV9yZWFkYWhlYWQoc3RydWN0IGFkZHJlc3Nfc3BhY2UgKm1hcHBpbmcsIGludCBpbmRleCkKewoJZmlsbGVyX3QgKmZpbGxlciA9IChmaWxsZXJfdCopbWFwcGluZy0+YV9vcHMtPnJlYWRwYWdlOwoJaW50IGksIHBhZ2VpOwoJdW5zaWduZWQgcmV0ID0gMDsKCXVuc2lnbmVkIGxvbmcgZW5kX2luZGV4OwoJc3RydWN0IHBhZ2UgKnBhZ2U7CglMSVNUX0hFQUQocGFnZV9wb29sKTsKCXN0cnVjdCBpbm9kZSAqaW5vZGUgPSBtYXBwaW5nLT5ob3N0OwoJbG9mZl90IGlzaXplID0gaV9zaXplX3JlYWQoaW5vZGUpOwoKCWlmICghaXNpemUpIHsKCQlJTkZPKCJpU2l6ZT0wIGluIGNhY2hlX3JlYWRhaGVhZFxuIik7CgkJcmV0dXJuOwoJfQoKCWVuZF9pbmRleCA9ICgoaXNpemUgLSAxKSA+PiBQQUdFX0NBQ0hFX1NISUZUKTsKCglyZWFkX2xvY2tfaXJxKCZtYXBwaW5nLT50cmVlX2xvY2spOwoJZm9yIChpID0gMDsgaSA8IFBBR0VfUkVBREFIRUFEOyBpKyspIHsKCQlwYWdlaSA9IGluZGV4ICsgaTsKCQlpZiAocGFnZWkgPiBlbmRfaW5kZXgpIHsKCQkJSU5GTygiT3ZlcnJ1biBlbmQgb2YgZGlzayBpbiBjYWNoZSByZWFkYWhlYWRcbiIpOwoJCQlicmVhazsKCQl9CgkJcGFnZSA9IHJhZGl4X3RyZWVfbG9va3VwKCZtYXBwaW5nLT5wYWdlX3RyZWUsIHBhZ2VpKTsKCQlpZiAocGFnZSAmJiAoIWkpKQoJCQlicmVhazsKCQlpZiAocGFnZSkKCQkJY29udGludWU7CgkJcmVhZF91bmxvY2tfaXJxKCZtYXBwaW5nLT50cmVlX2xvY2spOwoJCXBhZ2UgPSBwYWdlX2NhY2hlX2FsbG9jX2NvbGQobWFwcGluZyk7CgkJcmVhZF9sb2NrX2lycSgmbWFwcGluZy0+dHJlZV9sb2NrKTsKCQlpZiAoIXBhZ2UpCgkJCWJyZWFrOwoJCXBhZ2UtPmluZGV4ID0gcGFnZWk7CgkJbGlzdF9hZGQoJnBhZ2UtPmxydSwgJnBhZ2VfcG9vbCk7CgkJcmV0Kys7Cgl9CglyZWFkX3VubG9ja19pcnEoJm1hcHBpbmctPnRyZWVfbG9jayk7CglpZiAocmV0KQoJCXJlYWRfY2FjaGVfcGFnZXMobWFwcGluZywgJnBhZ2VfcG9vbCwgZmlsbGVyLCBOVUxMKTsKfQoKCnN0YXRpYyBzdHJ1Y3QgcGFnZSogcGFnZV9yZWFkYWhlYWQoc3RydWN0IGFkZHJlc3Nfc3BhY2UgKm1hcHBpbmcsIGludCBpbmRleCkKewoJZmlsbGVyX3QgKmZpbGxlciA9IChmaWxsZXJfdCopbWFwcGluZy0+YV9vcHMtPnJlYWRwYWdlOwoJY2FjaGVfcmVhZGFoZWFkKG1hcHBpbmcsIGluZGV4KTsKCXJldHVybiByZWFkX2NhY2hlX3BhZ2UobWFwcGluZywgaW5kZXgsIGZpbGxlciwgTlVMTCk7Cn0KCgovKiBlcmFzZSBhIHNwZWNpZmllZCBwYXJ0IG9mIHRoZSBkZXZpY2UgKi8Kc3RhdGljIGludCBfYmxvY2sybXRkX2VyYXNlKHN0cnVjdCBibG9jazJtdGRfZGV2ICpkZXYsIGxvZmZfdCB0bywgc2l6ZV90IGxlbikKewoJc3RydWN0IGFkZHJlc3Nfc3BhY2UgKm1hcHBpbmcgPSBkZXYtPmJsa2Rldi0+YmRfaW5vZGUtPmlfbWFwcGluZzsKCXN0cnVjdCBwYWdlICpwYWdlOwoJaW50IGluZGV4ID0gdG8gPj4gUEFHRV9TSElGVDsJLy8gcGFnZSBpbmRleAoJaW50IHBhZ2VzID0gbGVuID4+IFBBR0VfU0hJRlQ7Cgl1X2xvbmcgKnA7Cgl1X2xvbmcgKm1heDsKCgl3aGlsZSAocGFnZXMpIHsKCQlwYWdlID0gcGFnZV9yZWFkYWhlYWQobWFwcGluZywgaW5kZXgpOwoJCWlmICghcGFnZSkKCQkJcmV0dXJuIC1FTk9NRU07CgkJaWYgKElTX0VSUihwYWdlKSkKCQkJcmV0dXJuIFBUUl9FUlIocGFnZSk7CgoJCW1heCA9ICh1X2xvbmcqKXBhZ2VfYWRkcmVzcyhwYWdlKSArIFBBR0VfU0laRTsKCQlmb3IgKHA9KHVfbG9uZyopcGFnZV9hZGRyZXNzKHBhZ2UpOyBwPG1heDsgcCsrKSAKCQkJaWYgKCpwICE9IC0xVUwpIHsKCQkJCWxvY2tfcGFnZShwYWdlKTsKCQkJCW1lbXNldChwYWdlX2FkZHJlc3MocGFnZSksIDB4ZmYsIFBBR0VfU0laRSk7CgkJCQlzZXRfcGFnZV9kaXJ0eShwYWdlKTsKCQkJCXVubG9ja19wYWdlKHBhZ2UpOwoJCQkJYnJlYWs7CgkJCX0KCgkJcGFnZV9jYWNoZV9yZWxlYXNlKHBhZ2UpOwoJCXBhZ2VzLS07CgkJaW5kZXgrKzsKCX0KCXJldHVybiAwOwp9CnN0YXRpYyBpbnQgYmxvY2sybXRkX2VyYXNlKHN0cnVjdCBtdGRfaW5mbyAqbXRkLCBzdHJ1Y3QgZXJhc2VfaW5mbyAqaW5zdHIpCnsKCXN0cnVjdCBibG9jazJtdGRfZGV2ICpkZXYgPSBtdGQtPnByaXY7CglzaXplX3QgZnJvbSA9IGluc3RyLT5hZGRyOwoJc2l6ZV90IGxlbiA9IGluc3RyLT5sZW47CglpbnQgZXJyOwoKCWluc3RyLT5zdGF0ZSA9IE1URF9FUkFTSU5HOwoJZG93bigmZGV2LT53cml0ZV9tdXRleCk7CgllcnIgPSBfYmxvY2sybXRkX2VyYXNlKGRldiwgZnJvbSwgbGVuKTsKCXVwKCZkZXYtPndyaXRlX211dGV4KTsKCWlmIChlcnIpIHsKCQlFUlJPUigiZXJhc2UgZmFpbGVkIGVyciA9ICVkIiwgZXJyKTsKCQlpbnN0ci0+c3RhdGUgPSBNVERfRVJBU0VfRkFJTEVEOwoJfSBlbHNlCgkJaW5zdHItPnN0YXRlID0gTVREX0VSQVNFX0RPTkU7CgoJaW5zdHItPnN0YXRlID0gTVREX0VSQVNFX0RPTkU7CgltdGRfZXJhc2VfY2FsbGJhY2soaW5zdHIpOwoJcmV0dXJuIGVycjsKfQoKCnN0YXRpYyBpbnQgYmxvY2sybXRkX3JlYWQoc3RydWN0IG10ZF9pbmZvICptdGQsIGxvZmZfdCBmcm9tLCBzaXplX3QgbGVuLAoJCXNpemVfdCAqcmV0bGVuLCB1X2NoYXIgKmJ1ZikKewoJc3RydWN0IGJsb2NrMm10ZF9kZXYgKmRldiA9IG10ZC0+cHJpdjsKCXN0cnVjdCBwYWdlICpwYWdlOwoJaW50IGluZGV4ID0gZnJvbSA+PiBQQUdFX1NISUZUOwoJaW50IG9mZnNldCA9IGZyb20gJiAoUEFHRV9TSVpFLTEpOwoJaW50IGNweWxlbjsKCglpZiAoZnJvbSA+IG10ZC0+c2l6ZSkKCQlyZXR1cm4gLUVJTlZBTDsKCWlmIChmcm9tICsgbGVuID4gbXRkLT5zaXplKQoJCWxlbiA9IG10ZC0+c2l6ZSAtIGZyb207CgoJaWYgKHJldGxlbikKCQkqcmV0bGVuID0gMDsKCgl3aGlsZSAobGVuKSB7CgkJaWYgKChvZmZzZXQgKyBsZW4pID4gUEFHRV9TSVpFKQoJCQljcHlsZW4gPSBQQUdFX1NJWkUgLSBvZmZzZXQ7CS8vIG11bHRpcGxlIHBhZ2VzCgkJZWxzZQoJCQljcHlsZW4gPSBsZW47CS8vIHRoaXMgcGFnZQoJCWxlbiA9IGxlbiAtIGNweWxlbjsKCgkJLy8gICAgICBHZXQgcGFnZQoJCXBhZ2UgPSBwYWdlX3JlYWRhaGVhZChkZXYtPmJsa2Rldi0+YmRfaW5vZGUtPmlfbWFwcGluZywgaW5kZXgpOwoJCWlmICghcGFnZSkKCQkJcmV0dXJuIC1FTk9NRU07CgkJaWYgKElTX0VSUihwYWdlKSkKCQkJcmV0dXJuIFBUUl9FUlIocGFnZSk7CgoJCW1lbWNweShidWYsIHBhZ2VfYWRkcmVzcyhwYWdlKSArIG9mZnNldCwgY3B5bGVuKTsKCQlwYWdlX2NhY2hlX3JlbGVhc2UocGFnZSk7CgoJCWlmIChyZXRsZW4pCgkJCSpyZXRsZW4gKz0gY3B5bGVuOwoJCWJ1ZiArPSBjcHlsZW47CgkJb2Zmc2V0ID0gMDsKCQlpbmRleCsrOwoJfQoJcmV0dXJuIDA7Cn0KCgovKiB3cml0ZSBkYXRhIHRvIHRoZSB1bmRlcmx5aW5nIGRldmljZSAqLwpzdGF0aWMgaW50IF9ibG9jazJtdGRfd3JpdGUoc3RydWN0IGJsb2NrMm10ZF9kZXYgKmRldiwgY29uc3QgdV9jaGFyICpidWYsCgkJbG9mZl90IHRvLCBzaXplX3QgbGVuLCBzaXplX3QgKnJldGxlbikKewoJc3RydWN0IHBhZ2UgKnBhZ2U7CglzdHJ1Y3QgYWRkcmVzc19zcGFjZSAqbWFwcGluZyA9IGRldi0+YmxrZGV2LT5iZF9pbm9kZS0+aV9tYXBwaW5nOwoJaW50IGluZGV4ID0gdG8gPj4gUEFHRV9TSElGVDsJLy8gcGFnZSBpbmRleAoJaW50IG9mZnNldCA9IHRvICYgflBBR0VfTUFTSzsJLy8gcGFnZSBvZmZzZXQKCWludCBjcHlsZW47CgoJaWYgKHJldGxlbikKCQkqcmV0bGVuID0gMDsKCXdoaWxlIChsZW4pIHsKCQlpZiAoKG9mZnNldCtsZW4pID4gUEFHRV9TSVpFKSAKCQkJY3B5bGVuID0gUEFHRV9TSVpFIC0gb2Zmc2V0OwkvLyBtdWx0aXBsZSBwYWdlcwoJCWVsc2UKCQkJY3B5bGVuID0gbGVuOwkJCS8vIHRoaXMgcGFnZQoJCWxlbiA9IGxlbiAtIGNweWxlbjsKCgkJLy8JR2V0IHBhZ2UKCQlwYWdlID0gcGFnZV9yZWFkYWhlYWQobWFwcGluZywgaW5kZXgpOwoJCWlmICghcGFnZSkKCQkJcmV0dXJuIC1FTk9NRU07CgkJaWYgKElTX0VSUihwYWdlKSkKCQkJcmV0dXJuIFBUUl9FUlIocGFnZSk7CgoJCWlmIChtZW1jbXAocGFnZV9hZGRyZXNzKHBhZ2UpK29mZnNldCwgYnVmLCBjcHlsZW4pKSB7CgkJCWxvY2tfcGFnZShwYWdlKTsKCQkJbWVtY3B5KHBhZ2VfYWRkcmVzcyhwYWdlKSArIG9mZnNldCwgYnVmLCBjcHlsZW4pOwoJCQlzZXRfcGFnZV9kaXJ0eShwYWdlKTsKCQkJdW5sb2NrX3BhZ2UocGFnZSk7CgkJfQoJCXBhZ2VfY2FjaGVfcmVsZWFzZShwYWdlKTsKCgkJaWYgKHJldGxlbikKCQkJKnJldGxlbiArPSBjcHlsZW47CgoJCWJ1ZiArPSBjcHlsZW47CgkJb2Zmc2V0ID0gMDsKCQlpbmRleCsrOwoJfQoJcmV0dXJuIDA7Cn0Kc3RhdGljIGludCBibG9jazJtdGRfd3JpdGUoc3RydWN0IG10ZF9pbmZvICptdGQsIGxvZmZfdCB0bywgc2l6ZV90IGxlbiwKCQlzaXplX3QgKnJldGxlbiwgY29uc3QgdV9jaGFyICpidWYpCnsKCXN0cnVjdCBibG9jazJtdGRfZGV2ICpkZXYgPSBtdGQtPnByaXY7CglpbnQgZXJyOwoKCWlmICghbGVuKQoJCXJldHVybiAwOwoJaWYgKHRvID49IG10ZC0+c2l6ZSkKCQlyZXR1cm4gLUVOT1NQQzsKCWlmICh0byArIGxlbiA+IG10ZC0+c2l6ZSkKCQlsZW4gPSBtdGQtPnNpemUgLSB0bzsKCglkb3duKCZkZXYtPndyaXRlX211dGV4KTsKCWVyciA9IF9ibG9jazJtdGRfd3JpdGUoZGV2LCBidWYsIHRvLCBsZW4sIHJldGxlbik7Cgl1cCgmZGV2LT53cml0ZV9tdXRleCk7CglpZiAoZXJyID4gMCkKCQllcnIgPSAwOwoJcmV0dXJuIGVycjsKfQoKCi8qIHN5bmMgdGhlIGRldmljZSAtIHdhaXQgdW50aWwgdGhlIHdyaXRlIHF1ZXVlIGlzIGVtcHR5ICovCnN0YXRpYyB2b2lkIGJsb2NrMm10ZF9zeW5jKHN0cnVjdCBtdGRfaW5mbyAqbXRkKQp7CglzdHJ1Y3QgYmxvY2sybXRkX2RldiAqZGV2ID0gbXRkLT5wcml2OwoJc3luY19ibG9ja2RldihkZXYtPmJsa2Rldik7CglyZXR1cm47Cn0KCgpzdGF0aWMgdm9pZCBibG9jazJtdGRfZnJlZV9kZXZpY2Uoc3RydWN0IGJsb2NrMm10ZF9kZXYgKmRldikKewoJaWYgKCFkZXYpCgkJcmV0dXJuOwoKCWtmcmVlKGRldi0+bXRkLm5hbWUpOwoKCWlmIChkZXYtPmJsa2RldikgewoJCWludmFsaWRhdGVfaW5vZGVfcGFnZXMoZGV2LT5ibGtkZXYtPmJkX2lub2RlLT5pX21hcHBpbmcpOwoJCWNsb3NlX2JkZXZfZXhjbChkZXYtPmJsa2Rldik7Cgl9CgoJa2ZyZWUoZGV2KTsKfQoKCi8qIEZJWE1FOiBlbnN1cmUgdGhhdCBtdGQtPnNpemUgJSBlcmFzZV9zaXplID09IDAgKi8Kc3RhdGljIHN0cnVjdCBibG9jazJtdGRfZGV2ICphZGRfZGV2aWNlKGNoYXIgKmRldm5hbWUsIGludCBlcmFzZV9zaXplKQp7CglzdHJ1Y3QgYmxvY2tfZGV2aWNlICpiZGV2OwoJc3RydWN0IGJsb2NrMm10ZF9kZXYgKmRldjsKCglpZiAoIWRldm5hbWUpCgkJcmV0dXJuIE5VTEw7CgoJZGV2ID0ga21hbGxvYyhzaXplb2Yoc3RydWN0IGJsb2NrMm10ZF9kZXYpLCBHRlBfS0VSTkVMKTsKCWlmICghZGV2KQoJCXJldHVybiBOVUxMOwoJbWVtc2V0KGRldiwgMCwgc2l6ZW9mKCpkZXYpKTsKCgkvKiBHZXQgYSBoYW5kbGUgb24gdGhlIGRldmljZSAqLwoJYmRldiA9IG9wZW5fYmRldl9leGNsKGRldm5hbWUsIE9fUkRXUiwgTlVMTCk7CglpZiAoSVNfRVJSKGJkZXYpKSB7CgkJRVJST1IoImVycm9yOiBjYW5ub3Qgb3BlbiBkZXZpY2UgJXMiLCBkZXZuYW1lKTsKCQlnb3RvIGRldmluaXRfZXJyOwoJfQoJZGV2LT5ibGtkZXYgPSBiZGV2OwoKCWlmIChNQUpPUihiZGV2LT5iZF9kZXYpID09IE1URF9CTE9DS19NQUpPUikgewoJCUVSUk9SKCJhdHRlbXB0aW5nIHRvIHVzZSBhbiBNVEQgZGV2aWNlIGFzIGEgYmxvY2sgZGV2aWNlIik7CgkJZ290byBkZXZpbml0X2VycjsKCX0KCglpbml0X01VVEVYKCZkZXYtPndyaXRlX211dGV4KTsKCgkvKiBTZXR1cCB0aGUgTVREIHN0cnVjdHVyZSAqLwoJLyogbWFrZSB0aGUgbmFtZSBjb250YWluIHRoZSBibG9jayBkZXZpY2UgaW4gKi8KCWRldi0+bXRkLm5hbWUgPSBrbWFsbG9jKHNpemVvZigiYmxvY2sybXRkOiAiKSArIHN0cmxlbihkZXZuYW1lKSwKCQkJR0ZQX0tFUk5FTCk7CglpZiAoIWRldi0+bXRkLm5hbWUpCgkJZ290byBkZXZpbml0X2VycjsKCglzcHJpbnRmKGRldi0+bXRkLm5hbWUsICJibG9jazJtdGQ6ICVzIiwgZGV2bmFtZSk7CgoJZGV2LT5tdGQuc2l6ZSA9IGRldi0+YmxrZGV2LT5iZF9pbm9kZS0+aV9zaXplICYgUEFHRV9NQVNLOwoJZGV2LT5tdGQuZXJhc2VzaXplID0gZXJhc2Vfc2l6ZTsKCWRldi0+bXRkLnR5cGUgPSBNVERfUkFNOwoJZGV2LT5tdGQuZmxhZ3MgPSBNVERfQ0FQX1JBTTsKCWRldi0+bXRkLmVyYXNlID0gYmxvY2sybXRkX2VyYXNlOwoJZGV2LT5tdGQud3JpdGUgPSBibG9jazJtdGRfd3JpdGU7CglkZXYtPm10ZC53cml0ZXYgPSBkZWZhdWx0X210ZF93cml0ZXY7CglkZXYtPm10ZC5zeW5jID0gYmxvY2sybXRkX3N5bmM7CglkZXYtPm10ZC5yZWFkID0gYmxvY2sybXRkX3JlYWQ7CglkZXYtPm10ZC5yZWFkdiA9IGRlZmF1bHRfbXRkX3JlYWR2OwoJZGV2LT5tdGQucHJpdiA9IGRldjsKCWRldi0+bXRkLm93bmVyID0gVEhJU19NT0RVTEU7CgoJaWYgKGFkZF9tdGRfZGV2aWNlKCZkZXYtPm10ZCkpIHsKCQkvKiBEZXZpY2UgZGlkbnQgZ2V0IGFkZGVkLCBzbyBmcmVlIHRoZSBlbnRyeSAqLwoJCWdvdG8gZGV2aW5pdF9lcnI7Cgl9CglsaXN0X2FkZCgmZGV2LT5saXN0LCAmYmxrbXRkX2RldmljZV9saXN0KTsKCUlORk8oIm10ZCVkOiBbJXNdIGVyYXNlX3NpemUgPSAlZEtpQiBbJWRdIiwgZGV2LT5tdGQuaW5kZXgsCgkJCWRldi0+bXRkLm5hbWUgKyBzdHJsZW4oImJsa210ZDogIiksCgkJCWRldi0+bXRkLmVyYXNlc2l6ZSA+PiAxMCwgZGV2LT5tdGQuZXJhc2VzaXplKTsKCXJldHVybiBkZXY7CgpkZXZpbml0X2VycjoKCWJsb2NrMm10ZF9mcmVlX2RldmljZShkZXYpOwoJcmV0dXJuIE5VTEw7Cn0KCgpzdGF0aWMgaW50IHVzdHJ0b3VsKGNvbnN0IGNoYXIgKmNwLCBjaGFyICoqZW5kcCwgdW5zaWduZWQgaW50IGJhc2UpCnsKCXVuc2lnbmVkIGxvbmcgcmVzdWx0ID0gc2ltcGxlX3N0cnRvdWwoY3AsIGVuZHAsIGJhc2UpOwoJc3dpdGNoICgqKmVuZHApIHsKCWNhc2UgJ0cnIDoKCQlyZXN1bHQgKj0gMTAyNDsKCWNhc2UgJ00nOgoJCXJlc3VsdCAqPSAxMDI0OwoJY2FzZSAnayc6CgkJcmVzdWx0ICo9IDEwMjQ7CgkvKiBCeSBkd213MiBlZGl0b3JpYWwgZGVjcmVlLCAia2kiLCAiTWkiIG9yICJHaSIgYXJlIHRvIGJlIHVzZWQuICovCgkJaWYgKCgqZW5kcClbMV0gPT0gJ2knKQoJCQkoKmVuZHApICs9IDI7Cgl9CglyZXR1cm4gcmVzdWx0Owp9CgoKc3RhdGljIGludCBwYXJzZV9udW0oc2l6ZV90ICpudW0sIGNvbnN0IGNoYXIgKnRva2VuKQp7CgljaGFyICplbmRwOwoJc2l6ZV90IG47CgoJbiA9IChzaXplX3QpIHVzdHJ0b3VsKHRva2VuLCAmZW5kcCwgMCk7CglpZiAoKmVuZHApCgkJcmV0dXJuIC1FSU5WQUw7CgoJKm51bSA9IG47CglyZXR1cm4gMDsKfQoKCnN0YXRpYyBpbnQgcGFyc2VfbmFtZShjaGFyICoqcG5hbWUsIGNvbnN0IGNoYXIgKnRva2VuLCBzaXplX3QgbGltaXQpCnsKCXNpemVfdCBsZW47CgljaGFyICpuYW1lOwoKCWxlbiA9IHN0cmxlbih0b2tlbikgKyAxOwoJaWYgKGxlbiA+IGxpbWl0KQoJCXJldHVybiAtRU5PU1BDOwoKCW5hbWUgPSBrbWFsbG9jKGxlbiwgR0ZQX0tFUk5FTCk7CglpZiAoIW5hbWUpCgkJcmV0dXJuIC1FTk9NRU07CgoJc3RyY3B5KG5hbWUsIHRva2VuKTsKCgkqcG5hbWUgPSBuYW1lOwoJcmV0dXJuIDA7Cn0KCgpzdGF0aWMgaW5saW5lIHZvaWQga2lsbF9maW5hbF9uZXdsaW5lKGNoYXIgKnN0cikKewoJY2hhciAqbmV3bGluZSA9IHN0cnJjaHIoc3RyLCAnXG4nKTsKCWlmIChuZXdsaW5lICYmICFuZXdsaW5lWzFdKQoJCSpuZXdsaW5lID0gMDsKfQoKCiNkZWZpbmUgcGFyc2VfZXJyKGZtdCwgYXJncy4uLikgZG8gewkJXAoJRVJST1IoImJsb2NrMm10ZDogIiBmbXQgIlxuIiwgIyMgYXJncyk7CVwKCXJldHVybiAwOwkJCQlcCn0gd2hpbGUgKDApCgpzdGF0aWMgaW50IGJsb2NrMm10ZF9zZXR1cChjb25zdCBjaGFyICp2YWwsIHN0cnVjdCBrZXJuZWxfcGFyYW0gKmtwKQp7CgljaGFyIGJ1Zls4MCsxMl0sICpzdHI9YnVmOyAvKiA4MCBmb3IgZGV2aWNlLCAxMiBmb3IgZXJhc2Ugc2l6ZSAqLwoJY2hhciAqdG9rZW5bMl07CgljaGFyICpuYW1lOwoJc2l6ZV90IGVyYXNlX3NpemUgPSBQQUdFX1NJWkU7CglpbnQgaSwgcmV0OwoKCWlmIChzdHJubGVuKHZhbCwgc2l6ZW9mKGJ1ZikpID49IHNpemVvZihidWYpKQoJCXBhcnNlX2VycigicGFyYW1ldGVyIHRvbyBsb25nIik7CgoJc3RyY3B5KHN0ciwgdmFsKTsKCWtpbGxfZmluYWxfbmV3bGluZShzdHIpOwoKCWZvciAoaT0wOyBpPDI7IGkrKykKCQl0b2tlbltpXSA9IHN0cnNlcCgmc3RyLCAiLCIpOwoKCWlmIChzdHIpCgkJcGFyc2VfZXJyKCJ0b28gbWFueSBhcmd1bWVudHMiKTsKCglpZiAoIXRva2VuWzBdKQoJCXBhcnNlX2Vycigibm8gYXJndW1lbnQiKTsKCglyZXQgPSBwYXJzZV9uYW1lKCZuYW1lLCB0b2tlblswXSwgODApOwoJaWYgKHJldCA9PSAtRU5PTUVNKQoJCXBhcnNlX2Vycigib3V0IG9mIG1lbW9yeSIpOwoJaWYgKHJldCA9PSAtRU5PU1BDKQoJCXBhcnNlX2VycigibmFtZSB0b28gbG9uZyIpOwoJaWYgKHJldCkKCQlyZXR1cm4gMDsKCglpZiAodG9rZW5bMV0pIHsKCQlyZXQgPSBwYXJzZV9udW0oJmVyYXNlX3NpemUsIHRva2VuWzFdKTsKCQlpZiAocmV0KQoJCQlwYXJzZV9lcnIoImlsbGVnYWwgZXJhc2Ugc2l6ZSIpOwoJfQoKCWFkZF9kZXZpY2UobmFtZSwgZXJhc2Vfc2l6ZSk7CgoJcmV0dXJuIDA7Cn0KCgptb2R1bGVfcGFyYW1fY2FsbChibG9jazJtdGQsIGJsb2NrMm10ZF9zZXR1cCwgTlVMTCwgTlVMTCwgMDIwMCk7Ck1PRFVMRV9QQVJNX0RFU0MoYmxvY2sybXRkLCAiRGV2aWNlIHRvIHVzZS4gXCJibG9jazJtdGQ9PGRldj5bLDxlcmFzZXNpemU+XVwiIik7CgpzdGF0aWMgaW50IF9faW5pdCBibG9jazJtdGRfaW5pdCh2b2lkKQp7CglJTkZPKCJ2ZXJzaW9uICIgVkVSU0lPTik7CglyZXR1cm4gMDsKfQoKCnN0YXRpYyB2b2lkIF9fZGV2ZXhpdCBibG9jazJtdGRfZXhpdCh2b2lkKQp7CglzdHJ1Y3QgbGlzdF9oZWFkICpwb3MsICpuZXh0OwoKCS8qIFJlbW92ZSB0aGUgTVREIGRldmljZXMgKi8KCWxpc3RfZm9yX2VhY2hfc2FmZShwb3MsIG5leHQsICZibGttdGRfZGV2aWNlX2xpc3QpIHsKCQlzdHJ1Y3QgYmxvY2sybXRkX2RldiAqZGV2ID0gbGlzdF9lbnRyeShwb3MsIHR5cGVvZigqZGV2KSwgbGlzdCk7CgkJYmxvY2sybXRkX3N5bmMoJmRldi0+bXRkKTsKCQlkZWxfbXRkX2RldmljZSgmZGV2LT5tdGQpOwoJCUlORk8oIm10ZCVkOiBbJXNdIHJlbW92ZWQiLCBkZXYtPm10ZC5pbmRleCwKCQkJCWRldi0+bXRkLm5hbWUgKyBzdHJsZW4oImJsa210ZDogIikpOwoJCWxpc3RfZGVsKCZkZXYtPmxpc3QpOwoJCWJsb2NrMm10ZF9mcmVlX2RldmljZShkZXYpOwoJfQp9CgoKbW9kdWxlX2luaXQoYmxvY2sybXRkX2luaXQpOwptb2R1bGVfZXhpdChibG9jazJtdGRfZXhpdCk7CgpNT0RVTEVfTElDRU5TRSgiR1BMIik7Ck1PRFVMRV9BVVRIT1IoIlNpbW9uIEV2YW5zIDxzcHNlQHNlY3JldC5vcmcudWs+IGFuZCBvdGhlcnMiKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJFbXVsYXRlIGFuIE1URCB1c2luZyBhIGJsb2NrIGRldmljZSIpOwo=