LyoKICogIGxpbnV4L2ZzL3N1cGVyLmMKICoKICogIENvcHlyaWdodCAoQykgMTk5MSwgMTk5MiAgTGludXMgVG9ydmFsZHMKICoKICogIHN1cGVyLmMgY29udGFpbnMgY29kZSB0byBoYW5kbGU6IC0gbW91bnQgc3RydWN0dXJlcwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBzdXBlci1ibG9jayB0YWJsZXMKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gZmlsZXN5c3RlbSBkcml2ZXJzIGxpc3QKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gbW91bnQgc3lzdGVtIGNhbGwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gdW1vdW50IHN5c3RlbSBjYWxsCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIHVzdGF0IHN5c3RlbSBjYWxsCiAqCiAqIEdLIDIvNS85NSAgLSAgQ2hhbmdlZCB0byBzdXBwb3J0IG1vdW50aW5nIHRoZSByb290IGZzIHZpYSBORlMKICoKICogIEFkZGVkIGtlcm5lbGQgc3VwcG9ydDogSmFjcXVlcyBHZWxpbmFzIGFuZCBCam9ybiBFa3dhbGwKICogIEFkZGVkIGNoYW5nZV9yb290OiBXZXJuZXIgQWxtZXNiZXJnZXIgJiBIYW5zIExlcm1lbiwgRmViICc5NgogKiAgQWRkZWQgb3B0aW9ucyB0byAvcHJvYy9tb3VudHM6CiAqICAgIFRvcmJq9nJuIExpbmRoICh0b3Jiam9ybi5saW5kaEBnb3B0YS5zZSksIEFwcmlsIDE0LCAxOTk2LgogKiAgQWRkZWQgZGV2ZnMgc3VwcG9ydDogUmljaGFyZCBHb29jaCA8cmdvb2NoQGF0bmYuY3Npcm8uYXU+LCAxMy1KQU4tMTk5OAogKiAgSGVhdmlseSByZXdyaXR0ZW4gZm9yICdvbmUgZnMgLSBvbmUgdHJlZScgZGNhY2hlIGFyY2hpdGVjdHVyZS4gQVYsIE1hciAyMDAwCiAqLwoKI2luY2x1ZGUgPGxpbnV4L2NvbmZpZy5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9zbXBfbG9jay5oPgojaW5jbHVkZSA8bGludXgvYWNjdC5oPgojaW5jbHVkZSA8bGludXgvYmxrZGV2Lmg+CiNpbmNsdWRlIDxsaW51eC9xdW90YW9wcy5oPgojaW5jbHVkZSA8bGludXgvbmFtZWkuaD4KI2luY2x1ZGUgPGxpbnV4L2J1ZmZlcl9oZWFkLmg+CQkvKiBmb3IgZnN5bmNfc3VwZXIoKSAqLwojaW5jbHVkZSA8bGludXgvbW91bnQuaD4KI2luY2x1ZGUgPGxpbnV4L3NlY3VyaXR5Lmg+CiNpbmNsdWRlIDxsaW51eC9zeXNjYWxscy5oPgojaW5jbHVkZSA8bGludXgvdmZzLmg+CiNpbmNsdWRlIDxsaW51eC93cml0ZWJhY2suaD4JCS8qIGZvciB0aGUgZW1lcmdlbmN5IHJlbW91bnQgc3R1ZmYgKi8KI2luY2x1ZGUgPGxpbnV4L2lkci5oPgojaW5jbHVkZSA8bGludXgva29iamVjdC5oPgojaW5jbHVkZSA8YXNtL3VhY2Nlc3MuaD4KCgp2b2lkIGdldF9maWxlc3lzdGVtKHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmcyk7CnZvaWQgcHV0X2ZpbGVzeXN0ZW0oc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzKTsKc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmdldF9mc190eXBlKGNvbnN0IGNoYXIgKm5hbWUpOwoKTElTVF9IRUFEKHN1cGVyX2Jsb2Nrcyk7CkRFRklORV9TUElOTE9DSyhzYl9sb2NrKTsKCi8qKgogKglhbGxvY19zdXBlcgktCWNyZWF0ZSBuZXcgc3VwZXJibG9jawogKgogKglBbGxvY2F0ZXMgYW5kIGluaXRpYWxpemVzIGEgbmV3ICZzdHJ1Y3Qgc3VwZXJfYmxvY2suICBhbGxvY19zdXBlcigpCiAqCXJldHVybnMgYSBwb2ludGVyIG5ldyBzdXBlcmJsb2NrIG9yICVOVUxMIGlmIGFsbG9jYXRpb24gaGFkIGZhaWxlZC4KICovCnN0YXRpYyBzdHJ1Y3Qgc3VwZXJfYmxvY2sgKmFsbG9jX3N1cGVyKHZvaWQpCnsKCXN0cnVjdCBzdXBlcl9ibG9jayAqcyA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBzdXBlcl9ibG9jayksICBHRlBfVVNFUik7CglzdGF0aWMgc3RydWN0IHN1cGVyX29wZXJhdGlvbnMgZGVmYXVsdF9vcDsKCglpZiAocykgewoJCW1lbXNldChzLCAwLCBzaXplb2Yoc3RydWN0IHN1cGVyX2Jsb2NrKSk7CgkJaWYgKHNlY3VyaXR5X3NiX2FsbG9jKHMpKSB7CgkJCWtmcmVlKHMpOwoJCQlzID0gTlVMTDsKCQkJZ290byBvdXQ7CgkJfQoJCUlOSVRfTElTVF9IRUFEKCZzLT5zX2RpcnR5KTsKCQlJTklUX0xJU1RfSEVBRCgmcy0+c19pbyk7CgkJSU5JVF9MSVNUX0hFQUQoJnMtPnNfZmlsZXMpOwoJCUlOSVRfTElTVF9IRUFEKCZzLT5zX2luc3RhbmNlcyk7CgkJSU5JVF9ITElTVF9IRUFEKCZzLT5zX2Fub24pOwoJCUlOSVRfTElTVF9IRUFEKCZzLT5zX2lub2Rlcyk7CgkJaW5pdF9yd3NlbSgmcy0+c191bW91bnQpOwoJCXNlbWFfaW5pdCgmcy0+c19sb2NrLCAxKTsKCQlkb3duX3dyaXRlKCZzLT5zX3Vtb3VudCk7CgkJcy0+c19jb3VudCA9IFNfQklBUzsKCQlhdG9taWNfc2V0KCZzLT5zX2FjdGl2ZSwgMSk7CgkJc2VtYV9pbml0KCZzLT5zX3Zmc19yZW5hbWVfc2VtLDEpOwoJCXNlbWFfaW5pdCgmcy0+c19kcXVvdC5kcWlvX3NlbSwgMSk7CgkJc2VtYV9pbml0KCZzLT5zX2RxdW90LmRxb25vZmZfc2VtLCAxKTsKCQlpbml0X3J3c2VtKCZzLT5zX2RxdW90LmRxcHRyX3NlbSk7CgkJaW5pdF93YWl0cXVldWVfaGVhZCgmcy0+c193YWl0X3VuZnJvemVuKTsKCQlzLT5zX21heGJ5dGVzID0gTUFYX05PTl9MRlM7CgkJcy0+ZHFfb3AgPSBzYl9kcXVvdF9vcHM7CgkJcy0+c19xY29wID0gc2JfcXVvdGFjdGxfb3BzOwoJCXMtPnNfb3AgPSAmZGVmYXVsdF9vcDsKCQlzLT5zX3RpbWVfZ3JhbiA9IDEwMDAwMDAwMDA7Cgl9Cm91dDoKCXJldHVybiBzOwp9CgovKioKICoJZGVzdHJveV9zdXBlcgktCWZyZWVzIGEgc3VwZXJibG9jawogKglAczogc3VwZXJibG9jayB0byBmcmVlCiAqCiAqCUZyZWVzIGEgc3VwZXJibG9jay4KICovCnN0YXRpYyBpbmxpbmUgdm9pZCBkZXN0cm95X3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqcykKewoJc2VjdXJpdHlfc2JfZnJlZShzKTsKCWtmcmVlKHMpOwp9CgovKiBTdXBlcmJsb2NrIHJlZmNvdW50aW5nICAqLwoKLyoKICogRHJvcCBhIHN1cGVyYmxvY2sncyByZWZjb3VudC4gIFJldHVybnMgbm9uLXplcm8gaWYgdGhlIHN1cGVyYmxvY2sgd2FzCiAqIGRlc3Ryb3llZC4gIFRoZSBjYWxsZXIgbXVzdCBob2xkIHNiX2xvY2suCiAqLwppbnQgX19wdXRfc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJaW50IHJldCA9IDA7CgoJaWYgKCEtLXNiLT5zX2NvdW50KSB7CgkJZGVzdHJveV9zdXBlcihzYik7CgkJcmV0ID0gMTsKCX0KCXJldHVybiByZXQ7Cn0KCi8qCiAqIERyb3AgYSBzdXBlcmJsb2NrJ3MgcmVmY291bnQuCiAqIFJldHVybnMgbm9uLXplcm8gaWYgdGhlIHN1cGVyYmxvY2sgaXMgYWJvdXQgdG8gYmUgZGVzdHJveWVkIGFuZAogKiBhdCBsZWFzdCBpcyBhbHJlYWR5IHJlbW92ZWQgZnJvbSBzdXBlcl9ibG9ja3MgbGlzdCwgc28gaWYgd2UgYXJlCiAqIG1ha2luZyBhIGxvb3AgdGhyb3VnaCBzdXBlciBibG9ja3MgdGhlbiB3ZSBuZWVkIHRvIHJlc3RhcnQuCiAqIFRoZSBjYWxsZXIgbXVzdCBob2xkIHNiX2xvY2suCiAqLwppbnQgX19wdXRfc3VwZXJfYW5kX25lZWRfcmVzdGFydChzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiKQp7CgkvKiBjaGVjayBmb3IgcmFjZSB3aXRoIGdlbmVyaWNfc2h1dGRvd25fc3VwZXIoKSAqLwoJaWYgKGxpc3RfZW1wdHkoJnNiLT5zX2xpc3QpKSB7CgkJLyogc3VwZXIgYmxvY2sgaXMgcmVtb3ZlZCwgbmVlZCB0byByZXN0YXJ0Li4uICovCgkJX19wdXRfc3VwZXIoc2IpOwoJCXJldHVybiAxOwoJfQoJLyogY2FuJ3QgYmUgdGhlIGxhc3QsIHNpbmNlIHNfbGlzdCBpcyBzdGlsbCBpbiB1c2UgKi8KCXNiLT5zX2NvdW50LS07CglCVUdfT04oc2ItPnNfY291bnQgPT0gMCk7CglyZXR1cm4gMDsKfQoKLyoqCiAqCXB1dF9zdXBlcgktCWRyb3AgYSB0ZW1wb3JhcnkgcmVmZXJlbmNlIHRvIHN1cGVyYmxvY2sKICoJQHNiOiBzdXBlcmJsb2NrIGluIHF1ZXN0aW9uCiAqCiAqCURyb3BzIGEgdGVtcG9yYXJ5IHJlZmVyZW5jZSwgZnJlZXMgc3VwZXJibG9jayBpZiB0aGVyZSdzIG5vCiAqCXJlZmVyZW5jZXMgbGVmdC4KICovCnN0YXRpYyB2b2lkIHB1dF9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiKQp7CglzcGluX2xvY2soJnNiX2xvY2spOwoJX19wdXRfc3VwZXIoc2IpOwoJc3Bpbl91bmxvY2soJnNiX2xvY2spOwp9CgoKLyoqCiAqCWRlYWN0aXZhdGVfc3VwZXIJLQlkcm9wIGFuIGFjdGl2ZSByZWZlcmVuY2UgdG8gc3VwZXJibG9jawogKglAczogc3VwZXJibG9jayB0byBkZWFjdGl2YXRlCiAqCiAqCURyb3BzIGFuIGFjdGl2ZSByZWZlcmVuY2UgdG8gc3VwZXJibG9jaywgYWNxdWlyaW5nIGEgdGVtcHJvcnkgb25lIGlmCiAqCXRoZXJlIGlzIG5vIGFjdGl2ZSByZWZlcmVuY2VzIGxlZnQuICBJbiB0aGF0IGNhc2Ugd2UgbG9jayBzdXBlcmJsb2NrLAogKgl0ZWxsIGZzIGRyaXZlciB0byBzaHV0IGl0IGRvd24gYW5kIGRyb3AgdGhlIHRlbXBvcmFyeSByZWZlcmVuY2Ugd2UKICoJaGFkIGp1c3QgYWNxdWlyZWQuCiAqLwp2b2lkIGRlYWN0aXZhdGVfc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzKQp7CglzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSAqZnMgPSBzLT5zX3R5cGU7CglpZiAoYXRvbWljX2RlY19hbmRfbG9jaygmcy0+c19hY3RpdmUsICZzYl9sb2NrKSkgewoJCXMtPnNfY291bnQgLT0gU19CSUFTLTE7CgkJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJCWRvd25fd3JpdGUoJnMtPnNfdW1vdW50KTsKCQlmcy0+a2lsbF9zYihzKTsKCQlwdXRfZmlsZXN5c3RlbShmcyk7CgkJcHV0X3N1cGVyKHMpOwoJfQp9CgpFWFBPUlRfU1lNQk9MKGRlYWN0aXZhdGVfc3VwZXIpOwoKLyoqCiAqCWdyYWJfc3VwZXIgLSBhY3F1aXJlIGFuIGFjdGl2ZSByZWZlcmVuY2UKICoJQHM6IHJlZmVyZW5jZSB3ZSBhcmUgdHJ5aW5nIHRvIG1ha2UgYWN0aXZlCiAqCiAqCVRyaWVzIHRvIGFjcXVpcmUgYW4gYWN0aXZlIHJlZmVyZW5jZS4gIGdyYWJfc3VwZXIoKSBpcyB1c2VkIHdoZW4gd2UKICogCWhhZCBqdXN0IGZvdW5kIGEgc3VwZXJibG9jayBpbiBzdXBlcl9ibG9ja3Mgb3IgZnNfdHlwZS0+ZnNfc3VwZXJzCiAqCWFuZCB3YW50IHRvIHR1cm4gaXQgaW50byBhIGZ1bGwtYmxvd24gYWN0aXZlIHJlZmVyZW5jZS4gIGdyYWJfc3VwZXIoKQogKglpcyBjYWxsZWQgd2l0aCBzYl9sb2NrIGhlbGQgYW5kIGRyb3BzIGl0LiAgUmV0dXJucyAxIGluIGNhc2Ugb2YKICoJc3VjY2VzcywgMCBpZiB3ZSBoYWQgZmFpbGVkIChzdXBlcmJsb2NrIGNvbnRlbnRzIHdhcyBhbHJlYWR5IGRlYWQgb3IKICoJZHlpbmcgd2hlbiBncmFiX3N1cGVyKCkgaGFkIGJlZW4gY2FsbGVkKS4KICovCnN0YXRpYyBpbnQgZ3JhYl9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnMpCnsKCXMtPnNfY291bnQrKzsKCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCWRvd25fd3JpdGUoJnMtPnNfdW1vdW50KTsKCWlmIChzLT5zX3Jvb3QpIHsKCQlzcGluX2xvY2soJnNiX2xvY2spOwoJCWlmIChzLT5zX2NvdW50ID4gU19CSUFTKSB7CgkJCWF0b21pY19pbmMoJnMtPnNfYWN0aXZlKTsKCQkJcy0+c19jb3VudC0tOwoJCQlzcGluX3VubG9jaygmc2JfbG9jayk7CgkJCXJldHVybiAxOwoJCX0KCQlzcGluX3VubG9jaygmc2JfbG9jayk7Cgl9Cgl1cF93cml0ZSgmcy0+c191bW91bnQpOwoJcHV0X3N1cGVyKHMpOwoJeWllbGQoKTsKCXJldHVybiAwOwp9CgovKioKICoJZ2VuZXJpY19zaHV0ZG93bl9zdXBlcgktCWNvbW1vbiBoZWxwZXIgZm9yIC0+a2lsbF9zYigpCiAqCUBzYjogc3VwZXJibG9jayB0byBraWxsCiAqCiAqCWdlbmVyaWNfc2h1dGRvd25fc3VwZXIoKSBkb2VzIGFsbCBmcy1pbmRlcGVuZGVudCB3b3JrIG9uIHN1cGVyYmxvY2sKICoJc2h1dGRvd24uICBUeXBpY2FsIC0+a2lsbF9zYigpIHNob3VsZCBwaWNrIGFsbCBmcy1zcGVjaWZpYyBvYmplY3RzCiAqCXRoYXQgbmVlZCBkZXN0cnVjdGlvbiBvdXQgb2Ygc3VwZXJibG9jaywgY2FsbCBnZW5lcmljX3NodXRkb3duX3N1cGVyKCkKICoJYW5kIHJlbGVhc2UgYWZvcmVtZW50aW9uZWQgb2JqZWN0cy4gIE5vdGU6IGRlbnRyaWVzIGFuZCBpbm9kZXMgX2FyZV8KICoJdGFrZW4gY2FyZSBvZiBhbmQgZG8gbm90IG5lZWQgc3BlY2lmaWMgaGFuZGxpbmcuCiAqLwp2b2lkIGdlbmVyaWNfc2h1dGRvd25fc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJc3RydWN0IGRlbnRyeSAqcm9vdCA9IHNiLT5zX3Jvb3Q7CglzdHJ1Y3Qgc3VwZXJfb3BlcmF0aW9ucyAqc29wID0gc2ItPnNfb3A7CgoJaWYgKHJvb3QpIHsKCQlzYi0+c19yb290ID0gTlVMTDsKCQlzaHJpbmtfZGNhY2hlX3BhcmVudChyb290KTsKCQlzaHJpbmtfZGNhY2hlX2Fub24oJnNiLT5zX2Fub24pOwoJCWRwdXQocm9vdCk7CgkJZnN5bmNfc3VwZXIoc2IpOwoJCWxvY2tfc3VwZXIoc2IpOwoJCXNiLT5zX2ZsYWdzICY9IH5NU19BQ1RJVkU7CgkJLyogYmFkIG5hbWUgLSBpdCBzaG91bGQgYmUgZXZpY3RfaW5vZGVzKCkgKi8KCQlpbnZhbGlkYXRlX2lub2RlcyhzYik7CgkJbG9ja19rZXJuZWwoKTsKCgkJaWYgKHNvcC0+d3JpdGVfc3VwZXIgJiYgc2ItPnNfZGlydCkKCQkJc29wLT53cml0ZV9zdXBlcihzYik7CgkJaWYgKHNvcC0+cHV0X3N1cGVyKQoJCQlzb3AtPnB1dF9zdXBlcihzYik7CgoJCS8qIEZvcmdldCBhbnkgcmVtYWluaW5nIGlub2RlcyAqLwoJCWlmIChpbnZhbGlkYXRlX2lub2RlcyhzYikpIHsKCQkJcHJpbnRrKCJWRlM6IEJ1c3kgaW5vZGVzIGFmdGVyIHVubW91bnQuICIKCQkJICAgIlNlbGYtZGVzdHJ1Y3QgaW4gNSBzZWNvbmRzLiAgSGF2ZSBhIG5pY2UgZGF5Li4uXG4iKTsKCQl9CgoJCXVubG9ja19rZXJuZWwoKTsKCQl1bmxvY2tfc3VwZXIoc2IpOwoJfQoJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCS8qIHNob3VsZCBiZSBpbml0aWFsaXplZCBmb3IgX19wdXRfc3VwZXJfYW5kX25lZWRfcmVzdGFydCgpICovCglsaXN0X2RlbF9pbml0KCZzYi0+c19saXN0KTsKCWxpc3RfZGVsKCZzYi0+c19pbnN0YW5jZXMpOwoJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJdXBfd3JpdGUoJnNiLT5zX3Vtb3VudCk7Cn0KCkVYUE9SVF9TWU1CT0woZ2VuZXJpY19zaHV0ZG93bl9zdXBlcik7CgovKioKICoJc2dldAktCWZpbmQgb3IgY3JlYXRlIGEgc3VwZXJibG9jawogKglAdHlwZToJZmlsZXN5c3RlbSB0eXBlIHN1cGVyYmxvY2sgc2hvdWxkIGJlbG9uZyB0bwogKglAdGVzdDoJY29tcGFyaXNvbiBjYWxsYmFjawogKglAc2V0OglzZXR1cCBjYWxsYmFjawogKglAZGF0YToJYXJndW1lbnQgdG8gZWFjaCBvZiB0aGVtCiAqLwpzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNnZXQoc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKnR5cGUsCgkJCWludCAoKnRlc3QpKHN0cnVjdCBzdXBlcl9ibG9jayAqLHZvaWQgKiksCgkJCWludCAoKnNldCkoc3RydWN0IHN1cGVyX2Jsb2NrICosdm9pZCAqKSwKCQkJdm9pZCAqZGF0YSkKewoJc3RydWN0IHN1cGVyX2Jsb2NrICpzID0gTlVMTDsKCXN0cnVjdCBsaXN0X2hlYWQgKnA7CglpbnQgZXJyOwoKcmV0cnk6CglzcGluX2xvY2soJnNiX2xvY2spOwoJaWYgKHRlc3QpIGxpc3RfZm9yX2VhY2gocCwgJnR5cGUtPmZzX3N1cGVycykgewoJCXN0cnVjdCBzdXBlcl9ibG9jayAqb2xkOwoJCW9sZCA9IGxpc3RfZW50cnkocCwgc3RydWN0IHN1cGVyX2Jsb2NrLCBzX2luc3RhbmNlcyk7CgkJaWYgKCF0ZXN0KG9sZCwgZGF0YSkpCgkJCWNvbnRpbnVlOwoJCWlmICghZ3JhYl9zdXBlcihvbGQpKQoJCQlnb3RvIHJldHJ5OwoJCWlmIChzKQoJCQlkZXN0cm95X3N1cGVyKHMpOwoJCXJldHVybiBvbGQ7Cgl9CglpZiAoIXMpIHsKCQlzcGluX3VubG9jaygmc2JfbG9jayk7CgkJcyA9IGFsbG9jX3N1cGVyKCk7CgkJaWYgKCFzKQoJCQlyZXR1cm4gRVJSX1BUUigtRU5PTUVNKTsKCQlnb3RvIHJldHJ5OwoJfQoJCQoJZXJyID0gc2V0KHMsIGRhdGEpOwoJaWYgKGVycikgewoJCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCQlkZXN0cm95X3N1cGVyKHMpOwoJCXJldHVybiBFUlJfUFRSKGVycik7Cgl9CglzLT5zX3R5cGUgPSB0eXBlOwoJc3RybGNweShzLT5zX2lkLCB0eXBlLT5uYW1lLCBzaXplb2Yocy0+c19pZCkpOwoJbGlzdF9hZGRfdGFpbCgmcy0+c19saXN0LCAmc3VwZXJfYmxvY2tzKTsKCWxpc3RfYWRkKCZzLT5zX2luc3RhbmNlcywgJnR5cGUtPmZzX3N1cGVycyk7CglzcGluX3VubG9jaygmc2JfbG9jayk7CglnZXRfZmlsZXN5c3RlbSh0eXBlKTsKCXJldHVybiBzOwp9CgpFWFBPUlRfU1lNQk9MKHNnZXQpOwoKdm9pZCBkcm9wX3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IpCnsKCXVwX3JlYWQoJnNiLT5zX3Vtb3VudCk7CglwdXRfc3VwZXIoc2IpOwp9CgpFWFBPUlRfU1lNQk9MKGRyb3Bfc3VwZXIpOwoKc3RhdGljIGlubGluZSB2b2lkIHdyaXRlX3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IpCnsKCWxvY2tfc3VwZXIoc2IpOwoJaWYgKHNiLT5zX3Jvb3QgJiYgc2ItPnNfZGlydCkKCQlpZiAoc2ItPnNfb3AtPndyaXRlX3N1cGVyKQoJCQlzYi0+c19vcC0+d3JpdGVfc3VwZXIoc2IpOwoJdW5sb2NrX3N1cGVyKHNiKTsKfQoKLyoKICogTm90ZTogY2hlY2sgdGhlIGRpcnR5IGZsYWcgYmVmb3JlIHdhaXRpbmcsIHNvIHdlIGRvbid0CiAqIGhvbGQgdXAgdGhlIHN5bmMgd2hpbGUgbW91bnRpbmcgYSBkZXZpY2UuIChUaGUgbmV3bHkKICogbW91bnRlZCBkZXZpY2Ugd29uJ3QgbmVlZCBzeW5jaW5nLikKICovCnZvaWQgc3luY19zdXBlcnModm9pZCkKewoJc3RydWN0IHN1cGVyX2Jsb2NrICpzYjsKCglzcGluX2xvY2soJnNiX2xvY2spOwpyZXN0YXJ0OgoJbGlzdF9mb3JfZWFjaF9lbnRyeShzYiwgJnN1cGVyX2Jsb2Nrcywgc19saXN0KSB7CgkJaWYgKHNiLT5zX2RpcnQpIHsKCQkJc2ItPnNfY291bnQrKzsKCQkJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJCQlkb3duX3JlYWQoJnNiLT5zX3Vtb3VudCk7CgkJCXdyaXRlX3N1cGVyKHNiKTsKCQkJdXBfcmVhZCgmc2ItPnNfdW1vdW50KTsKCQkJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCQkJaWYgKF9fcHV0X3N1cGVyX2FuZF9uZWVkX3Jlc3RhcnQoc2IpKQoJCQkJZ290byByZXN0YXJ0OwoJCX0KCX0KCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKfQoKLyoKICogQ2FsbCB0aGUgLT5zeW5jX2ZzIHN1cGVyX29wIGFnYWluc3QgYWxsIGZpbGVzeXRlbXMgd2hpY2ggYXJlIHIvdyBhbmQKICogd2hpY2ggaW1wbGVtZW50IGl0LgogKgogKiBUaGlzIG9wZXJhdGlvbiBpcyBjYXJlZnVsIHRvIGF2b2lkIHRoZSBsaXZlbG9jayB3aGljaCBjb3VsZCBlYXNpbHkgaGFwcGVuCiAqIGlmIHR3byBvciBtb3JlIGZpbGVzeXN0ZW1zIGFyZSBiZWluZyBjb250aW51b3VzbHkgZGlydGllZC4gIHNfbmVlZF9zeW5jX2ZzCiAqIGlzIHVzZWQgb25seSBoZXJlLiAgV2Ugc2V0IGl0IGFnYWluc3QgYWxsIGZpbGVzeXN0ZW1zIGFuZCB0aGVuIGNsZWFyIGl0IGFzCiAqIHdlIHN5bmMgdGhlbS4gIFNvIHJlZGlydGllZCBmaWxlc3lzdGVtcyBhcmUgc2tpcHBlZC4KICoKICogQnV0IGlmIHByb2Nlc3MgQSBpcyBjdXJyZW50bHkgcnVubmluZyBzeW5jX2ZpbGVzeXRlbXMgYW5kIHRoZW4gcHJvY2VzcyBCCiAqIGNhbGxzIHN5bmNfZmlsZXN5c3RlbXMgYXMgd2VsbCwgcHJvY2VzcyBCIHdpbGwgc2V0IGFsbCB0aGUgc19uZWVkX3N5bmNfZnMKICogZmxhZ3MgYWdhaW4sIHdoaWNoIHdpbGwgY2F1c2UgcHJvY2VzcyBBIHRvIHJlc3luYyBldmVyeXRoaW5nLiAgRml4IHRoYXQgd2l0aAogKiBhIGxvY2FsIG11dGV4LgogKgogKiAoRmFiaWFuKSBBdm9pZCBzeW5jX2ZzIHdpdGggY2xlYW4gZnMgJiB3YWl0IG1vZGUgMAogKi8Kdm9pZCBzeW5jX2ZpbGVzeXN0ZW1zKGludCB3YWl0KQp7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiOwoJc3RhdGljIERFQ0xBUkVfTVVURVgobXV0ZXgpOwoKCWRvd24oJm11dGV4KTsJCS8qIENvdWxkIGJlIGRvd25faW50ZXJydXB0aWJsZSAqLwoJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoc2IsICZzdXBlcl9ibG9ja3MsIHNfbGlzdCkgewoJCWlmICghc2ItPnNfb3AtPnN5bmNfZnMpCgkJCWNvbnRpbnVlOwoJCWlmIChzYi0+c19mbGFncyAmIE1TX1JET05MWSkKCQkJY29udGludWU7CgkJc2ItPnNfbmVlZF9zeW5jX2ZzID0gMTsKCX0KCnJlc3RhcnQ6CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHNiLCAmc3VwZXJfYmxvY2tzLCBzX2xpc3QpIHsKCQlpZiAoIXNiLT5zX25lZWRfc3luY19mcykKCQkJY29udGludWU7CgkJc2ItPnNfbmVlZF9zeW5jX2ZzID0gMDsKCQlpZiAoc2ItPnNfZmxhZ3MgJiBNU19SRE9OTFkpCgkJCWNvbnRpbnVlOwkvKiBobS4gIFdhcyByZW1vdW50ZWQgci9vIG1lYW53aGlsZSAqLwoJCXNiLT5zX2NvdW50Kys7CgkJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJCWRvd25fcmVhZCgmc2ItPnNfdW1vdW50KTsKCQlpZiAoc2ItPnNfcm9vdCAmJiAod2FpdCB8fCBzYi0+c19kaXJ0KSkKCQkJc2ItPnNfb3AtPnN5bmNfZnMoc2IsIHdhaXQpOwoJCXVwX3JlYWQoJnNiLT5zX3Vtb3VudCk7CgkJLyogcmVzdGFydCBvbmx5IHdoZW4gc2IgaXMgbm8gbG9uZ2VyIG9uIHRoZSBsaXN0ICovCgkJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCQlpZiAoX19wdXRfc3VwZXJfYW5kX25lZWRfcmVzdGFydChzYikpCgkJCWdvdG8gcmVzdGFydDsKCX0KCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCXVwKCZtdXRleCk7Cn0KCi8qKgogKglnZXRfc3VwZXIgLSBnZXQgdGhlIHN1cGVyYmxvY2sgb2YgYSBkZXZpY2UKICoJQGJkZXY6IGRldmljZSB0byBnZXQgdGhlIHN1cGVyYmxvY2sgZm9yCiAqCQogKglTY2FucyB0aGUgc3VwZXJibG9jayBsaXN0IGFuZCBmaW5kcyB0aGUgc3VwZXJibG9jayBvZiB0aGUgZmlsZSBzeXN0ZW0KICoJbW91bnRlZCBvbiB0aGUgZGV2aWNlIGdpdmVuLiAlTlVMTCBpcyByZXR1cm5lZCBpZiBubyBtYXRjaCBpcyBmb3VuZC4KICovCgpzdHJ1Y3Qgc3VwZXJfYmxvY2sgKiBnZXRfc3VwZXIoc3RydWN0IGJsb2NrX2RldmljZSAqYmRldikKewoJc3RydWN0IHN1cGVyX2Jsb2NrICpzYjsKCglpZiAoIWJkZXYpCgkJcmV0dXJuIE5VTEw7CgoJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKcmVzY2FuOgoJbGlzdF9mb3JfZWFjaF9lbnRyeShzYiwgJnN1cGVyX2Jsb2Nrcywgc19saXN0KSB7CgkJaWYgKHNiLT5zX2JkZXYgPT0gYmRldikgewoJCQlzYi0+c19jb3VudCsrOwoJCQlzcGluX3VubG9jaygmc2JfbG9jayk7CgkJCWRvd25fcmVhZCgmc2ItPnNfdW1vdW50KTsKCQkJaWYgKHNiLT5zX3Jvb3QpCgkJCQlyZXR1cm4gc2I7CgkJCXVwX3JlYWQoJnNiLT5zX3Vtb3VudCk7CgkJCS8qIHJlc3RhcnQgb25seSB3aGVuIHNiIGlzIG5vIGxvbmdlciBvbiB0aGUgbGlzdCAqLwoJCQlzcGluX2xvY2soJnNiX2xvY2spOwoJCQlpZiAoX19wdXRfc3VwZXJfYW5kX25lZWRfcmVzdGFydChzYikpCgkJCQlnb3RvIHJlc2NhbjsKCQl9Cgl9CglzcGluX3VubG9jaygmc2JfbG9jayk7CglyZXR1cm4gTlVMTDsKfQoKRVhQT1JUX1NZTUJPTChnZXRfc3VwZXIpOwogCnN0cnVjdCBzdXBlcl9ibG9jayAqIHVzZXJfZ2V0X3N1cGVyKGRldl90IGRldikKewoJc3RydWN0IHN1cGVyX2Jsb2NrICpzYjsKCglzcGluX2xvY2soJnNiX2xvY2spOwpyZXNjYW46CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHNiLCAmc3VwZXJfYmxvY2tzLCBzX2xpc3QpIHsKCQlpZiAoc2ItPnNfZGV2ID09ICBkZXYpIHsKCQkJc2ItPnNfY291bnQrKzsKCQkJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJCQlkb3duX3JlYWQoJnNiLT5zX3Vtb3VudCk7CgkJCWlmIChzYi0+c19yb290KQoJCQkJcmV0dXJuIHNiOwoJCQl1cF9yZWFkKCZzYi0+c191bW91bnQpOwoJCQkvKiByZXN0YXJ0IG9ubHkgd2hlbiBzYiBpcyBubyBsb25nZXIgb24gdGhlIGxpc3QgKi8KCQkJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCQkJaWYgKF9fcHV0X3N1cGVyX2FuZF9uZWVkX3Jlc3RhcnQoc2IpKQoJCQkJZ290byByZXNjYW47CgkJfQoJfQoJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJcmV0dXJuIE5VTEw7Cn0KCkVYUE9SVF9TWU1CT0wodXNlcl9nZXRfc3VwZXIpOwoKYXNtbGlua2FnZSBsb25nIHN5c191c3RhdCh1bnNpZ25lZCBkZXYsIHN0cnVjdCB1c3RhdCBfX3VzZXIgKiB1YnVmKQp7CiAgICAgICAgc3RydWN0IHN1cGVyX2Jsb2NrICpzOwogICAgICAgIHN0cnVjdCB1c3RhdCB0bXA7CiAgICAgICAgc3RydWN0IGtzdGF0ZnMgc2J1ZjsKCWludCBlcnIgPSAtRUlOVkFMOwoKICAgICAgICBzID0gdXNlcl9nZXRfc3VwZXIobmV3X2RlY29kZV9kZXYoZGV2KSk7CiAgICAgICAgaWYgKHMgPT0gTlVMTCkKICAgICAgICAgICAgICAgIGdvdG8gb3V0OwoJZXJyID0gdmZzX3N0YXRmcyhzLCAmc2J1Zik7Cglkcm9wX3N1cGVyKHMpOwoJaWYgKGVycikKCQlnb3RvIG91dDsKCiAgICAgICAgbWVtc2V0KCZ0bXAsMCxzaXplb2Yoc3RydWN0IHVzdGF0KSk7CiAgICAgICAgdG1wLmZfdGZyZWUgPSBzYnVmLmZfYmZyZWU7CiAgICAgICAgdG1wLmZfdGlub2RlID0gc2J1Zi5mX2ZmcmVlOwoKICAgICAgICBlcnIgPSBjb3B5X3RvX3VzZXIodWJ1ZiwmdG1wLHNpemVvZihzdHJ1Y3QgdXN0YXQpKSA/IC1FRkFVTFQgOiAwOwpvdXQ6CglyZXR1cm4gZXJyOwp9CgovKioKICoJbWFya19maWxlc19ybwogKglAc2I6IHN1cGVyYmxvY2sgaW4gcXVlc3Rpb24KICoKICoJQWxsIGZpbGVzIGFyZSBtYXJrZWQgcmVhZC9vbmx5LiAgV2UgZG9uJ3QgY2FyZSBhYm91dCBwZW5kaW5nCiAqCWRlbGV0ZSBmaWxlcyBzbyB0aGlzIHNob3VsZCBiZSB1c2VkIGluICdmb3JjZScgbW9kZSBvbmx5CiAqLwoKc3RhdGljIHZvaWQgbWFya19maWxlc19ybyhzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiKQp7CglzdHJ1Y3QgZmlsZSAqZjsKCglmaWxlX2xpc3RfbG9jaygpOwoJbGlzdF9mb3JfZWFjaF9lbnRyeShmLCAmc2ItPnNfZmlsZXMsIGZfdS5mdV9saXN0KSB7CgkJaWYgKFNfSVNSRUcoZi0+Zl9kZW50cnktPmRfaW5vZGUtPmlfbW9kZSkgJiYgZmlsZV9jb3VudChmKSkKCQkJZi0+Zl9tb2RlICY9IH5GTU9ERV9XUklURTsKCX0KCWZpbGVfbGlzdF91bmxvY2soKTsKfQoKLyoqCiAqCWRvX3JlbW91bnRfc2IgLSBhc2tzIGZpbGVzeXN0ZW0gdG8gY2hhbmdlIG1vdW50IG9wdGlvbnMuCiAqCUBzYjoJc3VwZXJibG9jayBpbiBxdWVzdGlvbgogKglAZmxhZ3M6CW51bWVyaWMgcGFydCBvZiBvcHRpb25zCiAqCUBkYXRhOgl0aGUgcmVzdCBvZiBvcHRpb25zCiAqICAgICAgQGZvcmNlOiB3aGV0aGVyIG9yIG5vdCB0byBmb3JjZSB0aGUgY2hhbmdlCiAqCiAqCUFsdGVycyB0aGUgbW91bnQgb3B0aW9ucyBvZiBhIG1vdW50ZWQgZmlsZSBzeXN0ZW0uCiAqLwppbnQgZG9fcmVtb3VudF9zYihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiLCBpbnQgZmxhZ3MsIHZvaWQgKmRhdGEsIGludCBmb3JjZSkKewoJaW50IHJldHZhbDsKCQoJaWYgKCEoZmxhZ3MgJiBNU19SRE9OTFkpICYmIGJkZXZfcmVhZF9vbmx5KHNiLT5zX2JkZXYpKQoJCXJldHVybiAtRUFDQ0VTOwoJaWYgKGZsYWdzICYgTVNfUkRPTkxZKQoJCWFjY3RfYXV0b19jbG9zZShzYik7CglzaHJpbmtfZGNhY2hlX3NiKHNiKTsKCWZzeW5jX3N1cGVyKHNiKTsKCgkvKiBJZiB3ZSBhcmUgcmVtb3VudGluZyBSRE9OTFkgYW5kIGN1cnJlbnQgc2IgaXMgcmVhZC93cml0ZSwKCSAgIG1ha2Ugc3VyZSB0aGVyZSBhcmUgbm8gcncgZmlsZXMgb3BlbmVkICovCglpZiAoKGZsYWdzICYgTVNfUkRPTkxZKSAmJiAhKHNiLT5zX2ZsYWdzICYgTVNfUkRPTkxZKSkgewoJCWlmIChmb3JjZSkKCQkJbWFya19maWxlc19ybyhzYik7CgkJZWxzZSBpZiAoIWZzX21heV9yZW1vdW50X3JvKHNiKSkKCQkJcmV0dXJuIC1FQlVTWTsKCX0KCglpZiAoc2ItPnNfb3AtPnJlbW91bnRfZnMpIHsKCQlsb2NrX3N1cGVyKHNiKTsKCQlyZXR2YWwgPSBzYi0+c19vcC0+cmVtb3VudF9mcyhzYiwgJmZsYWdzLCBkYXRhKTsKCQl1bmxvY2tfc3VwZXIoc2IpOwoJCWlmIChyZXR2YWwpCgkJCXJldHVybiByZXR2YWw7Cgl9CglzYi0+c19mbGFncyA9IChzYi0+c19mbGFncyAmIH5NU19STVRfTUFTSykgfCAoZmxhZ3MgJiBNU19STVRfTUFTSyk7CglyZXR1cm4gMDsKfQoKc3RhdGljIHZvaWQgZG9fZW1lcmdlbmN5X3JlbW91bnQodW5zaWduZWQgbG9uZyBmb28pCnsKCXN0cnVjdCBzdXBlcl9ibG9jayAqc2I7CgoJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoc2IsICZzdXBlcl9ibG9ja3MsIHNfbGlzdCkgewoJCXNiLT5zX2NvdW50Kys7CgkJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJCWRvd25fcmVhZCgmc2ItPnNfdW1vdW50KTsKCQlpZiAoc2ItPnNfcm9vdCAmJiBzYi0+c19iZGV2ICYmICEoc2ItPnNfZmxhZ3MgJiBNU19SRE9OTFkpKSB7CgkJCS8qCgkJCSAqIC0+cmVtb3VudF9mcyBuZWVkcyBsb2NrX2tlcm5lbCgpLgoJCQkgKgoJCQkgKiBXaGF0IGxvY2sgcHJvdGVjdHMgc2ItPnNfZmxhZ3M/PwoJCQkgKi8KCQkJbG9ja19rZXJuZWwoKTsKCQkJZG9fcmVtb3VudF9zYihzYiwgTVNfUkRPTkxZLCBOVUxMLCAxKTsKCQkJdW5sb2NrX2tlcm5lbCgpOwoJCX0KCQlkcm9wX3N1cGVyKHNiKTsKCQlzcGluX2xvY2soJnNiX2xvY2spOwoJfQoJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJcHJpbnRrKCJFbWVyZ2VuY3kgUmVtb3VudCBjb21wbGV0ZVxuIik7Cn0KCnZvaWQgZW1lcmdlbmN5X3JlbW91bnQodm9pZCkKewoJcGRmbHVzaF9vcGVyYXRpb24oZG9fZW1lcmdlbmN5X3JlbW91bnQsIDApOwp9CgovKgogKiBVbm5hbWVkIGJsb2NrIGRldmljZXMgYXJlIGR1bW15IGRldmljZXMgdXNlZCBieSB2aXJ0dWFsCiAqIGZpbGVzeXN0ZW1zIHdoaWNoIGRvbid0IHVzZSByZWFsIGJsb2NrLWRldmljZXMuICAtLSBqcnMKICovCgpzdGF0aWMgc3RydWN0IGlkciB1bm5hbWVkX2Rldl9pZHI7CnN0YXRpYyBERUZJTkVfU1BJTkxPQ0sodW5uYW1lZF9kZXZfbG9jayk7LyogcHJvdGVjdHMgdGhlIGFib3ZlICovCgppbnQgc2V0X2Fub25fc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzLCB2b2lkICpkYXRhKQp7CglpbnQgZGV2OwoJaW50IGVycm9yOwoKIHJldHJ5OgoJaWYgKGlkcl9wcmVfZ2V0KCZ1bm5hbWVkX2Rldl9pZHIsIEdGUF9BVE9NSUMpID09IDApCgkJcmV0dXJuIC1FTk9NRU07CglzcGluX2xvY2soJnVubmFtZWRfZGV2X2xvY2spOwoJZXJyb3IgPSBpZHJfZ2V0X25ldygmdW5uYW1lZF9kZXZfaWRyLCBOVUxMLCAmZGV2KTsKCXNwaW5fdW5sb2NrKCZ1bm5hbWVkX2Rldl9sb2NrKTsKCWlmIChlcnJvciA9PSAtRUFHQUlOKQoJCS8qIFdlIHJhY2VkIGFuZCBsb3N0IHdpdGggYW5vdGhlciBDUFUuICovCgkJZ290byByZXRyeTsKCWVsc2UgaWYgKGVycm9yKQoJCXJldHVybiAtRUFHQUlOOwoKCWlmICgoZGV2ICYgTUFYX0lEX01BU0spID09ICgxIDw8IE1JTk9SQklUUykpIHsKCQlzcGluX2xvY2soJnVubmFtZWRfZGV2X2xvY2spOwoJCWlkcl9yZW1vdmUoJnVubmFtZWRfZGV2X2lkciwgZGV2KTsKCQlzcGluX3VubG9jaygmdW5uYW1lZF9kZXZfbG9jayk7CgkJcmV0dXJuIC1FTUZJTEU7Cgl9CglzLT5zX2RldiA9IE1LREVWKDAsIGRldiAmIE1JTk9STUFTSyk7CglyZXR1cm4gMDsKfQoKRVhQT1JUX1NZTUJPTChzZXRfYW5vbl9zdXBlcik7Cgp2b2lkIGtpbGxfYW5vbl9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiKQp7CglpbnQgc2xvdCA9IE1JTk9SKHNiLT5zX2Rldik7CgoJZ2VuZXJpY19zaHV0ZG93bl9zdXBlcihzYik7CglzcGluX2xvY2soJnVubmFtZWRfZGV2X2xvY2spOwoJaWRyX3JlbW92ZSgmdW5uYW1lZF9kZXZfaWRyLCBzbG90KTsKCXNwaW5fdW5sb2NrKCZ1bm5hbWVkX2Rldl9sb2NrKTsKfQoKRVhQT1JUX1NZTUJPTChraWxsX2Fub25fc3VwZXIpOwoKdm9pZCBfX2luaXQgdW5uYW1lZF9kZXZfaW5pdCh2b2lkKQp7CglpZHJfaW5pdCgmdW5uYW1lZF9kZXZfaWRyKTsKfQoKdm9pZCBraWxsX2xpdHRlcl9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiKQp7CglpZiAoc2ItPnNfcm9vdCkKCQlkX2dlbm9jaWRlKHNiLT5zX3Jvb3QpOwoJa2lsbF9hbm9uX3N1cGVyKHNiKTsKfQoKRVhQT1JUX1NZTUJPTChraWxsX2xpdHRlcl9zdXBlcik7CgpzdGF0aWMgaW50IHNldF9iZGV2X3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqcywgdm9pZCAqZGF0YSkKewoJcy0+c19iZGV2ID0gZGF0YTsKCXMtPnNfZGV2ID0gcy0+c19iZGV2LT5iZF9kZXY7CglyZXR1cm4gMDsKfQoKc3RhdGljIGludCB0ZXN0X2JkZXZfc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzLCB2b2lkICpkYXRhKQp7CglyZXR1cm4gKHZvaWQgKilzLT5zX2JkZXYgPT0gZGF0YTsKfQoKc3RhdGljIHZvaWQgYmRldl91ZXZlbnQoc3RydWN0IGJsb2NrX2RldmljZSAqYmRldiwgZW51bSBrb2JqZWN0X2FjdGlvbiBhY3Rpb24pCnsKCWlmIChiZGV2LT5iZF9kaXNrKSB7CgkJaWYgKGJkZXYtPmJkX3BhcnQpCgkJCWtvYmplY3RfdWV2ZW50KCZiZGV2LT5iZF9wYXJ0LT5rb2JqLCBhY3Rpb24sIE5VTEwpOwoJCWVsc2UKCQkJa29iamVjdF91ZXZlbnQoJmJkZXYtPmJkX2Rpc2stPmtvYmosIGFjdGlvbiwgTlVMTCk7Cgl9Cn0KCnN0cnVjdCBzdXBlcl9ibG9jayAqZ2V0X3NiX2JkZXYoc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzX3R5cGUsCglpbnQgZmxhZ3MsIGNvbnN0IGNoYXIgKmRldl9uYW1lLCB2b2lkICpkYXRhLAoJaW50ICgqZmlsbF9zdXBlcikoc3RydWN0IHN1cGVyX2Jsb2NrICosIHZvaWQgKiwgaW50KSkKewoJc3RydWN0IGJsb2NrX2RldmljZSAqYmRldjsKCXN0cnVjdCBzdXBlcl9ibG9jayAqczsKCWludCBlcnJvciA9IDA7CgoJYmRldiA9IG9wZW5fYmRldl9leGNsKGRldl9uYW1lLCBmbGFncywgZnNfdHlwZSk7CglpZiAoSVNfRVJSKGJkZXYpKQoJCXJldHVybiAoc3RydWN0IHN1cGVyX2Jsb2NrICopYmRldjsKCgkvKgoJICogb25jZSB0aGUgc3VwZXIgaXMgaW5zZXJ0ZWQgaW50byB0aGUgbGlzdCBieSBzZ2V0LCBzX3Vtb3VudAoJICogd2lsbCBwcm90ZWN0IHRoZSBsb2NrZnMgY29kZSBmcm9tIHRyeWluZyB0byBzdGFydCBhIHNuYXBzaG90CgkgKiB3aGlsZSB3ZSBhcmUgbW91bnRpbmcKCSAqLwoJZG93bigmYmRldi0+YmRfbW91bnRfc2VtKTsKCXMgPSBzZ2V0KGZzX3R5cGUsIHRlc3RfYmRldl9zdXBlciwgc2V0X2JkZXZfc3VwZXIsIGJkZXYpOwoJdXAoJmJkZXYtPmJkX21vdW50X3NlbSk7CglpZiAoSVNfRVJSKHMpKQoJCWdvdG8gb3V0OwoKCWlmIChzLT5zX3Jvb3QpIHsKCQlpZiAoKGZsYWdzIF4gcy0+c19mbGFncykgJiBNU19SRE9OTFkpIHsKCQkJdXBfd3JpdGUoJnMtPnNfdW1vdW50KTsKCQkJZGVhY3RpdmF0ZV9zdXBlcihzKTsKCQkJcyA9IEVSUl9QVFIoLUVCVVNZKTsKCQl9CgkJZ290byBvdXQ7Cgl9IGVsc2UgewoJCWNoYXIgYltCREVWTkFNRV9TSVpFXTsKCgkJcy0+c19mbGFncyA9IGZsYWdzOwoJCXN0cmxjcHkocy0+c19pZCwgYmRldm5hbWUoYmRldiwgYiksIHNpemVvZihzLT5zX2lkKSk7CgkJcy0+c19vbGRfYmxvY2tzaXplID0gYmxvY2tfc2l6ZShiZGV2KTsKCQlzYl9zZXRfYmxvY2tzaXplKHMsIHMtPnNfb2xkX2Jsb2Nrc2l6ZSk7CgkJZXJyb3IgPSBmaWxsX3N1cGVyKHMsIGRhdGEsIGZsYWdzICYgTVNfVkVSQk9TRSA/IDEgOiAwKTsKCQlpZiAoZXJyb3IpIHsKCQkJdXBfd3JpdGUoJnMtPnNfdW1vdW50KTsKCQkJZGVhY3RpdmF0ZV9zdXBlcihzKTsKCQkJcyA9IEVSUl9QVFIoZXJyb3IpOwoJCX0gZWxzZSB7CgkJCXMtPnNfZmxhZ3MgfD0gTVNfQUNUSVZFOwoJCQliZGV2X3VldmVudChiZGV2LCBLT0JKX01PVU5UKTsKCQl9Cgl9CgoJcmV0dXJuIHM7CgpvdXQ6CgljbG9zZV9iZGV2X2V4Y2woYmRldik7CglyZXR1cm4gczsKfQoKRVhQT1JUX1NZTUJPTChnZXRfc2JfYmRldik7Cgp2b2lkIGtpbGxfYmxvY2tfc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJc3RydWN0IGJsb2NrX2RldmljZSAqYmRldiA9IHNiLT5zX2JkZXY7CgoJYmRldl91ZXZlbnQoYmRldiwgS09CSl9VTU9VTlQpOwoJZ2VuZXJpY19zaHV0ZG93bl9zdXBlcihzYik7CglzeW5jX2Jsb2NrZGV2KGJkZXYpOwoJY2xvc2VfYmRldl9leGNsKGJkZXYpOwp9CgpFWFBPUlRfU1lNQk9MKGtpbGxfYmxvY2tfc3VwZXIpOwoKc3RydWN0IHN1cGVyX2Jsb2NrICpnZXRfc2Jfbm9kZXYoc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzX3R5cGUsCglpbnQgZmxhZ3MsIHZvaWQgKmRhdGEsCglpbnQgKCpmaWxsX3N1cGVyKShzdHJ1Y3Qgc3VwZXJfYmxvY2sgKiwgdm9pZCAqLCBpbnQpKQp7CglpbnQgZXJyb3I7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnMgPSBzZ2V0KGZzX3R5cGUsIE5VTEwsIHNldF9hbm9uX3N1cGVyLCBOVUxMKTsKCglpZiAoSVNfRVJSKHMpKQoJCXJldHVybiBzOwoKCXMtPnNfZmxhZ3MgPSBmbGFnczsKCgllcnJvciA9IGZpbGxfc3VwZXIocywgZGF0YSwgZmxhZ3MgJiBNU19WRVJCT1NFID8gMSA6IDApOwoJaWYgKGVycm9yKSB7CgkJdXBfd3JpdGUoJnMtPnNfdW1vdW50KTsKCQlkZWFjdGl2YXRlX3N1cGVyKHMpOwoJCXJldHVybiBFUlJfUFRSKGVycm9yKTsKCX0KCXMtPnNfZmxhZ3MgfD0gTVNfQUNUSVZFOwoJcmV0dXJuIHM7Cn0KCkVYUE9SVF9TWU1CT0woZ2V0X3NiX25vZGV2KTsKCnN0YXRpYyBpbnQgY29tcGFyZV9zaW5nbGUoc3RydWN0IHN1cGVyX2Jsb2NrICpzLCB2b2lkICpwKQp7CglyZXR1cm4gMTsKfQoKc3RydWN0IHN1cGVyX2Jsb2NrICpnZXRfc2Jfc2luZ2xlKHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmc190eXBlLAoJaW50IGZsYWdzLCB2b2lkICpkYXRhLAoJaW50ICgqZmlsbF9zdXBlcikoc3RydWN0IHN1cGVyX2Jsb2NrICosIHZvaWQgKiwgaW50KSkKewoJc3RydWN0IHN1cGVyX2Jsb2NrICpzOwoJaW50IGVycm9yOwoKCXMgPSBzZ2V0KGZzX3R5cGUsIGNvbXBhcmVfc2luZ2xlLCBzZXRfYW5vbl9zdXBlciwgTlVMTCk7CglpZiAoSVNfRVJSKHMpKQoJCXJldHVybiBzOwoJaWYgKCFzLT5zX3Jvb3QpIHsKCQlzLT5zX2ZsYWdzID0gZmxhZ3M7CgkJZXJyb3IgPSBmaWxsX3N1cGVyKHMsIGRhdGEsIGZsYWdzICYgTVNfVkVSQk9TRSA/IDEgOiAwKTsKCQlpZiAoZXJyb3IpIHsKCQkJdXBfd3JpdGUoJnMtPnNfdW1vdW50KTsKCQkJZGVhY3RpdmF0ZV9zdXBlcihzKTsKCQkJcmV0dXJuIEVSUl9QVFIoZXJyb3IpOwoJCX0KCQlzLT5zX2ZsYWdzIHw9IE1TX0FDVElWRTsKCX0KCWRvX3JlbW91bnRfc2IocywgZmxhZ3MsIGRhdGEsIDApOwoJcmV0dXJuIHM7Cn0KCkVYUE9SVF9TWU1CT0woZ2V0X3NiX3NpbmdsZSk7CgpzdHJ1Y3QgdmZzbW91bnQgKgpkb19rZXJuX21vdW50KGNvbnN0IGNoYXIgKmZzdHlwZSwgaW50IGZsYWdzLCBjb25zdCBjaGFyICpuYW1lLCB2b2lkICpkYXRhKQp7CglzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSAqdHlwZSA9IGdldF9mc190eXBlKGZzdHlwZSk7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiID0gRVJSX1BUUigtRU5PTUVNKTsKCXN0cnVjdCB2ZnNtb3VudCAqbW50OwoJaW50IGVycm9yOwoJY2hhciAqc2VjZGF0YSA9IE5VTEw7CgoJaWYgKCF0eXBlKQoJCXJldHVybiBFUlJfUFRSKC1FTk9ERVYpOwoKCW1udCA9IGFsbG9jX3Zmc21udChuYW1lKTsKCWlmICghbW50KQoJCWdvdG8gb3V0OwoKCWlmIChkYXRhKSB7CgkJc2VjZGF0YSA9IGFsbG9jX3NlY2RhdGEoKTsKCQlpZiAoIXNlY2RhdGEpIHsKCQkJc2IgPSBFUlJfUFRSKC1FTk9NRU0pOwoJCQlnb3RvIG91dF9tbnQ7CgkJfQoKCQllcnJvciA9IHNlY3VyaXR5X3NiX2NvcHlfZGF0YSh0eXBlLCBkYXRhLCBzZWNkYXRhKTsKCQlpZiAoZXJyb3IpIHsKCQkJc2IgPSBFUlJfUFRSKGVycm9yKTsKCQkJZ290byBvdXRfZnJlZV9zZWNkYXRhOwoJCX0KCX0KCglzYiA9IHR5cGUtPmdldF9zYih0eXBlLCBmbGFncywgbmFtZSwgZGF0YSk7CglpZiAoSVNfRVJSKHNiKSkKCQlnb3RvIG91dF9mcmVlX3NlY2RhdGE7CiAJZXJyb3IgPSBzZWN1cml0eV9zYl9rZXJuX21vdW50KHNiLCBzZWNkYXRhKTsKIAlpZiAoZXJyb3IpCiAJCWdvdG8gb3V0X3NiOwoJbW50LT5tbnRfc2IgPSBzYjsKCW1udC0+bW50X3Jvb3QgPSBkZ2V0KHNiLT5zX3Jvb3QpOwoJbW50LT5tbnRfbW91bnRwb2ludCA9IHNiLT5zX3Jvb3Q7CgltbnQtPm1udF9wYXJlbnQgPSBtbnQ7Cgl1cF93cml0ZSgmc2ItPnNfdW1vdW50KTsKCWZyZWVfc2VjZGF0YShzZWNkYXRhKTsKCXB1dF9maWxlc3lzdGVtKHR5cGUpOwoJcmV0dXJuIG1udDsKb3V0X3NiOgoJdXBfd3JpdGUoJnNiLT5zX3Vtb3VudCk7CglkZWFjdGl2YXRlX3N1cGVyKHNiKTsKCXNiID0gRVJSX1BUUihlcnJvcik7Cm91dF9mcmVlX3NlY2RhdGE6CglmcmVlX3NlY2RhdGEoc2VjZGF0YSk7Cm91dF9tbnQ6CglmcmVlX3Zmc21udChtbnQpOwpvdXQ6CglwdXRfZmlsZXN5c3RlbSh0eXBlKTsKCXJldHVybiAoc3RydWN0IHZmc21vdW50ICopc2I7Cn0KCkVYUE9SVF9TWU1CT0xfR1BMKGRvX2tlcm5fbW91bnQpOwoKc3RydWN0IHZmc21vdW50ICprZXJuX21vdW50KHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICp0eXBlKQp7CglyZXR1cm4gZG9fa2Vybl9tb3VudCh0eXBlLT5uYW1lLCAwLCB0eXBlLT5uYW1lLCBOVUxMKTsKfQoKRVhQT1JUX1NZTUJPTChrZXJuX21vdW50KTsK