LyoKICogJElkOiBibG9jazJtdGQuYyx2IDEuMzAgMjAwNS8xMS8yOSAxNDo0ODozMiBnbGVpeG5lciBFeHAgJAogKgogKiBibG9jazJtdGQuYyAtIGNyZWF0ZSBhbiBtdGQgZnJvbSBhIGJsb2NrIGRldmljZQogKgogKiBDb3B5cmlnaHQgKEMpIDIwMDEsMjAwMglTaW1vbiBFdmFucyA8c3BzZUBzZWNyZXQub3JnLnVrPgogKiBDb3B5cmlnaHQgKEMpIDIwMDQsMjAwNQlK9nJuIEVuZ2VsIDxqb2VybkB3aC5maC13ZWRlbC5kZT4KICoKICogTGljZW5jZTogR1BMCiAqLwojaW5jbHVkZSA8bGludXgvY29uZmlnLmg+CiNpbmNsdWRlIDxsaW51eC9tb2R1bGUuaD4KI2luY2x1ZGUgPGxpbnV4L2ZzLmg+CiNpbmNsdWRlIDxsaW51eC9ibGtkZXYuaD4KI2luY2x1ZGUgPGxpbnV4L2Jpby5oPgojaW5jbHVkZSA8bGludXgvcGFnZW1hcC5oPgojaW5jbHVkZSA8bGludXgvbGlzdC5oPgojaW5jbHVkZSA8bGludXgvaW5pdC5oPgojaW5jbHVkZSA8bGludXgvbXRkL210ZC5oPgojaW5jbHVkZSA8bGludXgvYnVmZmVyX2hlYWQuaD4KCiNkZWZpbmUgVkVSU0lPTiAiJFJldmlzaW9uOiAxLjMwICQiCgoKI2RlZmluZSBFUlJPUihmbXQsIGFyZ3MuLi4pIHByaW50ayhLRVJOX0VSUiAiYmxvY2sybXRkOiAiIGZtdCAiXG4iICwgIyMgYXJncykKI2RlZmluZSBJTkZPKGZtdCwgYXJncy4uLikgcHJpbnRrKEtFUk5fSU5GTyAiYmxvY2sybXRkOiAiIGZtdCAiXG4iICwgIyMgYXJncykKCgovKiBJbmZvIGZvciB0aGUgYmxvY2sgZGV2aWNlICovCnN0cnVjdCBibG9jazJtdGRfZGV2IHsKCXN0cnVjdCBsaXN0X2hlYWQgbGlzdDsKCXN0cnVjdCBibG9ja19kZXZpY2UgKmJsa2RldjsKCXN0cnVjdCBtdGRfaW5mbyBtdGQ7CglzdHJ1Y3Qgc2VtYXBob3JlIHdyaXRlX211dGV4Owp9OwoKCi8qIFN0YXRpYyBpbmZvIGFib3V0IHRoZSBNVEQsIHVzZWQgaW4gY2xlYW51cF9tb2R1bGUgKi8Kc3RhdGljIExJU1RfSEVBRChibGttdGRfZGV2aWNlX2xpc3QpOwoKCiNkZWZpbmUgUEFHRV9SRUFEQUhFQUQgNjQKc3RhdGljIHZvaWQgY2FjaGVfcmVhZGFoZWFkKHN0cnVjdCBhZGRyZXNzX3NwYWNlICptYXBwaW5nLCBpbnQgaW5kZXgpCnsKCWZpbGxlcl90ICpmaWxsZXIgPSAoZmlsbGVyX3QqKW1hcHBpbmctPmFfb3BzLT5yZWFkcGFnZTsKCWludCBpLCBwYWdlaTsKCXVuc2lnbmVkIHJldCA9IDA7Cgl1bnNpZ25lZCBsb25nIGVuZF9pbmRleDsKCXN0cnVjdCBwYWdlICpwYWdlOwoJTElTVF9IRUFEKHBhZ2VfcG9vbCk7CglzdHJ1Y3QgaW5vZGUgKmlub2RlID0gbWFwcGluZy0+aG9zdDsKCWxvZmZfdCBpc2l6ZSA9IGlfc2l6ZV9yZWFkKGlub2RlKTsKCglpZiAoIWlzaXplKSB7CgkJSU5GTygiaVNpemU9MCBpbiBjYWNoZV9yZWFkYWhlYWRcbiIpOwoJCXJldHVybjsKCX0KCgllbmRfaW5kZXggPSAoKGlzaXplIC0gMSkgPj4gUEFHRV9DQUNIRV9TSElGVCk7CgoJcmVhZF9sb2NrX2lycSgmbWFwcGluZy0+dHJlZV9sb2NrKTsKCWZvciAoaSA9IDA7IGkgPCBQQUdFX1JFQURBSEVBRDsgaSsrKSB7CgkJcGFnZWkgPSBpbmRleCArIGk7CgkJaWYgKHBhZ2VpID4gZW5kX2luZGV4KSB7CgkJCUlORk8oIk92ZXJydW4gZW5kIG9mIGRpc2sgaW4gY2FjaGUgcmVhZGFoZWFkXG4iKTsKCQkJYnJlYWs7CgkJfQoJCXBhZ2UgPSByYWRpeF90cmVlX2xvb2t1cCgmbWFwcGluZy0+cGFnZV90cmVlLCBwYWdlaSk7CgkJaWYgKHBhZ2UgJiYgKCFpKSkKCQkJYnJlYWs7CgkJaWYgKHBhZ2UpCgkJCWNvbnRpbnVlOwoJCXJlYWRfdW5sb2NrX2lycSgmbWFwcGluZy0+dHJlZV9sb2NrKTsKCQlwYWdlID0gcGFnZV9jYWNoZV9hbGxvY19jb2xkKG1hcHBpbmcpOwoJCXJlYWRfbG9ja19pcnEoJm1hcHBpbmctPnRyZWVfbG9jayk7CgkJaWYgKCFwYWdlKQoJCQlicmVhazsKCQlwYWdlLT5pbmRleCA9IHBhZ2VpOwoJCWxpc3RfYWRkKCZwYWdlLT5scnUsICZwYWdlX3Bvb2wpOwoJCXJldCsrOwoJfQoJcmVhZF91bmxvY2tfaXJxKCZtYXBwaW5nLT50cmVlX2xvY2spOwoJaWYgKHJldCkKCQlyZWFkX2NhY2hlX3BhZ2VzKG1hcHBpbmcsICZwYWdlX3Bvb2wsIGZpbGxlciwgTlVMTCk7Cn0KCgpzdGF0aWMgc3RydWN0IHBhZ2UqIHBhZ2VfcmVhZGFoZWFkKHN0cnVjdCBhZGRyZXNzX3NwYWNlICptYXBwaW5nLCBpbnQgaW5kZXgpCnsKCWZpbGxlcl90ICpmaWxsZXIgPSAoZmlsbGVyX3QqKW1hcHBpbmctPmFfb3BzLT5yZWFkcGFnZTsKCWNhY2hlX3JlYWRhaGVhZChtYXBwaW5nLCBpbmRleCk7CglyZXR1cm4gcmVhZF9jYWNoZV9wYWdlKG1hcHBpbmcsIGluZGV4LCBmaWxsZXIsIE5VTEwpOwp9CgoKLyogZXJhc2UgYSBzcGVjaWZpZWQgcGFydCBvZiB0aGUgZGV2aWNlICovCnN0YXRpYyBpbnQgX2Jsb2NrMm10ZF9lcmFzZShzdHJ1Y3QgYmxvY2sybXRkX2RldiAqZGV2LCBsb2ZmX3QgdG8sIHNpemVfdCBsZW4pCnsKCXN0cnVjdCBhZGRyZXNzX3NwYWNlICptYXBwaW5nID0gZGV2LT5ibGtkZXYtPmJkX2lub2RlLT5pX21hcHBpbmc7CglzdHJ1Y3QgcGFnZSAqcGFnZTsKCWludCBpbmRleCA9IHRvID4+IFBBR0VfU0hJRlQ7CS8vIHBhZ2UgaW5kZXgKCWludCBwYWdlcyA9IGxlbiA+PiBQQUdFX1NISUZUOwoJdV9sb25nICpwOwoJdV9sb25nICptYXg7CgoJd2hpbGUgKHBhZ2VzKSB7CgkJcGFnZSA9IHBhZ2VfcmVhZGFoZWFkKG1hcHBpbmcsIGluZGV4KTsKCQlpZiAoIXBhZ2UpCgkJCXJldHVybiAtRU5PTUVNOwoJCWlmIChJU19FUlIocGFnZSkpCgkJCXJldHVybiBQVFJfRVJSKHBhZ2UpOwoKCQltYXggPSAodV9sb25nKilwYWdlX2FkZHJlc3MocGFnZSkgKyBQQUdFX1NJWkU7CgkJZm9yIChwPSh1X2xvbmcqKXBhZ2VfYWRkcmVzcyhwYWdlKTsgcDxtYXg7IHArKykKCQkJaWYgKCpwICE9IC0xVUwpIHsKCQkJCWxvY2tfcGFnZShwYWdlKTsKCQkJCW1lbXNldChwYWdlX2FkZHJlc3MocGFnZSksIDB4ZmYsIFBBR0VfU0laRSk7CgkJCQlzZXRfcGFnZV9kaXJ0eShwYWdlKTsKCQkJCXVubG9ja19wYWdlKHBhZ2UpOwoJCQkJYnJlYWs7CgkJCX0KCgkJcGFnZV9jYWNoZV9yZWxlYXNlKHBhZ2UpOwoJCXBhZ2VzLS07CgkJaW5kZXgrKzsKCX0KCXJldHVybiAwOwp9CnN0YXRpYyBpbnQgYmxvY2sybXRkX2VyYXNlKHN0cnVjdCBtdGRfaW5mbyAqbXRkLCBzdHJ1Y3QgZXJhc2VfaW5mbyAqaW5zdHIpCnsKCXN0cnVjdCBibG9jazJtdGRfZGV2ICpkZXYgPSBtdGQtPnByaXY7CglzaXplX3QgZnJvbSA9IGluc3RyLT5hZGRyOwoJc2l6ZV90IGxlbiA9IGluc3RyLT5sZW47CglpbnQgZXJyOwoKCWluc3RyLT5zdGF0ZSA9IE1URF9FUkFTSU5HOwoJZG93bigmZGV2LT53cml0ZV9tdXRleCk7CgllcnIgPSBfYmxvY2sybXRkX2VyYXNlKGRldiwgZnJvbSwgbGVuKTsKCXVwKCZkZXYtPndyaXRlX211dGV4KTsKCWlmIChlcnIpIHsKCQlFUlJPUigiZXJhc2UgZmFpbGVkIGVyciA9ICVkIiwgZXJyKTsKCQlpbnN0ci0+c3RhdGUgPSBNVERfRVJBU0VfRkFJTEVEOwoJfSBlbHNlCgkJaW5zdHItPnN0YXRlID0gTVREX0VSQVNFX0RPTkU7CgoJaW5zdHItPnN0YXRlID0gTVREX0VSQVNFX0RPTkU7CgltdGRfZXJhc2VfY2FsbGJhY2soaW5zdHIpOwoJcmV0dXJuIGVycjsKfQoKCnN0YXRpYyBpbnQgYmxvY2sybXRkX3JlYWQoc3RydWN0IG10ZF9pbmZvICptdGQsIGxvZmZfdCBmcm9tLCBzaXplX3QgbGVuLAoJCXNpemVfdCAqcmV0bGVuLCB1X2NoYXIgKmJ1ZikKewoJc3RydWN0IGJsb2NrMm10ZF9kZXYgKmRldiA9IG10ZC0+cHJpdjsKCXN0cnVjdCBwYWdlICpwYWdlOwoJaW50IGluZGV4ID0gZnJvbSA+PiBQQUdFX1NISUZUOwoJaW50IG9mZnNldCA9IGZyb20gJiAoUEFHRV9TSVpFLTEpOwoJaW50IGNweWxlbjsKCglpZiAoZnJvbSA+IG10ZC0+c2l6ZSkKCQlyZXR1cm4gLUVJTlZBTDsKCWlmIChmcm9tICsgbGVuID4gbXRkLT5zaXplKQoJCWxlbiA9IG10ZC0+c2l6ZSAtIGZyb207CgoJaWYgKHJldGxlbikKCQkqcmV0bGVuID0gMDsKCgl3aGlsZSAobGVuKSB7CgkJaWYgKChvZmZzZXQgKyBsZW4pID4gUEFHRV9TSVpFKQoJCQljcHlsZW4gPSBQQUdFX1NJWkUgLSBvZmZzZXQ7CS8vIG11bHRpcGxlIHBhZ2VzCgkJZWxzZQoJCQljcHlsZW4gPSBsZW47CS8vIHRoaXMgcGFnZQoJCWxlbiA9IGxlbiAtIGNweWxlbjsKCgkJLy8gICAgICBHZXQgcGFnZQoJCXBhZ2UgPSBwYWdlX3JlYWRhaGVhZChkZXYtPmJsa2Rldi0+YmRfaW5vZGUtPmlfbWFwcGluZywgaW5kZXgpOwoJCWlmICghcGFnZSkKCQkJcmV0dXJuIC1FTk9NRU07CgkJaWYgKElTX0VSUihwYWdlKSkKCQkJcmV0dXJuIFBUUl9FUlIocGFnZSk7CgoJCW1lbWNweShidWYsIHBhZ2VfYWRkcmVzcyhwYWdlKSArIG9mZnNldCwgY3B5bGVuKTsKCQlwYWdlX2NhY2hlX3JlbGVhc2UocGFnZSk7CgoJCWlmIChyZXRsZW4pCgkJCSpyZXRsZW4gKz0gY3B5bGVuOwoJCWJ1ZiArPSBjcHlsZW47CgkJb2Zmc2V0ID0gMDsKCQlpbmRleCsrOwoJfQoJcmV0dXJuIDA7Cn0KCgovKiB3cml0ZSBkYXRhIHRvIHRoZSB1bmRlcmx5aW5nIGRldmljZSAqLwpzdGF0aWMgaW50IF9ibG9jazJtdGRfd3JpdGUoc3RydWN0IGJsb2NrMm10ZF9kZXYgKmRldiwgY29uc3QgdV9jaGFyICpidWYsCgkJbG9mZl90IHRvLCBzaXplX3QgbGVuLCBzaXplX3QgKnJldGxlbikKewoJc3RydWN0IHBhZ2UgKnBhZ2U7CglzdHJ1Y3QgYWRkcmVzc19zcGFjZSAqbWFwcGluZyA9IGRldi0+YmxrZGV2LT5iZF9pbm9kZS0+aV9tYXBwaW5nOwoJaW50IGluZGV4ID0gdG8gPj4gUEFHRV9TSElGVDsJLy8gcGFnZSBpbmRleAoJaW50IG9mZnNldCA9IHRvICYgflBBR0VfTUFTSzsJLy8gcGFnZSBvZmZzZXQKCWludCBjcHlsZW47CgoJaWYgKHJldGxlbikKCQkqcmV0bGVuID0gMDsKCXdoaWxlIChsZW4pIHsKCQlpZiAoKG9mZnNldCtsZW4pID4gUEFHRV9TSVpFKQoJCQljcHlsZW4gPSBQQUdFX1NJWkUgLSBvZmZzZXQ7CS8vIG11bHRpcGxlIHBhZ2VzCgkJZWxzZQoJCQljcHlsZW4gPSBsZW47CQkJLy8gdGhpcyBwYWdlCgkJbGVuID0gbGVuIC0gY3B5bGVuOwoKCQkvLwlHZXQgcGFnZQoJCXBhZ2UgPSBwYWdlX3JlYWRhaGVhZChtYXBwaW5nLCBpbmRleCk7CgkJaWYgKCFwYWdlKQoJCQlyZXR1cm4gLUVOT01FTTsKCQlpZiAoSVNfRVJSKHBhZ2UpKQoJCQlyZXR1cm4gUFRSX0VSUihwYWdlKTsKCgkJaWYgKG1lbWNtcChwYWdlX2FkZHJlc3MocGFnZSkrb2Zmc2V0LCBidWYsIGNweWxlbikpIHsKCQkJbG9ja19wYWdlKHBhZ2UpOwoJCQltZW1jcHkocGFnZV9hZGRyZXNzKHBhZ2UpICsgb2Zmc2V0LCBidWYsIGNweWxlbik7CgkJCXNldF9wYWdlX2RpcnR5KHBhZ2UpOwoJCQl1bmxvY2tfcGFnZShwYWdlKTsKCQl9CgkJcGFnZV9jYWNoZV9yZWxlYXNlKHBhZ2UpOwoKCQlpZiAocmV0bGVuKQoJCQkqcmV0bGVuICs9IGNweWxlbjsKCgkJYnVmICs9IGNweWxlbjsKCQlvZmZzZXQgPSAwOwoJCWluZGV4Kys7Cgl9CglyZXR1cm4gMDsKfQpzdGF0aWMgaW50IGJsb2NrMm10ZF93cml0ZShzdHJ1Y3QgbXRkX2luZm8gKm10ZCwgbG9mZl90IHRvLCBzaXplX3QgbGVuLAoJCXNpemVfdCAqcmV0bGVuLCBjb25zdCB1X2NoYXIgKmJ1ZikKewoJc3RydWN0IGJsb2NrMm10ZF9kZXYgKmRldiA9IG10ZC0+cHJpdjsKCWludCBlcnI7CgoJaWYgKCFsZW4pCgkJcmV0dXJuIDA7CglpZiAodG8gPj0gbXRkLT5zaXplKQoJCXJldHVybiAtRU5PU1BDOwoJaWYgKHRvICsgbGVuID4gbXRkLT5zaXplKQoJCWxlbiA9IG10ZC0+c2l6ZSAtIHRvOwoKCWRvd24oJmRldi0+d3JpdGVfbXV0ZXgpOwoJZXJyID0gX2Jsb2NrMm10ZF93cml0ZShkZXYsIGJ1ZiwgdG8sIGxlbiwgcmV0bGVuKTsKCXVwKCZkZXYtPndyaXRlX211dGV4KTsKCWlmIChlcnIgPiAwKQoJCWVyciA9IDA7CglyZXR1cm4gZXJyOwp9CgoKLyogc3luYyB0aGUgZGV2aWNlIC0gd2FpdCB1bnRpbCB0aGUgd3JpdGUgcXVldWUgaXMgZW1wdHkgKi8Kc3RhdGljIHZvaWQgYmxvY2sybXRkX3N5bmMoc3RydWN0IG10ZF9pbmZvICptdGQpCnsKCXN0cnVjdCBibG9jazJtdGRfZGV2ICpkZXYgPSBtdGQtPnByaXY7CglzeW5jX2Jsb2NrZGV2KGRldi0+YmxrZGV2KTsKCXJldHVybjsKfQoKCnN0YXRpYyB2b2lkIGJsb2NrMm10ZF9mcmVlX2RldmljZShzdHJ1Y3QgYmxvY2sybXRkX2RldiAqZGV2KQp7CglpZiAoIWRldikKCQlyZXR1cm47CgoJa2ZyZWUoZGV2LT5tdGQubmFtZSk7CgoJaWYgKGRldi0+YmxrZGV2KSB7CgkJaW52YWxpZGF0ZV9pbm9kZV9wYWdlcyhkZXYtPmJsa2Rldi0+YmRfaW5vZGUtPmlfbWFwcGluZyk7CgkJY2xvc2VfYmRldl9leGNsKGRldi0+YmxrZGV2KTsKCX0KCglrZnJlZShkZXYpOwp9CgoKLyogRklYTUU6IGVuc3VyZSB0aGF0IG10ZC0+c2l6ZSAlIGVyYXNlX3NpemUgPT0gMCAqLwpzdGF0aWMgc3RydWN0IGJsb2NrMm10ZF9kZXYgKmFkZF9kZXZpY2UoY2hhciAqZGV2bmFtZSwgaW50IGVyYXNlX3NpemUpCnsKCXN0cnVjdCBibG9ja19kZXZpY2UgKmJkZXY7CglzdHJ1Y3QgYmxvY2sybXRkX2RldiAqZGV2OwoKCWlmICghZGV2bmFtZSkKCQlyZXR1cm4gTlVMTDsKCglkZXYgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgYmxvY2sybXRkX2RldiksIEdGUF9LRVJORUwpOwoJaWYgKCFkZXYpCgkJcmV0dXJuIE5VTEw7CgltZW1zZXQoZGV2LCAwLCBzaXplb2YoKmRldikpOwoKCS8qIEdldCBhIGhhbmRsZSBvbiB0aGUgZGV2aWNlICovCgliZGV2ID0gb3Blbl9iZGV2X2V4Y2woZGV2bmFtZSwgT19SRFdSLCBOVUxMKTsKCWlmIChJU19FUlIoYmRldikpIHsKCQlFUlJPUigiZXJyb3I6IGNhbm5vdCBvcGVuIGRldmljZSAlcyIsIGRldm5hbWUpOwoJCWdvdG8gZGV2aW5pdF9lcnI7Cgl9CglkZXYtPmJsa2RldiA9IGJkZXY7CgoJaWYgKE1BSk9SKGJkZXYtPmJkX2RldikgPT0gTVREX0JMT0NLX01BSk9SKSB7CgkJRVJST1IoImF0dGVtcHRpbmcgdG8gdXNlIGFuIE1URCBkZXZpY2UgYXMgYSBibG9jayBkZXZpY2UiKTsKCQlnb3RvIGRldmluaXRfZXJyOwoJfQoKCWluaXRfTVVURVgoJmRldi0+d3JpdGVfbXV0ZXgpOwoKCS8qIFNldHVwIHRoZSBNVEQgc3RydWN0dXJlICovCgkvKiBtYWtlIHRoZSBuYW1lIGNvbnRhaW4gdGhlIGJsb2NrIGRldmljZSBpbiAqLwoJZGV2LT5tdGQubmFtZSA9IGttYWxsb2Moc2l6ZW9mKCJibG9jazJtdGQ6ICIpICsgc3RybGVuKGRldm5hbWUpLAoJCQlHRlBfS0VSTkVMKTsKCWlmICghZGV2LT5tdGQubmFtZSkKCQlnb3RvIGRldmluaXRfZXJyOwoKCXNwcmludGYoZGV2LT5tdGQubmFtZSwgImJsb2NrMm10ZDogJXMiLCBkZXZuYW1lKTsKCglkZXYtPm10ZC5zaXplID0gZGV2LT5ibGtkZXYtPmJkX2lub2RlLT5pX3NpemUgJiBQQUdFX01BU0s7CglkZXYtPm10ZC5lcmFzZXNpemUgPSBlcmFzZV9zaXplOwoJZGV2LT5tdGQudHlwZSA9IE1URF9SQU07CglkZXYtPm10ZC5mbGFncyA9IE1URF9DQVBfUkFNOwoJZGV2LT5tdGQuZXJhc2UgPSBibG9jazJtdGRfZXJhc2U7CglkZXYtPm10ZC53cml0ZSA9IGJsb2NrMm10ZF93cml0ZTsKCWRldi0+bXRkLndyaXRldiA9IGRlZmF1bHRfbXRkX3dyaXRldjsKCWRldi0+bXRkLnN5bmMgPSBibG9jazJtdGRfc3luYzsKCWRldi0+bXRkLnJlYWQgPSBibG9jazJtdGRfcmVhZDsKCWRldi0+bXRkLnJlYWR2ID0gZGVmYXVsdF9tdGRfcmVhZHY7CglkZXYtPm10ZC5wcml2ID0gZGV2OwoJZGV2LT5tdGQub3duZXIgPSBUSElTX01PRFVMRTsKCglpZiAoYWRkX210ZF9kZXZpY2UoJmRldi0+bXRkKSkgewoJCS8qIERldmljZSBkaWRudCBnZXQgYWRkZWQsIHNvIGZyZWUgdGhlIGVudHJ5ICovCgkJZ290byBkZXZpbml0X2VycjsKCX0KCWxpc3RfYWRkKCZkZXYtPmxpc3QsICZibGttdGRfZGV2aWNlX2xpc3QpOwoJSU5GTygibXRkJWQ6IFslc10gZXJhc2Vfc2l6ZSA9ICVkS2lCIFslZF0iLCBkZXYtPm10ZC5pbmRleCwKCQkJZGV2LT5tdGQubmFtZSArIHN0cmxlbigiYmxrbXRkOiAiKSwKCQkJZGV2LT5tdGQuZXJhc2VzaXplID4+IDEwLCBkZXYtPm10ZC5lcmFzZXNpemUpOwoJcmV0dXJuIGRldjsKCmRldmluaXRfZXJyOgoJYmxvY2sybXRkX2ZyZWVfZGV2aWNlKGRldik7CglyZXR1cm4gTlVMTDsKfQoKCnN0YXRpYyBpbnQgdXN0cnRvdWwoY29uc3QgY2hhciAqY3AsIGNoYXIgKiplbmRwLCB1bnNpZ25lZCBpbnQgYmFzZSkKewoJdW5zaWduZWQgbG9uZyByZXN1bHQgPSBzaW1wbGVfc3RydG91bChjcCwgZW5kcCwgYmFzZSk7Cglzd2l0Y2ggKCoqZW5kcCkgewoJY2FzZSAnRycgOgoJCXJlc3VsdCAqPSAxMDI0OwoJY2FzZSAnTSc6CgkJcmVzdWx0ICo9IDEwMjQ7CgljYXNlICdrJzoKCQlyZXN1bHQgKj0gMTAyNDsKCS8qIEJ5IGR3bXcyIGVkaXRvcmlhbCBkZWNyZWUsICJraSIsICJNaSIgb3IgIkdpIiBhcmUgdG8gYmUgdXNlZC4gKi8KCQlpZiAoKCplbmRwKVsxXSA9PSAnaScpCgkJCSgqZW5kcCkgKz0gMjsKCX0KCXJldHVybiByZXN1bHQ7Cn0KCgpzdGF0aWMgaW50IHBhcnNlX251bShzaXplX3QgKm51bSwgY29uc3QgY2hhciAqdG9rZW4pCnsKCWNoYXIgKmVuZHA7CglzaXplX3QgbjsKCgluID0gKHNpemVfdCkgdXN0cnRvdWwodG9rZW4sICZlbmRwLCAwKTsKCWlmICgqZW5kcCkKCQlyZXR1cm4gLUVJTlZBTDsKCgkqbnVtID0gbjsKCXJldHVybiAwOwp9CgoKc3RhdGljIGludCBwYXJzZV9uYW1lKGNoYXIgKipwbmFtZSwgY29uc3QgY2hhciAqdG9rZW4sIHNpemVfdCBsaW1pdCkKewoJc2l6ZV90IGxlbjsKCWNoYXIgKm5hbWU7CgoJbGVuID0gc3RybGVuKHRva2VuKSArIDE7CglpZiAobGVuID4gbGltaXQpCgkJcmV0dXJuIC1FTk9TUEM7CgoJbmFtZSA9IGttYWxsb2MobGVuLCBHRlBfS0VSTkVMKTsKCWlmICghbmFtZSkKCQlyZXR1cm4gLUVOT01FTTsKCglzdHJjcHkobmFtZSwgdG9rZW4pOwoKCSpwbmFtZSA9IG5hbWU7CglyZXR1cm4gMDsKfQoKCnN0YXRpYyBpbmxpbmUgdm9pZCBraWxsX2ZpbmFsX25ld2xpbmUoY2hhciAqc3RyKQp7CgljaGFyICpuZXdsaW5lID0gc3RycmNocihzdHIsICdcbicpOwoJaWYgKG5ld2xpbmUgJiYgIW5ld2xpbmVbMV0pCgkJKm5ld2xpbmUgPSAwOwp9CgoKI2RlZmluZSBwYXJzZV9lcnIoZm10LCBhcmdzLi4uKSBkbyB7CQlcCglFUlJPUigiYmxvY2sybXRkOiAiIGZtdCAiXG4iLCAjIyBhcmdzKTsJXAoJcmV0dXJuIDA7CQkJCVwKfSB3aGlsZSAoMCkKCnN0YXRpYyBpbnQgYmxvY2sybXRkX3NldHVwKGNvbnN0IGNoYXIgKnZhbCwgc3RydWN0IGtlcm5lbF9wYXJhbSAqa3ApCnsKCWNoYXIgYnVmWzgwKzEyXSwgKnN0cj1idWY7IC8qIDgwIGZvciBkZXZpY2UsIDEyIGZvciBlcmFzZSBzaXplICovCgljaGFyICp0b2tlblsyXTsKCWNoYXIgKm5hbWU7CglzaXplX3QgZXJhc2Vfc2l6ZSA9IFBBR0VfU0laRTsKCWludCBpLCByZXQ7CgoJaWYgKHN0cm5sZW4odmFsLCBzaXplb2YoYnVmKSkgPj0gc2l6ZW9mKGJ1ZikpCgkJcGFyc2VfZXJyKCJwYXJhbWV0ZXIgdG9vIGxvbmciKTsKCglzdHJjcHkoc3RyLCB2YWwpOwoJa2lsbF9maW5hbF9uZXdsaW5lKHN0cik7CgoJZm9yIChpPTA7IGk8MjsgaSsrKQoJCXRva2VuW2ldID0gc3Ryc2VwKCZzdHIsICIsIik7CgoJaWYgKHN0cikKCQlwYXJzZV9lcnIoInRvbyBtYW55IGFyZ3VtZW50cyIpOwoKCWlmICghdG9rZW5bMF0pCgkJcGFyc2VfZXJyKCJubyBhcmd1bWVudCIpOwoKCXJldCA9IHBhcnNlX25hbWUoJm5hbWUsIHRva2VuWzBdLCA4MCk7CglpZiAocmV0ID09IC1FTk9NRU0pCgkJcGFyc2VfZXJyKCJvdXQgb2YgbWVtb3J5Iik7CglpZiAocmV0ID09IC1FTk9TUEMpCgkJcGFyc2VfZXJyKCJuYW1lIHRvbyBsb25nIik7CglpZiAocmV0KQoJCXJldHVybiAwOwoKCWlmICh0b2tlblsxXSkgewoJCXJldCA9IHBhcnNlX251bSgmZXJhc2Vfc2l6ZSwgdG9rZW5bMV0pOwoJCWlmIChyZXQpCgkJCXBhcnNlX2VycigiaWxsZWdhbCBlcmFzZSBzaXplIik7Cgl9CgoJYWRkX2RldmljZShuYW1lLCBlcmFzZV9zaXplKTsKCglyZXR1cm4gMDsKfQoKCm1vZHVsZV9wYXJhbV9jYWxsKGJsb2NrMm10ZCwgYmxvY2sybXRkX3NldHVwLCBOVUxMLCBOVUxMLCAwMjAwKTsKTU9EVUxFX1BBUk1fREVTQyhibG9jazJtdGQsICJEZXZpY2UgdG8gdXNlLiBcImJsb2NrMm10ZD08ZGV2PlssPGVyYXNlc2l6ZT5dXCIiKTsKCnN0YXRpYyBpbnQgX19pbml0IGJsb2NrMm10ZF9pbml0KHZvaWQpCnsKCUlORk8oInZlcnNpb24gIiBWRVJTSU9OKTsKCXJldHVybiAwOwp9CgoKc3RhdGljIHZvaWQgX19kZXZleGl0IGJsb2NrMm10ZF9leGl0KHZvaWQpCnsKCXN0cnVjdCBsaXN0X2hlYWQgKnBvcywgKm5leHQ7CgoJLyogUmVtb3ZlIHRoZSBNVEQgZGV2aWNlcyAqLwoJbGlzdF9mb3JfZWFjaF9zYWZlKHBvcywgbmV4dCwgJmJsa210ZF9kZXZpY2VfbGlzdCkgewoJCXN0cnVjdCBibG9jazJtdGRfZGV2ICpkZXYgPSBsaXN0X2VudHJ5KHBvcywgdHlwZW9mKCpkZXYpLCBsaXN0KTsKCQlibG9jazJtdGRfc3luYygmZGV2LT5tdGQpOwoJCWRlbF9tdGRfZGV2aWNlKCZkZXYtPm10ZCk7CgkJSU5GTygibXRkJWQ6IFslc10gcmVtb3ZlZCIsIGRldi0+bXRkLmluZGV4LAoJCQkJZGV2LT5tdGQubmFtZSArIHN0cmxlbigiYmxrbXRkOiAiKSk7CgkJbGlzdF9kZWwoJmRldi0+bGlzdCk7CgkJYmxvY2sybXRkX2ZyZWVfZGV2aWNlKGRldik7Cgl9Cn0KCgptb2R1bGVfaW5pdChibG9jazJtdGRfaW5pdCk7Cm1vZHVsZV9leGl0KGJsb2NrMm10ZF9leGl0KTsKCk1PRFVMRV9MSUNFTlNFKCJHUEwiKTsKTU9EVUxFX0FVVEhPUigiU2ltb24gRXZhbnMgPHNwc2VAc2VjcmV0Lm9yZy51az4gYW5kIG90aGVycyIpOwpNT0RVTEVfREVTQ1JJUFRJT04oIkVtdWxhdGUgYW4gTVREIHVzaW5nIGEgYmxvY2sgZGV2aWNlIik7Cg==