I2luY2x1ZGUgPHN0ZGludC5oPgojaW5jbHVkZSA8c3RyaW5nLmg+CiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0ZGlvLmg+CiNpbmNsdWRlIDxlcnJuby5oPgojaW5jbHVkZSA8aXB4ZS9pby5oPgojaW5jbHVkZSA8dW5pc3RkLmg+CiNpbmNsdWRlIDxpcHhlL2Vpc2EuaD4KCkZJTEVfTElDRU5DRSAoIEdQTDJfT1JfTEFURVIgKTsKCnN0YXRpYyB2b2lkIGVpc2FidXNfcmVtb3ZlICggc3RydWN0IHJvb3RfZGV2aWNlICpyb290ZGV2ICk7CgovKioKICogUmVzZXQgYW5kIGVuYWJsZS9kaXNhYmxlIGFuIEVJU0EgZGV2aWNlCiAqCiAqIEB2IGVpc2EJCUVJU0EgZGV2aWNlCiAqIEB2IGVuYWJsZWQJCTE9ZW5hYmxlLCAwPWRpc2FibGUKICovCnZvaWQgZWlzYV9kZXZpY2VfZW5hYmxlZCAoIHN0cnVjdCBlaXNhX2RldmljZSAqZWlzYSwgaW50IGVuYWJsZWQgKSB7CgkvKiBTZXQgcmVzZXQgbGluZSBoaWdoIGZvciAxMDAwILVzLiAgU3BlYyBzYXlzIDUwMCC1cywgYnV0CgkgKiB0aGlzIGRvZXNuJ3Qgd29yayBmb3IgYWxsIGNhcmRzLCBzbyB3ZSBhcmUgY29uc2VydmF0aXZlLgoJICovCglvdXRiICggRUlTQV9DTURfUkVTRVQsIGVpc2EtPmlvYWRkciArIEVJU0FfR0xPQkFMX0NPTkZJRyApOwoJdWRlbGF5ICggMTAwMCApOyAvKiBNdXN0IHdhaXQgODAwICovCgoJLyogU2V0IHJlc2V0IGxvdyBhbmQgd3JpdGUgYSAxIHRvIEVOQUJMRS4gIERlbGF5IGFnYWluLCBpbgoJICogY2FzZSB0aGUgY2FyZCB0YWtlcyBhIHdoaWxlIHRvIHdha2UgdXAuCgkgKi8KCW91dGIgKCBlbmFibGVkID8gRUlTQV9DTURfRU5BQkxFIDogMCwKCSAgICAgICBlaXNhLT5pb2FkZHIgKyBFSVNBX0dMT0JBTF9DT05GSUcgKTsKCXVkZWxheSAoIDEwMDAgKTsgLyogTXVzdCB3YWl0IDgwMCAqLwoKCURCRyAoICJFSVNBICVzIGRldmljZSAlMDJ4XG4iLCAoIGVuYWJsZWQgPyAiZW5hYmxlZCIgOiAiZGlzYWJsZWQiICksCgkgICAgICBlaXNhLT5zbG90ICk7Cn0KCi8qKgogKiBQcm9iZSBhbiBFSVNBIGRldmljZQogKgogKiBAdiBlaXNhCQlFSVNBIGRldmljZQogKiBAcmV0IHJjCQlSZXR1cm4gc3RhdHVzIGNvZGUKICoKICogU2VhcmNoZXMgZm9yIGEgZHJpdmVyIGZvciB0aGUgRUlTQSBkZXZpY2UuICBJZiBhIGRyaXZlciBpcyBmb3VuZCwKICogaXRzIHByb2JlKCkgcm91dGluZSBpcyBjYWxsZWQuCiAqLwpzdGF0aWMgaW50IGVpc2FfcHJvYmUgKCBzdHJ1Y3QgZWlzYV9kZXZpY2UgKmVpc2EgKSB7CglzdHJ1Y3QgZWlzYV9kcml2ZXIgKmRyaXZlcjsKCXN0cnVjdCBlaXNhX2RldmljZV9pZCAqaWQ7Cgl1bnNpZ25lZCBpbnQgaTsKCWludCByYzsKCglEQkcgKCAiQWRkaW5nIEVJU0EgZGV2aWNlICUwMnggKCUwNHg6JTA0eCAoXCIlc1wiKSBpbyAleClcbiIsCgkgICAgICBlaXNhLT5zbG90LCBlaXNhLT52ZW5kb3JfaWQsIGVpc2EtPnByb2RfaWQsCgkgICAgICBpc2FfaWRfc3RyaW5nICggZWlzYS0+dmVuZG9yX2lkLCBlaXNhLT5wcm9kX2lkICksIGVpc2EtPmlvYWRkciApOwoKCWZvcl9lYWNoX3RhYmxlX2VudHJ5ICggZHJpdmVyLCBFSVNBX0RSSVZFUlMgKSB7CgkJZm9yICggaSA9IDAgOyBpIDwgZHJpdmVyLT5pZF9jb3VudCA7IGkrKyApIHsKCQkJaWQgPSAmZHJpdmVyLT5pZHNbaV07CgkJCWlmICggaWQtPnZlbmRvcl9pZCAhPSBlaXNhLT52ZW5kb3JfaWQgKQoJCQkJY29udGludWU7CgkJCWlmICggSVNBX1BST0RfSUQgKCBpZC0+cHJvZF9pZCApICE9CgkJCSAgICAgSVNBX1BST0RfSUQgKCBlaXNhLT5wcm9kX2lkICkgKQoJCQkJY29udGludWU7CgkJCWVpc2EtPmRyaXZlciA9IGRyaXZlcjsKCQkJZWlzYS0+ZGV2LmRyaXZlcl9uYW1lID0gaWQtPm5hbWU7CgkJCURCRyAoICIuLi51c2luZyBkcml2ZXIgJXNcbiIsIGVpc2EtPmRldi5kcml2ZXJfbmFtZSApOwoJCQlpZiAoICggcmMgPSBkcml2ZXItPnByb2JlICggZWlzYSwgaWQgKSApICE9IDAgKSB7CgkJCQlEQkcgKCAiLi4uLi4ucHJvYmUgZmFpbGVkXG4iICk7CgkJCQljb250aW51ZTsKCQkJfQoJCQlyZXR1cm4gMDsKCQl9Cgl9CgoJREJHICggIi4uLm5vIGRyaXZlciBmb3VuZFxuIiApOwoJcmV0dXJuIC1FTk9UVFk7Cn0KCi8qKgogKiBSZW1vdmUgYW4gRUlTQSBkZXZpY2UKICoKICogQHYgZWlzYQkJRUlTQSBkZXZpY2UKICovCnN0YXRpYyB2b2lkIGVpc2FfcmVtb3ZlICggc3RydWN0IGVpc2FfZGV2aWNlICplaXNhICkgewoJZWlzYS0+ZHJpdmVyLT5yZW1vdmUgKCBlaXNhICk7CglEQkcgKCAiUmVtb3ZlZCBFSVNBIGRldmljZSAlMDJ4XG4iLCBlaXNhLT5zbG90ICk7Cn0KCi8qKgogKiBQcm9iZSBFSVNBIHJvb3QgYnVzCiAqCiAqIEB2IHJvb3RkZXYJCUVJU0EgYnVzIHJvb3QgZGV2aWNlCiAqCiAqIFNjYW5zIHRoZSBFSVNBIGJ1cyBmb3IgZGV2aWNlcyBhbmQgcmVnaXN0ZXJzIGFsbCBkZXZpY2VzIGl0IGNhbgogKiBmaW5kLgogKi8Kc3RhdGljIGludCBlaXNhYnVzX3Byb2JlICggc3RydWN0IHJvb3RfZGV2aWNlICpyb290ZGV2ICkgewoJc3RydWN0IGVpc2FfZGV2aWNlICplaXNhID0gTlVMTDsKCXVuc2lnbmVkIGludCBzbG90OwoJdWludDhfdCBzeXN0ZW07CglpbnQgcmM7CgoJLyogQ2hlY2sgZm9yIEVJU0Egc3lzdGVtIGJvYXJkICovCglzeXN0ZW0gPSBpbmIgKCBFSVNBX1ZFTkRPUl9JRCApOwoJaWYgKCBzeXN0ZW0gJiAweDgwICkgewoJCURCRyAoICJObyBFSVNBIHN5c3RlbSBib2FyZCAocmVhZCAlMDJ4KVxuIiwgc3lzdGVtICk7CgkJcmV0dXJuIC1FTk9ERVY7Cgl9CgoJZm9yICggc2xvdCA9IEVJU0FfTUlOX1NMT1QgOyBzbG90IDw9IEVJU0FfTUFYX1NMT1QgOyBzbG90KysgKSB7CgkJLyogQWxsb2NhdGUgc3RydWN0IGVpc2FfZGV2aWNlICovCgkJaWYgKCAhIGVpc2EgKQoJCQllaXNhID0gbWFsbG9jICggc2l6ZW9mICggKmVpc2EgKSApOwoJCWlmICggISBlaXNhICkgewoJCQlyYyA9IC1FTk9NRU07CgkJCWdvdG8gZXJyOwoJCX0KCQltZW1zZXQgKCBlaXNhLCAwLCBzaXplb2YgKCAqZWlzYSApICk7CgkJZWlzYS0+c2xvdCA9IHNsb3Q7CgkJZWlzYS0+aW9hZGRyID0gRUlTQV9TTE9UX0JBU0UgKCBlaXNhLT5zbG90ICk7CgoJCS8qIFRlc3QgZm9yIGJvYXJkIHByZXNlbnQgKi8KCQlvdXRiICggMHhmZiwgZWlzYS0+aW9hZGRyICsgRUlTQV9WRU5ET1JfSUQgKTsKCQllaXNhLT52ZW5kb3JfaWQgPQoJCQlsZTE2X3RvX2NwdSAoIGludyAoIGVpc2EtPmlvYWRkciArIEVJU0FfVkVORE9SX0lEICkgKTsKCQllaXNhLT5wcm9kX2lkID0KCQkJbGUxNl90b19jcHUgKCBpbncgKCBlaXNhLT5pb2FkZHIgKyBFSVNBX1BST0RfSUQgKSApOwoJCWlmICggZWlzYS0+dmVuZG9yX2lkICYgMHg4MCApIHsKCQkJLyogTm8gYm9hcmQgcHJlc2VudCAqLwoJCQljb250aW51ZTsKCQl9CgoJCS8qIEFkZCB0byBkZXZpY2UgaGllcmFyY2h5ICovCgkJc25wcmludGYgKCBlaXNhLT5kZXYubmFtZSwgc2l6ZW9mICggZWlzYS0+ZGV2Lm5hbWUgKSwKCQkJICAgIkVJU0ElMDJ4Iiwgc2xvdCApOwoJCWVpc2EtPmRldi5kZXNjLmJ1c190eXBlID0gQlVTX1RZUEVfRUlTQTsKCQllaXNhLT5kZXYuZGVzYy52ZW5kb3IgPSBlaXNhLT52ZW5kb3JfaWQ7CgkJZWlzYS0+ZGV2LmRlc2MuZGV2aWNlID0gZWlzYS0+cHJvZF9pZDsKCQllaXNhLT5kZXYucGFyZW50ID0gJnJvb3RkZXYtPmRldjsKCQlsaXN0X2FkZCAoICZlaXNhLT5kZXYuc2libGluZ3MsICZyb290ZGV2LT5kZXYuY2hpbGRyZW4gKTsKCQlJTklUX0xJU1RfSEVBRCAoICZlaXNhLT5kZXYuY2hpbGRyZW4gKTsKCgkJLyogTG9vayBmb3IgYSBkcml2ZXIgKi8KCQlpZiAoIGVpc2FfcHJvYmUgKCBlaXNhICkgPT0gMCApIHsKCQkJLyogZWlzYWRldiByZWdpc3RlcmVkLCB3ZSBjYW4gZHJvcCBvdXIgcmVmICovCgkJCWVpc2EgPSBOVUxMOwoJCX0gZWxzZSB7CgkJCS8qIE5vdCByZWdpc3RlcmVkOyByZS11c2Ugc3RydWN0ICovCgkJCWxpc3RfZGVsICggJmVpc2EtPmRldi5zaWJsaW5ncyApOwoJCX0KCX0KCglmcmVlICggZWlzYSApOwoJcmV0dXJuIDA7CgogZXJyOgoJZnJlZSAoIGVpc2EgKTsKCWVpc2FidXNfcmVtb3ZlICggcm9vdGRldiApOwoJcmV0dXJuIHJjOwp9CgovKioKICogUmVtb3ZlIEVJU0Egcm9vdCBidXMKICoKICogQHYgcm9vdGRldgkJRUlTQSBidXMgcm9vdCBkZXZpY2UKICovCnN0YXRpYyB2b2lkIGVpc2FidXNfcmVtb3ZlICggc3RydWN0IHJvb3RfZGV2aWNlICpyb290ZGV2ICkgewoJc3RydWN0IGVpc2FfZGV2aWNlICplaXNhOwoJc3RydWN0IGVpc2FfZGV2aWNlICp0bXA7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeV9zYWZlICggZWlzYSwgdG1wLCAmcm9vdGRldi0+ZGV2LmNoaWxkcmVuLAoJCQkJICAgZGV2LnNpYmxpbmdzICkgewoJCWVpc2FfcmVtb3ZlICggZWlzYSApOwoJCWxpc3RfZGVsICggJmVpc2EtPmRldi5zaWJsaW5ncyApOwoJCWZyZWUgKCBlaXNhICk7Cgl9Cn0KCi8qKiBFSVNBIGJ1cyByb290IGRldmljZSBkcml2ZXIgKi8Kc3RhdGljIHN0cnVjdCByb290X2RyaXZlciBlaXNhX3Jvb3RfZHJpdmVyID0gewoJLnByb2JlID0gZWlzYWJ1c19wcm9iZSwKCS5yZW1vdmUgPSBlaXNhYnVzX3JlbW92ZSwKfTsKCi8qKiBFSVNBIGJ1cyByb290IGRldmljZSAqLwpzdHJ1Y3Qgcm9vdF9kZXZpY2UgZWlzYV9yb290X2RldmljZSBfX3Jvb3RfZGV2aWNlID0gewoJLmRldiA9IHsgLm5hbWUgPSAiRUlTQSIgfSwKCS5kcml2ZXIgPSAmZWlzYV9yb290X2RyaXZlciwKfTsK