LyoKICogIGxpbnV4L2ZzL3N1cGVyLmMKICoKICogIENvcHlyaWdodCAoQykgMTk5MSwgMTk5MiAgTGludXMgVG9ydmFsZHMKICoKICogIHN1cGVyLmMgY29udGFpbnMgY29kZSB0byBoYW5kbGU6IC0gbW91bnQgc3RydWN0dXJlcwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLSBzdXBlci1ibG9jayB0YWJsZXMKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gZmlsZXN5c3RlbSBkcml2ZXJzIGxpc3QKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gbW91bnQgc3lzdGVtIGNhbGwKICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC0gdW1vdW50IHN5c3RlbSBjYWxsCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAtIHVzdGF0IHN5c3RlbSBjYWxsCiAqCiAqIEdLIDIvNS85NSAgLSAgQ2hhbmdlZCB0byBzdXBwb3J0IG1vdW50aW5nIHRoZSByb290IGZzIHZpYSBORlMKICoKICogIEFkZGVkIGtlcm5lbGQgc3VwcG9ydDogSmFjcXVlcyBHZWxpbmFzIGFuZCBCam9ybiBFa3dhbGwKICogIEFkZGVkIGNoYW5nZV9yb290OiBXZXJuZXIgQWxtZXNiZXJnZXIgJiBIYW5zIExlcm1lbiwgRmViICc5NgogKiAgQWRkZWQgb3B0aW9ucyB0byAvcHJvYy9tb3VudHM6CiAqICAgIFRvcmJq9nJuIExpbmRoICh0b3Jiam9ybi5saW5kaEBnb3B0YS5zZSksIEFwcmlsIDE0LCAxOTk2LgogKiAgQWRkZWQgZGV2ZnMgc3VwcG9ydDogUmljaGFyZCBHb29jaCA8cmdvb2NoQGF0bmYuY3Npcm8uYXU+LCAxMy1KQU4tMTk5OAogKiAgSGVhdmlseSByZXdyaXR0ZW4gZm9yICdvbmUgZnMgLSBvbmUgdHJlZScgZGNhY2hlIGFyY2hpdGVjdHVyZS4gQVYsIE1hciAyMDAwCiAqLwoKI2luY2x1ZGUgPGxpbnV4L2NvbmZpZy5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC9zbGFiLmg+CiNpbmNsdWRlIDxsaW51eC9pbml0Lmg+CiNpbmNsdWRlIDxsaW51eC9zbXBfbG9jay5oPgojaW5jbHVkZSA8bGludXgvYWNjdC5oPgojaW5jbHVkZSA8bGludXgvYmxrZGV2Lmg+CiNpbmNsdWRlIDxsaW51eC9xdW90YW9wcy5oPgojaW5jbHVkZSA8bGludXgvbmFtZWkuaD4KI2luY2x1ZGUgPGxpbnV4L2J1ZmZlcl9oZWFkLmg+CQkvKiBmb3IgZnN5bmNfc3VwZXIoKSAqLwojaW5jbHVkZSA8bGludXgvbW91bnQuaD4KI2luY2x1ZGUgPGxpbnV4L3NlY3VyaXR5Lmg+CiNpbmNsdWRlIDxsaW51eC9zeXNjYWxscy5oPgojaW5jbHVkZSA8bGludXgvdmZzLmg+CiNpbmNsdWRlIDxsaW51eC93cml0ZWJhY2suaD4JCS8qIGZvciB0aGUgZW1lcmdlbmN5IHJlbW91bnQgc3R1ZmYgKi8KI2luY2x1ZGUgPGxpbnV4L2lkci5oPgojaW5jbHVkZSA8bGludXgva29iamVjdC5oPgojaW5jbHVkZSA8YXNtL3VhY2Nlc3MuaD4KCgp2b2lkIGdldF9maWxlc3lzdGVtKHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmcyk7CnZvaWQgcHV0X2ZpbGVzeXN0ZW0oc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzKTsKc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmdldF9mc190eXBlKGNvbnN0IGNoYXIgKm5hbWUpOwoKTElTVF9IRUFEKHN1cGVyX2Jsb2Nrcyk7CkRFRklORV9TUElOTE9DSyhzYl9sb2NrKTsKCi8qKgogKglhbGxvY19zdXBlcgktCWNyZWF0ZSBuZXcgc3VwZXJibG9jawogKgogKglBbGxvY2F0ZXMgYW5kIGluaXRpYWxpemVzIGEgbmV3ICZzdHJ1Y3Qgc3VwZXJfYmxvY2suICBhbGxvY19zdXBlcigpCiAqCXJldHVybnMgYSBwb2ludGVyIG5ldyBzdXBlcmJsb2NrIG9yICVOVUxMIGlmIGFsbG9jYXRpb24gaGFkIGZhaWxlZC4KICovCnN0YXRpYyBzdHJ1Y3Qgc3VwZXJfYmxvY2sgKmFsbG9jX3N1cGVyKHZvaWQpCnsKCXN0cnVjdCBzdXBlcl9ibG9jayAqcyA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBzdXBlcl9ibG9jayksICBHRlBfVVNFUik7CglzdGF0aWMgc3RydWN0IHN1cGVyX29wZXJhdGlvbnMgZGVmYXVsdF9vcDsKCglpZiAocykgewoJCW1lbXNldChzLCAwLCBzaXplb2Yoc3RydWN0IHN1cGVyX2Jsb2NrKSk7CgkJaWYgKHNlY3VyaXR5X3NiX2FsbG9jKHMpKSB7CgkJCWtmcmVlKHMpOwoJCQlzID0gTlVMTDsKCQkJZ290byBvdXQ7CgkJfQoJCUlOSVRfTElTVF9IRUFEKCZzLT5zX2RpcnR5KTsKCQlJTklUX0xJU1RfSEVBRCgmcy0+c19pbyk7CgkJSU5JVF9MSVNUX0hFQUQoJnMtPnNfZmlsZXMpOwoJCUlOSVRfTElTVF9IRUFEKCZzLT5zX2luc3RhbmNlcyk7CgkJSU5JVF9ITElTVF9IRUFEKCZzLT5zX2Fub24pOwoJCUlOSVRfTElTVF9IRUFEKCZzLT5zX2lub2Rlcyk7CgkJaW5pdF9yd3NlbSgmcy0+c191bW91bnQpOwoJCW11dGV4X2luaXQoJnMtPnNfbG9jayk7CgkJZG93bl93cml0ZSgmcy0+c191bW91bnQpOwoJCXMtPnNfY291bnQgPSBTX0JJQVM7CgkJYXRvbWljX3NldCgmcy0+c19hY3RpdmUsIDEpOwoJCXNlbWFfaW5pdCgmcy0+c192ZnNfcmVuYW1lX3NlbSwxKTsKCQlzZW1hX2luaXQoJnMtPnNfZHF1b3QuZHFpb19zZW0sIDEpOwoJCXNlbWFfaW5pdCgmcy0+c19kcXVvdC5kcW9ub2ZmX3NlbSwgMSk7CgkJaW5pdF9yd3NlbSgmcy0+c19kcXVvdC5kcXB0cl9zZW0pOwoJCWluaXRfd2FpdHF1ZXVlX2hlYWQoJnMtPnNfd2FpdF91bmZyb3plbik7CgkJcy0+c19tYXhieXRlcyA9IE1BWF9OT05fTEZTOwoJCXMtPmRxX29wID0gc2JfZHF1b3Rfb3BzOwoJCXMtPnNfcWNvcCA9IHNiX3F1b3RhY3RsX29wczsKCQlzLT5zX29wID0gJmRlZmF1bHRfb3A7CgkJcy0+c190aW1lX2dyYW4gPSAxMDAwMDAwMDAwOwoJfQpvdXQ6CglyZXR1cm4gczsKfQoKLyoqCiAqCWRlc3Ryb3lfc3VwZXIJLQlmcmVlcyBhIHN1cGVyYmxvY2sKICoJQHM6IHN1cGVyYmxvY2sgdG8gZnJlZQogKgogKglGcmVlcyBhIHN1cGVyYmxvY2suCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgZGVzdHJveV9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnMpCnsKCXNlY3VyaXR5X3NiX2ZyZWUocyk7CglrZnJlZShzKTsKfQoKLyogU3VwZXJibG9jayByZWZjb3VudGluZyAgKi8KCi8qCiAqIERyb3AgYSBzdXBlcmJsb2NrJ3MgcmVmY291bnQuICBSZXR1cm5zIG5vbi16ZXJvIGlmIHRoZSBzdXBlcmJsb2NrIHdhcwogKiBkZXN0cm95ZWQuICBUaGUgY2FsbGVyIG11c3QgaG9sZCBzYl9sb2NrLgogKi8KaW50IF9fcHV0X3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IpCnsKCWludCByZXQgPSAwOwoKCWlmICghLS1zYi0+c19jb3VudCkgewoJCWRlc3Ryb3lfc3VwZXIoc2IpOwoJCXJldCA9IDE7Cgl9CglyZXR1cm4gcmV0Owp9CgovKgogKiBEcm9wIGEgc3VwZXJibG9jaydzIHJlZmNvdW50LgogKiBSZXR1cm5zIG5vbi16ZXJvIGlmIHRoZSBzdXBlcmJsb2NrIGlzIGFib3V0IHRvIGJlIGRlc3Ryb3llZCBhbmQKICogYXQgbGVhc3QgaXMgYWxyZWFkeSByZW1vdmVkIGZyb20gc3VwZXJfYmxvY2tzIGxpc3QsIHNvIGlmIHdlIGFyZQogKiBtYWtpbmcgYSBsb29wIHRocm91Z2ggc3VwZXIgYmxvY2tzIHRoZW4gd2UgbmVlZCB0byByZXN0YXJ0LgogKiBUaGUgY2FsbGVyIG11c3QgaG9sZCBzYl9sb2NrLgogKi8KaW50IF9fcHV0X3N1cGVyX2FuZF9uZWVkX3Jlc3RhcnQoc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJLyogY2hlY2sgZm9yIHJhY2Ugd2l0aCBnZW5lcmljX3NodXRkb3duX3N1cGVyKCkgKi8KCWlmIChsaXN0X2VtcHR5KCZzYi0+c19saXN0KSkgewoJCS8qIHN1cGVyIGJsb2NrIGlzIHJlbW92ZWQsIG5lZWQgdG8gcmVzdGFydC4uLiAqLwoJCV9fcHV0X3N1cGVyKHNiKTsKCQlyZXR1cm4gMTsKCX0KCS8qIGNhbid0IGJlIHRoZSBsYXN0LCBzaW5jZSBzX2xpc3QgaXMgc3RpbGwgaW4gdXNlICovCglzYi0+c19jb3VudC0tOwoJQlVHX09OKHNiLT5zX2NvdW50ID09IDApOwoJcmV0dXJuIDA7Cn0KCi8qKgogKglwdXRfc3VwZXIJLQlkcm9wIGEgdGVtcG9yYXJ5IHJlZmVyZW5jZSB0byBzdXBlcmJsb2NrCiAqCUBzYjogc3VwZXJibG9jayBpbiBxdWVzdGlvbgogKgogKglEcm9wcyBhIHRlbXBvcmFyeSByZWZlcmVuY2UsIGZyZWVzIHN1cGVyYmxvY2sgaWYgdGhlcmUncyBubwogKglyZWZlcmVuY2VzIGxlZnQuCiAqLwpzdGF0aWMgdm9pZCBwdXRfc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCV9fcHV0X3N1cGVyKHNiKTsKCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKfQoKCi8qKgogKglkZWFjdGl2YXRlX3N1cGVyCS0JZHJvcCBhbiBhY3RpdmUgcmVmZXJlbmNlIHRvIHN1cGVyYmxvY2sKICoJQHM6IHN1cGVyYmxvY2sgdG8gZGVhY3RpdmF0ZQogKgogKglEcm9wcyBhbiBhY3RpdmUgcmVmZXJlbmNlIHRvIHN1cGVyYmxvY2ssIGFjcXVpcmluZyBhIHRlbXByb3J5IG9uZSBpZgogKgl0aGVyZSBpcyBubyBhY3RpdmUgcmVmZXJlbmNlcyBsZWZ0LiAgSW4gdGhhdCBjYXNlIHdlIGxvY2sgc3VwZXJibG9jaywKICoJdGVsbCBmcyBkcml2ZXIgdG8gc2h1dCBpdCBkb3duIGFuZCBkcm9wIHRoZSB0ZW1wb3JhcnkgcmVmZXJlbmNlIHdlCiAqCWhhZCBqdXN0IGFjcXVpcmVkLgogKi8Kdm9pZCBkZWFjdGl2YXRlX3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqcykKewoJc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzID0gcy0+c190eXBlOwoJaWYgKGF0b21pY19kZWNfYW5kX2xvY2soJnMtPnNfYWN0aXZlLCAmc2JfbG9jaykpIHsKCQlzLT5zX2NvdW50IC09IFNfQklBUy0xOwoJCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCQlEUVVPVF9PRkYocyk7CgkJZG93bl93cml0ZSgmcy0+c191bW91bnQpOwoJCWZzLT5raWxsX3NiKHMpOwoJCXB1dF9maWxlc3lzdGVtKGZzKTsKCQlwdXRfc3VwZXIocyk7Cgl9Cn0KCkVYUE9SVF9TWU1CT0woZGVhY3RpdmF0ZV9zdXBlcik7CgovKioKICoJZ3JhYl9zdXBlciAtIGFjcXVpcmUgYW4gYWN0aXZlIHJlZmVyZW5jZQogKglAczogcmVmZXJlbmNlIHdlIGFyZSB0cnlpbmcgdG8gbWFrZSBhY3RpdmUKICoKICoJVHJpZXMgdG8gYWNxdWlyZSBhbiBhY3RpdmUgcmVmZXJlbmNlLiAgZ3JhYl9zdXBlcigpIGlzIHVzZWQgd2hlbiB3ZQogKiAJaGFkIGp1c3QgZm91bmQgYSBzdXBlcmJsb2NrIGluIHN1cGVyX2Jsb2NrcyBvciBmc190eXBlLT5mc19zdXBlcnMKICoJYW5kIHdhbnQgdG8gdHVybiBpdCBpbnRvIGEgZnVsbC1ibG93biBhY3RpdmUgcmVmZXJlbmNlLiAgZ3JhYl9zdXBlcigpCiAqCWlzIGNhbGxlZCB3aXRoIHNiX2xvY2sgaGVsZCBhbmQgZHJvcHMgaXQuICBSZXR1cm5zIDEgaW4gY2FzZSBvZgogKglzdWNjZXNzLCAwIGlmIHdlIGhhZCBmYWlsZWQgKHN1cGVyYmxvY2sgY29udGVudHMgd2FzIGFscmVhZHkgZGVhZCBvcgogKglkeWluZyB3aGVuIGdyYWJfc3VwZXIoKSBoYWQgYmVlbiBjYWxsZWQpLgogKi8Kc3RhdGljIGludCBncmFiX3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqcykKewoJcy0+c19jb3VudCsrOwoJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJZG93bl93cml0ZSgmcy0+c191bW91bnQpOwoJaWYgKHMtPnNfcm9vdCkgewoJCXNwaW5fbG9jaygmc2JfbG9jayk7CgkJaWYgKHMtPnNfY291bnQgPiBTX0JJQVMpIHsKCQkJYXRvbWljX2luYygmcy0+c19hY3RpdmUpOwoJCQlzLT5zX2NvdW50LS07CgkJCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCQkJcmV0dXJuIDE7CgkJfQoJCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCX0KCXVwX3dyaXRlKCZzLT5zX3Vtb3VudCk7CglwdXRfc3VwZXIocyk7Cgl5aWVsZCgpOwoJcmV0dXJuIDA7Cn0KCi8qKgogKglnZW5lcmljX3NodXRkb3duX3N1cGVyCS0JY29tbW9uIGhlbHBlciBmb3IgLT5raWxsX3NiKCkKICoJQHNiOiBzdXBlcmJsb2NrIHRvIGtpbGwKICoKICoJZ2VuZXJpY19zaHV0ZG93bl9zdXBlcigpIGRvZXMgYWxsIGZzLWluZGVwZW5kZW50IHdvcmsgb24gc3VwZXJibG9jawogKglzaHV0ZG93bi4gIFR5cGljYWwgLT5raWxsX3NiKCkgc2hvdWxkIHBpY2sgYWxsIGZzLXNwZWNpZmljIG9iamVjdHMKICoJdGhhdCBuZWVkIGRlc3RydWN0aW9uIG91dCBvZiBzdXBlcmJsb2NrLCBjYWxsIGdlbmVyaWNfc2h1dGRvd25fc3VwZXIoKQogKglhbmQgcmVsZWFzZSBhZm9yZW1lbnRpb25lZCBvYmplY3RzLiAgTm90ZTogZGVudHJpZXMgYW5kIGlub2RlcyBfYXJlXwogKgl0YWtlbiBjYXJlIG9mIGFuZCBkbyBub3QgbmVlZCBzcGVjaWZpYyBoYW5kbGluZy4KICovCnZvaWQgZ2VuZXJpY19zaHV0ZG93bl9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiKQp7CglzdHJ1Y3QgZGVudHJ5ICpyb290ID0gc2ItPnNfcm9vdDsKCXN0cnVjdCBzdXBlcl9vcGVyYXRpb25zICpzb3AgPSBzYi0+c19vcDsKCglpZiAocm9vdCkgewoJCXNiLT5zX3Jvb3QgPSBOVUxMOwoJCXNocmlua19kY2FjaGVfcGFyZW50KHJvb3QpOwoJCXNocmlua19kY2FjaGVfYW5vbigmc2ItPnNfYW5vbik7CgkJZHB1dChyb290KTsKCQlmc3luY19zdXBlcihzYik7CgkJbG9ja19zdXBlcihzYik7CgkJc2ItPnNfZmxhZ3MgJj0gfk1TX0FDVElWRTsKCQkvKiBiYWQgbmFtZSAtIGl0IHNob3VsZCBiZSBldmljdF9pbm9kZXMoKSAqLwoJCWludmFsaWRhdGVfaW5vZGVzKHNiKTsKCQlsb2NrX2tlcm5lbCgpOwoKCQlpZiAoc29wLT53cml0ZV9zdXBlciAmJiBzYi0+c19kaXJ0KQoJCQlzb3AtPndyaXRlX3N1cGVyKHNiKTsKCQlpZiAoc29wLT5wdXRfc3VwZXIpCgkJCXNvcC0+cHV0X3N1cGVyKHNiKTsKCgkJLyogRm9yZ2V0IGFueSByZW1haW5pbmcgaW5vZGVzICovCgkJaWYgKGludmFsaWRhdGVfaW5vZGVzKHNiKSkgewoJCQlwcmludGsoIlZGUzogQnVzeSBpbm9kZXMgYWZ0ZXIgdW5tb3VudCBvZiAlcy4gIgoJCQkgICAiU2VsZi1kZXN0cnVjdCBpbiA1IHNlY29uZHMuICBIYXZlIGEgbmljZSBkYXkuLi5cbiIsCgkJCSAgIHNiLT5zX2lkKTsKCQl9CgoJCXVubG9ja19rZXJuZWwoKTsKCQl1bmxvY2tfc3VwZXIoc2IpOwoJfQoJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCS8qIHNob3VsZCBiZSBpbml0aWFsaXplZCBmb3IgX19wdXRfc3VwZXJfYW5kX25lZWRfcmVzdGFydCgpICovCglsaXN0X2RlbF9pbml0KCZzYi0+c19saXN0KTsKCWxpc3RfZGVsKCZzYi0+c19pbnN0YW5jZXMpOwoJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJdXBfd3JpdGUoJnNiLT5zX3Vtb3VudCk7Cn0KCkVYUE9SVF9TWU1CT0woZ2VuZXJpY19zaHV0ZG93bl9zdXBlcik7CgovKioKICoJc2dldAktCWZpbmQgb3IgY3JlYXRlIGEgc3VwZXJibG9jawogKglAdHlwZToJZmlsZXN5c3RlbSB0eXBlIHN1cGVyYmxvY2sgc2hvdWxkIGJlbG9uZyB0bwogKglAdGVzdDoJY29tcGFyaXNvbiBjYWxsYmFjawogKglAc2V0OglzZXR1cCBjYWxsYmFjawogKglAZGF0YToJYXJndW1lbnQgdG8gZWFjaCBvZiB0aGVtCiAqLwpzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNnZXQoc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKnR5cGUsCgkJCWludCAoKnRlc3QpKHN0cnVjdCBzdXBlcl9ibG9jayAqLHZvaWQgKiksCgkJCWludCAoKnNldCkoc3RydWN0IHN1cGVyX2Jsb2NrICosdm9pZCAqKSwKCQkJdm9pZCAqZGF0YSkKewoJc3RydWN0IHN1cGVyX2Jsb2NrICpzID0gTlVMTDsKCXN0cnVjdCBsaXN0X2hlYWQgKnA7CglpbnQgZXJyOwoKcmV0cnk6CglzcGluX2xvY2soJnNiX2xvY2spOwoJaWYgKHRlc3QpIGxpc3RfZm9yX2VhY2gocCwgJnR5cGUtPmZzX3N1cGVycykgewoJCXN0cnVjdCBzdXBlcl9ibG9jayAqb2xkOwoJCW9sZCA9IGxpc3RfZW50cnkocCwgc3RydWN0IHN1cGVyX2Jsb2NrLCBzX2luc3RhbmNlcyk7CgkJaWYgKCF0ZXN0KG9sZCwgZGF0YSkpCgkJCWNvbnRpbnVlOwoJCWlmICghZ3JhYl9zdXBlcihvbGQpKQoJCQlnb3RvIHJldHJ5OwoJCWlmIChzKQoJCQlkZXN0cm95X3N1cGVyKHMpOwoJCXJldHVybiBvbGQ7Cgl9CglpZiAoIXMpIHsKCQlzcGluX3VubG9jaygmc2JfbG9jayk7CgkJcyA9IGFsbG9jX3N1cGVyKCk7CgkJaWYgKCFzKQoJCQlyZXR1cm4gRVJSX1BUUigtRU5PTUVNKTsKCQlnb3RvIHJldHJ5OwoJfQoJCQoJZXJyID0gc2V0KHMsIGRhdGEpOwoJaWYgKGVycikgewoJCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCQlkZXN0cm95X3N1cGVyKHMpOwoJCXJldHVybiBFUlJfUFRSKGVycik7Cgl9CglzLT5zX3R5cGUgPSB0eXBlOwoJc3RybGNweShzLT5zX2lkLCB0eXBlLT5uYW1lLCBzaXplb2Yocy0+c19pZCkpOwoJbGlzdF9hZGRfdGFpbCgmcy0+c19saXN0LCAmc3VwZXJfYmxvY2tzKTsKCWxpc3RfYWRkKCZzLT5zX2luc3RhbmNlcywgJnR5cGUtPmZzX3N1cGVycyk7CglzcGluX3VubG9jaygmc2JfbG9jayk7CglnZXRfZmlsZXN5c3RlbSh0eXBlKTsKCXJldHVybiBzOwp9CgpFWFBPUlRfU1lNQk9MKHNnZXQpOwoKdm9pZCBkcm9wX3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IpCnsKCXVwX3JlYWQoJnNiLT5zX3Vtb3VudCk7CglwdXRfc3VwZXIoc2IpOwp9CgpFWFBPUlRfU1lNQk9MKGRyb3Bfc3VwZXIpOwoKc3RhdGljIGlubGluZSB2b2lkIHdyaXRlX3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqc2IpCnsKCWxvY2tfc3VwZXIoc2IpOwoJaWYgKHNiLT5zX3Jvb3QgJiYgc2ItPnNfZGlydCkKCQlpZiAoc2ItPnNfb3AtPndyaXRlX3N1cGVyKQoJCQlzYi0+c19vcC0+d3JpdGVfc3VwZXIoc2IpOwoJdW5sb2NrX3N1cGVyKHNiKTsKfQoKLyoKICogTm90ZTogY2hlY2sgdGhlIGRpcnR5IGZsYWcgYmVmb3JlIHdhaXRpbmcsIHNvIHdlIGRvbid0CiAqIGhvbGQgdXAgdGhlIHN5bmMgd2hpbGUgbW91bnRpbmcgYSBkZXZpY2UuIChUaGUgbmV3bHkKICogbW91bnRlZCBkZXZpY2Ugd29uJ3QgbmVlZCBzeW5jaW5nLikKICovCnZvaWQgc3luY19zdXBlcnModm9pZCkKewoJc3RydWN0IHN1cGVyX2Jsb2NrICpzYjsKCglzcGluX2xvY2soJnNiX2xvY2spOwpyZXN0YXJ0OgoJbGlzdF9mb3JfZWFjaF9lbnRyeShzYiwgJnN1cGVyX2Jsb2Nrcywgc19saXN0KSB7CgkJaWYgKHNiLT5zX2RpcnQpIHsKCQkJc2ItPnNfY291bnQrKzsKCQkJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJCQlkb3duX3JlYWQoJnNiLT5zX3Vtb3VudCk7CgkJCXdyaXRlX3N1cGVyKHNiKTsKCQkJdXBfcmVhZCgmc2ItPnNfdW1vdW50KTsKCQkJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCQkJaWYgKF9fcHV0X3N1cGVyX2FuZF9uZWVkX3Jlc3RhcnQoc2IpKQoJCQkJZ290byByZXN0YXJ0OwoJCX0KCX0KCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKfQoKLyoKICogQ2FsbCB0aGUgLT5zeW5jX2ZzIHN1cGVyX29wIGFnYWluc3QgYWxsIGZpbGVzeXRlbXMgd2hpY2ggYXJlIHIvdyBhbmQKICogd2hpY2ggaW1wbGVtZW50IGl0LgogKgogKiBUaGlzIG9wZXJhdGlvbiBpcyBjYXJlZnVsIHRvIGF2b2lkIHRoZSBsaXZlbG9jayB3aGljaCBjb3VsZCBlYXNpbHkgaGFwcGVuCiAqIGlmIHR3byBvciBtb3JlIGZpbGVzeXN0ZW1zIGFyZSBiZWluZyBjb250aW51b3VzbHkgZGlydGllZC4gIHNfbmVlZF9zeW5jX2ZzCiAqIGlzIHVzZWQgb25seSBoZXJlLiAgV2Ugc2V0IGl0IGFnYWluc3QgYWxsIGZpbGVzeXN0ZW1zIGFuZCB0aGVuIGNsZWFyIGl0IGFzCiAqIHdlIHN5bmMgdGhlbS4gIFNvIHJlZGlydGllZCBmaWxlc3lzdGVtcyBhcmUgc2tpcHBlZC4KICoKICogQnV0IGlmIHByb2Nlc3MgQSBpcyBjdXJyZW50bHkgcnVubmluZyBzeW5jX2ZpbGVzeXRlbXMgYW5kIHRoZW4gcHJvY2VzcyBCCiAqIGNhbGxzIHN5bmNfZmlsZXN5c3RlbXMgYXMgd2VsbCwgcHJvY2VzcyBCIHdpbGwgc2V0IGFsbCB0aGUgc19uZWVkX3N5bmNfZnMKICogZmxhZ3MgYWdhaW4sIHdoaWNoIHdpbGwgY2F1c2UgcHJvY2VzcyBBIHRvIHJlc3luYyBldmVyeXRoaW5nLiAgRml4IHRoYXQgd2l0aAogKiBhIGxvY2FsIG11dGV4LgogKgogKiAoRmFiaWFuKSBBdm9pZCBzeW5jX2ZzIHdpdGggY2xlYW4gZnMgJiB3YWl0IG1vZGUgMAogKi8Kdm9pZCBzeW5jX2ZpbGVzeXN0ZW1zKGludCB3YWl0KQp7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiOwoJc3RhdGljIERFQ0xBUkVfTVVURVgobXV0ZXgpOwoKCWRvd24oJm11dGV4KTsJCS8qIENvdWxkIGJlIGRvd25faW50ZXJydXB0aWJsZSAqLwoJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoc2IsICZzdXBlcl9ibG9ja3MsIHNfbGlzdCkgewoJCWlmICghc2ItPnNfb3AtPnN5bmNfZnMpCgkJCWNvbnRpbnVlOwoJCWlmIChzYi0+c19mbGFncyAmIE1TX1JET05MWSkKCQkJY29udGludWU7CgkJc2ItPnNfbmVlZF9zeW5jX2ZzID0gMTsKCX0KCnJlc3RhcnQ6CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHNiLCAmc3VwZXJfYmxvY2tzLCBzX2xpc3QpIHsKCQlpZiAoIXNiLT5zX25lZWRfc3luY19mcykKCQkJY29udGludWU7CgkJc2ItPnNfbmVlZF9zeW5jX2ZzID0gMDsKCQlpZiAoc2ItPnNfZmxhZ3MgJiBNU19SRE9OTFkpCgkJCWNvbnRpbnVlOwkvKiBobS4gIFdhcyByZW1vdW50ZWQgci9vIG1lYW53aGlsZSAqLwoJCXNiLT5zX2NvdW50Kys7CgkJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJCWRvd25fcmVhZCgmc2ItPnNfdW1vdW50KTsKCQlpZiAoc2ItPnNfcm9vdCAmJiAod2FpdCB8fCBzYi0+c19kaXJ0KSkKCQkJc2ItPnNfb3AtPnN5bmNfZnMoc2IsIHdhaXQpOwoJCXVwX3JlYWQoJnNiLT5zX3Vtb3VudCk7CgkJLyogcmVzdGFydCBvbmx5IHdoZW4gc2IgaXMgbm8gbG9uZ2VyIG9uIHRoZSBsaXN0ICovCgkJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCQlpZiAoX19wdXRfc3VwZXJfYW5kX25lZWRfcmVzdGFydChzYikpCgkJCWdvdG8gcmVzdGFydDsKCX0KCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCXVwKCZtdXRleCk7Cn0KCi8qKgogKglnZXRfc3VwZXIgLSBnZXQgdGhlIHN1cGVyYmxvY2sgb2YgYSBkZXZpY2UKICoJQGJkZXY6IGRldmljZSB0byBnZXQgdGhlIHN1cGVyYmxvY2sgZm9yCiAqCQogKglTY2FucyB0aGUgc3VwZXJibG9jayBsaXN0IGFuZCBmaW5kcyB0aGUgc3VwZXJibG9jayBvZiB0aGUgZmlsZSBzeXN0ZW0KICoJbW91bnRlZCBvbiB0aGUgZGV2aWNlIGdpdmVuLiAlTlVMTCBpcyByZXR1cm5lZCBpZiBubyBtYXRjaCBpcyBmb3VuZC4KICovCgpzdHJ1Y3Qgc3VwZXJfYmxvY2sgKiBnZXRfc3VwZXIoc3RydWN0IGJsb2NrX2RldmljZSAqYmRldikKewoJc3RydWN0IHN1cGVyX2Jsb2NrICpzYjsKCglpZiAoIWJkZXYpCgkJcmV0dXJuIE5VTEw7CgoJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKcmVzY2FuOgoJbGlzdF9mb3JfZWFjaF9lbnRyeShzYiwgJnN1cGVyX2Jsb2Nrcywgc19saXN0KSB7CgkJaWYgKHNiLT5zX2JkZXYgPT0gYmRldikgewoJCQlzYi0+c19jb3VudCsrOwoJCQlzcGluX3VubG9jaygmc2JfbG9jayk7CgkJCWRvd25fcmVhZCgmc2ItPnNfdW1vdW50KTsKCQkJaWYgKHNiLT5zX3Jvb3QpCgkJCQlyZXR1cm4gc2I7CgkJCXVwX3JlYWQoJnNiLT5zX3Vtb3VudCk7CgkJCS8qIHJlc3RhcnQgb25seSB3aGVuIHNiIGlzIG5vIGxvbmdlciBvbiB0aGUgbGlzdCAqLwoJCQlzcGluX2xvY2soJnNiX2xvY2spOwoJCQlpZiAoX19wdXRfc3VwZXJfYW5kX25lZWRfcmVzdGFydChzYikpCgkJCQlnb3RvIHJlc2NhbjsKCQl9Cgl9CglzcGluX3VubG9jaygmc2JfbG9jayk7CglyZXR1cm4gTlVMTDsKfQoKRVhQT1JUX1NZTUJPTChnZXRfc3VwZXIpOwogCnN0cnVjdCBzdXBlcl9ibG9jayAqIHVzZXJfZ2V0X3N1cGVyKGRldl90IGRldikKewoJc3RydWN0IHN1cGVyX2Jsb2NrICpzYjsKCglzcGluX2xvY2soJnNiX2xvY2spOwpyZXNjYW46CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHNiLCAmc3VwZXJfYmxvY2tzLCBzX2xpc3QpIHsKCQlpZiAoc2ItPnNfZGV2ID09ICBkZXYpIHsKCQkJc2ItPnNfY291bnQrKzsKCQkJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJCQlkb3duX3JlYWQoJnNiLT5zX3Vtb3VudCk7CgkJCWlmIChzYi0+c19yb290KQoJCQkJcmV0dXJuIHNiOwoJCQl1cF9yZWFkKCZzYi0+c191bW91bnQpOwoJCQkvKiByZXN0YXJ0IG9ubHkgd2hlbiBzYiBpcyBubyBsb25nZXIgb24gdGhlIGxpc3QgKi8KCQkJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCQkJaWYgKF9fcHV0X3N1cGVyX2FuZF9uZWVkX3Jlc3RhcnQoc2IpKQoJCQkJZ290byByZXNjYW47CgkJfQoJfQoJc3Bpbl91bmxvY2soJnNiX2xvY2spOwoJcmV0dXJuIE5VTEw7Cn0KCmFzbWxpbmthZ2UgbG9uZyBzeXNfdXN0YXQodW5zaWduZWQgZGV2LCBzdHJ1Y3QgdXN0YXQgX191c2VyICogdWJ1ZikKewogICAgICAgIHN0cnVjdCBzdXBlcl9ibG9jayAqczsKICAgICAgICBzdHJ1Y3QgdXN0YXQgdG1wOwogICAgICAgIHN0cnVjdCBrc3RhdGZzIHNidWY7CglpbnQgZXJyID0gLUVJTlZBTDsKCiAgICAgICAgcyA9IHVzZXJfZ2V0X3N1cGVyKG5ld19kZWNvZGVfZGV2KGRldikpOwogICAgICAgIGlmIChzID09IE5VTEwpCiAgICAgICAgICAgICAgICBnb3RvIG91dDsKCWVyciA9IHZmc19zdGF0ZnMocywgJnNidWYpOwoJZHJvcF9zdXBlcihzKTsKCWlmIChlcnIpCgkJZ290byBvdXQ7CgogICAgICAgIG1lbXNldCgmdG1wLDAsc2l6ZW9mKHN0cnVjdCB1c3RhdCkpOwogICAgICAgIHRtcC5mX3RmcmVlID0gc2J1Zi5mX2JmcmVlOwogICAgICAgIHRtcC5mX3Rpbm9kZSA9IHNidWYuZl9mZnJlZTsKCiAgICAgICAgZXJyID0gY29weV90b191c2VyKHVidWYsJnRtcCxzaXplb2Yoc3RydWN0IHVzdGF0KSkgPyAtRUZBVUxUIDogMDsKb3V0OgoJcmV0dXJuIGVycjsKfQoKLyoqCiAqCW1hcmtfZmlsZXNfcm8KICoJQHNiOiBzdXBlcmJsb2NrIGluIHF1ZXN0aW9uCiAqCiAqCUFsbCBmaWxlcyBhcmUgbWFya2VkIHJlYWQvb25seS4gIFdlIGRvbid0IGNhcmUgYWJvdXQgcGVuZGluZwogKglkZWxldGUgZmlsZXMgc28gdGhpcyBzaG91bGQgYmUgdXNlZCBpbiAnZm9yY2UnIG1vZGUgb25seQogKi8KCnN0YXRpYyB2b2lkIG1hcmtfZmlsZXNfcm8oc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJc3RydWN0IGZpbGUgKmY7CgoJZmlsZV9saXN0X2xvY2soKTsKCWxpc3RfZm9yX2VhY2hfZW50cnkoZiwgJnNiLT5zX2ZpbGVzLCBmX3UuZnVfbGlzdCkgewoJCWlmIChTX0lTUkVHKGYtPmZfZGVudHJ5LT5kX2lub2RlLT5pX21vZGUpICYmIGZpbGVfY291bnQoZikpCgkJCWYtPmZfbW9kZSAmPSB+Rk1PREVfV1JJVEU7Cgl9CglmaWxlX2xpc3RfdW5sb2NrKCk7Cn0KCi8qKgogKglkb19yZW1vdW50X3NiIC0gYXNrcyBmaWxlc3lzdGVtIHRvIGNoYW5nZSBtb3VudCBvcHRpb25zLgogKglAc2I6CXN1cGVyYmxvY2sgaW4gcXVlc3Rpb24KICoJQGZsYWdzOgludW1lcmljIHBhcnQgb2Ygb3B0aW9ucwogKglAZGF0YToJdGhlIHJlc3Qgb2Ygb3B0aW9ucwogKiAgICAgIEBmb3JjZTogd2hldGhlciBvciBub3QgdG8gZm9yY2UgdGhlIGNoYW5nZQogKgogKglBbHRlcnMgdGhlIG1vdW50IG9wdGlvbnMgb2YgYSBtb3VudGVkIGZpbGUgc3lzdGVtLgogKi8KaW50IGRvX3JlbW91bnRfc2Ioc3RydWN0IHN1cGVyX2Jsb2NrICpzYiwgaW50IGZsYWdzLCB2b2lkICpkYXRhLCBpbnQgZm9yY2UpCnsKCWludCByZXR2YWw7CgkKCWlmICghKGZsYWdzICYgTVNfUkRPTkxZKSAmJiBiZGV2X3JlYWRfb25seShzYi0+c19iZGV2KSkKCQlyZXR1cm4gLUVBQ0NFUzsKCWlmIChmbGFncyAmIE1TX1JET05MWSkKCQlhY2N0X2F1dG9fY2xvc2Uoc2IpOwoJc2hyaW5rX2RjYWNoZV9zYihzYik7Cglmc3luY19zdXBlcihzYik7CgoJLyogSWYgd2UgYXJlIHJlbW91bnRpbmcgUkRPTkxZIGFuZCBjdXJyZW50IHNiIGlzIHJlYWQvd3JpdGUsCgkgICBtYWtlIHN1cmUgdGhlcmUgYXJlIG5vIHJ3IGZpbGVzIG9wZW5lZCAqLwoJaWYgKChmbGFncyAmIE1TX1JET05MWSkgJiYgIShzYi0+c19mbGFncyAmIE1TX1JET05MWSkpIHsKCQlpZiAoZm9yY2UpCgkJCW1hcmtfZmlsZXNfcm8oc2IpOwoJCWVsc2UgaWYgKCFmc19tYXlfcmVtb3VudF9ybyhzYikpCgkJCXJldHVybiAtRUJVU1k7Cgl9CgoJaWYgKHNiLT5zX29wLT5yZW1vdW50X2ZzKSB7CgkJbG9ja19zdXBlcihzYik7CgkJcmV0dmFsID0gc2ItPnNfb3AtPnJlbW91bnRfZnMoc2IsICZmbGFncywgZGF0YSk7CgkJdW5sb2NrX3N1cGVyKHNiKTsKCQlpZiAocmV0dmFsKQoJCQlyZXR1cm4gcmV0dmFsOwoJfQoJc2ItPnNfZmxhZ3MgPSAoc2ItPnNfZmxhZ3MgJiB+TVNfUk1UX01BU0spIHwgKGZsYWdzICYgTVNfUk1UX01BU0spOwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyB2b2lkIGRvX2VtZXJnZW5jeV9yZW1vdW50KHVuc2lnbmVkIGxvbmcgZm9vKQp7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiOwoKCXNwaW5fbG9jaygmc2JfbG9jayk7CglsaXN0X2Zvcl9lYWNoX2VudHJ5KHNiLCAmc3VwZXJfYmxvY2tzLCBzX2xpc3QpIHsKCQlzYi0+c19jb3VudCsrOwoJCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCQlkb3duX3JlYWQoJnNiLT5zX3Vtb3VudCk7CgkJaWYgKHNiLT5zX3Jvb3QgJiYgc2ItPnNfYmRldiAmJiAhKHNiLT5zX2ZsYWdzICYgTVNfUkRPTkxZKSkgewoJCQkvKgoJCQkgKiAtPnJlbW91bnRfZnMgbmVlZHMgbG9ja19rZXJuZWwoKS4KCQkJICoKCQkJICogV2hhdCBsb2NrIHByb3RlY3RzIHNiLT5zX2ZsYWdzPz8KCQkJICovCgkJCWxvY2tfa2VybmVsKCk7CgkJCWRvX3JlbW91bnRfc2Ioc2IsIE1TX1JET05MWSwgTlVMTCwgMSk7CgkJCXVubG9ja19rZXJuZWwoKTsKCQl9CgkJZHJvcF9zdXBlcihzYik7CgkJc3Bpbl9sb2NrKCZzYl9sb2NrKTsKCX0KCXNwaW5fdW5sb2NrKCZzYl9sb2NrKTsKCXByaW50aygiRW1lcmdlbmN5IFJlbW91bnQgY29tcGxldGVcbiIpOwp9Cgp2b2lkIGVtZXJnZW5jeV9yZW1vdW50KHZvaWQpCnsKCXBkZmx1c2hfb3BlcmF0aW9uKGRvX2VtZXJnZW5jeV9yZW1vdW50LCAwKTsKfQoKLyoKICogVW5uYW1lZCBibG9jayBkZXZpY2VzIGFyZSBkdW1teSBkZXZpY2VzIHVzZWQgYnkgdmlydHVhbAogKiBmaWxlc3lzdGVtcyB3aGljaCBkb24ndCB1c2UgcmVhbCBibG9jay1kZXZpY2VzLiAgLS0ganJzCiAqLwoKc3RhdGljIHN0cnVjdCBpZHIgdW5uYW1lZF9kZXZfaWRyOwpzdGF0aWMgREVGSU5FX1NQSU5MT0NLKHVubmFtZWRfZGV2X2xvY2spOy8qIHByb3RlY3RzIHRoZSBhYm92ZSAqLwoKaW50IHNldF9hbm9uX3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqcywgdm9pZCAqZGF0YSkKewoJaW50IGRldjsKCWludCBlcnJvcjsKCiByZXRyeToKCWlmIChpZHJfcHJlX2dldCgmdW5uYW1lZF9kZXZfaWRyLCBHRlBfQVRPTUlDKSA9PSAwKQoJCXJldHVybiAtRU5PTUVNOwoJc3Bpbl9sb2NrKCZ1bm5hbWVkX2Rldl9sb2NrKTsKCWVycm9yID0gaWRyX2dldF9uZXcoJnVubmFtZWRfZGV2X2lkciwgTlVMTCwgJmRldik7CglzcGluX3VubG9jaygmdW5uYW1lZF9kZXZfbG9jayk7CglpZiAoZXJyb3IgPT0gLUVBR0FJTikKCQkvKiBXZSByYWNlZCBhbmQgbG9zdCB3aXRoIGFub3RoZXIgQ1BVLiAqLwoJCWdvdG8gcmV0cnk7CgllbHNlIGlmIChlcnJvcikKCQlyZXR1cm4gLUVBR0FJTjsKCglpZiAoKGRldiAmIE1BWF9JRF9NQVNLKSA9PSAoMSA8PCBNSU5PUkJJVFMpKSB7CgkJc3Bpbl9sb2NrKCZ1bm5hbWVkX2Rldl9sb2NrKTsKCQlpZHJfcmVtb3ZlKCZ1bm5hbWVkX2Rldl9pZHIsIGRldik7CgkJc3Bpbl91bmxvY2soJnVubmFtZWRfZGV2X2xvY2spOwoJCXJldHVybiAtRU1GSUxFOwoJfQoJcy0+c19kZXYgPSBNS0RFVigwLCBkZXYgJiBNSU5PUk1BU0spOwoJcmV0dXJuIDA7Cn0KCkVYUE9SVF9TWU1CT0woc2V0X2Fub25fc3VwZXIpOwoKdm9pZCBraWxsX2Fub25fc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJaW50IHNsb3QgPSBNSU5PUihzYi0+c19kZXYpOwoKCWdlbmVyaWNfc2h1dGRvd25fc3VwZXIoc2IpOwoJc3Bpbl9sb2NrKCZ1bm5hbWVkX2Rldl9sb2NrKTsKCWlkcl9yZW1vdmUoJnVubmFtZWRfZGV2X2lkciwgc2xvdCk7CglzcGluX3VubG9jaygmdW5uYW1lZF9kZXZfbG9jayk7Cn0KCkVYUE9SVF9TWU1CT0woa2lsbF9hbm9uX3N1cGVyKTsKCnZvaWQgX19pbml0IHVubmFtZWRfZGV2X2luaXQodm9pZCkKewoJaWRyX2luaXQoJnVubmFtZWRfZGV2X2lkcik7Cn0KCnZvaWQga2lsbF9saXR0ZXJfc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJaWYgKHNiLT5zX3Jvb3QpCgkJZF9nZW5vY2lkZShzYi0+c19yb290KTsKCWtpbGxfYW5vbl9zdXBlcihzYik7Cn0KCkVYUE9SVF9TWU1CT0woa2lsbF9saXR0ZXJfc3VwZXIpOwoKc3RhdGljIGludCBzZXRfYmRldl9zdXBlcihzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnMsIHZvaWQgKmRhdGEpCnsKCXMtPnNfYmRldiA9IGRhdGE7CglzLT5zX2RldiA9IHMtPnNfYmRldi0+YmRfZGV2OwoJcmV0dXJuIDA7Cn0KCnN0YXRpYyBpbnQgdGVzdF9iZGV2X3N1cGVyKHN0cnVjdCBzdXBlcl9ibG9jayAqcywgdm9pZCAqZGF0YSkKewoJcmV0dXJuICh2b2lkICopcy0+c19iZGV2ID09IGRhdGE7Cn0KCnN0YXRpYyB2b2lkIGJkZXZfdWV2ZW50KHN0cnVjdCBibG9ja19kZXZpY2UgKmJkZXYsIGVudW0ga29iamVjdF9hY3Rpb24gYWN0aW9uKQp7CglpZiAoYmRldi0+YmRfZGlzaykgewoJCWlmIChiZGV2LT5iZF9wYXJ0KQoJCQlrb2JqZWN0X3VldmVudCgmYmRldi0+YmRfcGFydC0+a29iaiwgYWN0aW9uKTsKCQllbHNlCgkJCWtvYmplY3RfdWV2ZW50KCZiZGV2LT5iZF9kaXNrLT5rb2JqLCBhY3Rpb24pOwoJfQp9CgpzdHJ1Y3Qgc3VwZXJfYmxvY2sgKmdldF9zYl9iZGV2KHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmc190eXBlLAoJaW50IGZsYWdzLCBjb25zdCBjaGFyICpkZXZfbmFtZSwgdm9pZCAqZGF0YSwKCWludCAoKmZpbGxfc3VwZXIpKHN0cnVjdCBzdXBlcl9ibG9jayAqLCB2b2lkICosIGludCkpCnsKCXN0cnVjdCBibG9ja19kZXZpY2UgKmJkZXY7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnM7CglpbnQgZXJyb3IgPSAwOwoKCWJkZXYgPSBvcGVuX2JkZXZfZXhjbChkZXZfbmFtZSwgZmxhZ3MsIGZzX3R5cGUpOwoJaWYgKElTX0VSUihiZGV2KSkKCQlyZXR1cm4gKHN0cnVjdCBzdXBlcl9ibG9jayAqKWJkZXY7CgoJLyoKCSAqIG9uY2UgdGhlIHN1cGVyIGlzIGluc2VydGVkIGludG8gdGhlIGxpc3QgYnkgc2dldCwgc191bW91bnQKCSAqIHdpbGwgcHJvdGVjdCB0aGUgbG9ja2ZzIGNvZGUgZnJvbSB0cnlpbmcgdG8gc3RhcnQgYSBzbmFwc2hvdAoJICogd2hpbGUgd2UgYXJlIG1vdW50aW5nCgkgKi8KCWRvd24oJmJkZXYtPmJkX21vdW50X3NlbSk7CglzID0gc2dldChmc190eXBlLCB0ZXN0X2JkZXZfc3VwZXIsIHNldF9iZGV2X3N1cGVyLCBiZGV2KTsKCXVwKCZiZGV2LT5iZF9tb3VudF9zZW0pOwoJaWYgKElTX0VSUihzKSkKCQlnb3RvIG91dDsKCglpZiAocy0+c19yb290KSB7CgkJaWYgKChmbGFncyBeIHMtPnNfZmxhZ3MpICYgTVNfUkRPTkxZKSB7CgkJCXVwX3dyaXRlKCZzLT5zX3Vtb3VudCk7CgkJCWRlYWN0aXZhdGVfc3VwZXIocyk7CgkJCXMgPSBFUlJfUFRSKC1FQlVTWSk7CgkJfQoJCWdvdG8gb3V0OwoJfSBlbHNlIHsKCQljaGFyIGJbQkRFVk5BTUVfU0laRV07CgoJCXMtPnNfZmxhZ3MgPSBmbGFnczsKCQlzdHJsY3B5KHMtPnNfaWQsIGJkZXZuYW1lKGJkZXYsIGIpLCBzaXplb2Yocy0+c19pZCkpOwoJCXNiX3NldF9ibG9ja3NpemUocywgYmxvY2tfc2l6ZShiZGV2KSk7CgkJZXJyb3IgPSBmaWxsX3N1cGVyKHMsIGRhdGEsIGZsYWdzICYgTVNfVkVSQk9TRSA/IDEgOiAwKTsKCQlpZiAoZXJyb3IpIHsKCQkJdXBfd3JpdGUoJnMtPnNfdW1vdW50KTsKCQkJZGVhY3RpdmF0ZV9zdXBlcihzKTsKCQkJcyA9IEVSUl9QVFIoZXJyb3IpOwoJCX0gZWxzZSB7CgkJCXMtPnNfZmxhZ3MgfD0gTVNfQUNUSVZFOwoJCQliZGV2X3VldmVudChiZGV2LCBLT0JKX01PVU5UKTsKCQl9Cgl9CgoJcmV0dXJuIHM7CgpvdXQ6CgljbG9zZV9iZGV2X2V4Y2woYmRldik7CglyZXR1cm4gczsKfQoKRVhQT1JUX1NZTUJPTChnZXRfc2JfYmRldik7Cgp2b2lkIGtpbGxfYmxvY2tfc3VwZXIoc3RydWN0IHN1cGVyX2Jsb2NrICpzYikKewoJc3RydWN0IGJsb2NrX2RldmljZSAqYmRldiA9IHNiLT5zX2JkZXY7CgoJYmRldl91ZXZlbnQoYmRldiwgS09CSl9VTU9VTlQpOwoJZ2VuZXJpY19zaHV0ZG93bl9zdXBlcihzYik7CglzeW5jX2Jsb2NrZGV2KGJkZXYpOwoJY2xvc2VfYmRldl9leGNsKGJkZXYpOwp9CgpFWFBPUlRfU1lNQk9MKGtpbGxfYmxvY2tfc3VwZXIpOwoKc3RydWN0IHN1cGVyX2Jsb2NrICpnZXRfc2Jfbm9kZXYoc3RydWN0IGZpbGVfc3lzdGVtX3R5cGUgKmZzX3R5cGUsCglpbnQgZmxhZ3MsIHZvaWQgKmRhdGEsCglpbnQgKCpmaWxsX3N1cGVyKShzdHJ1Y3Qgc3VwZXJfYmxvY2sgKiwgdm9pZCAqLCBpbnQpKQp7CglpbnQgZXJyb3I7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnMgPSBzZ2V0KGZzX3R5cGUsIE5VTEwsIHNldF9hbm9uX3N1cGVyLCBOVUxMKTsKCglpZiAoSVNfRVJSKHMpKQoJCXJldHVybiBzOwoKCXMtPnNfZmxhZ3MgPSBmbGFnczsKCgllcnJvciA9IGZpbGxfc3VwZXIocywgZGF0YSwgZmxhZ3MgJiBNU19WRVJCT1NFID8gMSA6IDApOwoJaWYgKGVycm9yKSB7CgkJdXBfd3JpdGUoJnMtPnNfdW1vdW50KTsKCQlkZWFjdGl2YXRlX3N1cGVyKHMpOwoJCXJldHVybiBFUlJfUFRSKGVycm9yKTsKCX0KCXMtPnNfZmxhZ3MgfD0gTVNfQUNUSVZFOwoJcmV0dXJuIHM7Cn0KCkVYUE9SVF9TWU1CT0woZ2V0X3NiX25vZGV2KTsKCnN0YXRpYyBpbnQgY29tcGFyZV9zaW5nbGUoc3RydWN0IHN1cGVyX2Jsb2NrICpzLCB2b2lkICpwKQp7CglyZXR1cm4gMTsKfQoKc3RydWN0IHN1cGVyX2Jsb2NrICpnZXRfc2Jfc2luZ2xlKHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICpmc190eXBlLAoJaW50IGZsYWdzLCB2b2lkICpkYXRhLAoJaW50ICgqZmlsbF9zdXBlcikoc3RydWN0IHN1cGVyX2Jsb2NrICosIHZvaWQgKiwgaW50KSkKewoJc3RydWN0IHN1cGVyX2Jsb2NrICpzOwoJaW50IGVycm9yOwoKCXMgPSBzZ2V0KGZzX3R5cGUsIGNvbXBhcmVfc2luZ2xlLCBzZXRfYW5vbl9zdXBlciwgTlVMTCk7CglpZiAoSVNfRVJSKHMpKQoJCXJldHVybiBzOwoJaWYgKCFzLT5zX3Jvb3QpIHsKCQlzLT5zX2ZsYWdzID0gZmxhZ3M7CgkJZXJyb3IgPSBmaWxsX3N1cGVyKHMsIGRhdGEsIGZsYWdzICYgTVNfVkVSQk9TRSA/IDEgOiAwKTsKCQlpZiAoZXJyb3IpIHsKCQkJdXBfd3JpdGUoJnMtPnNfdW1vdW50KTsKCQkJZGVhY3RpdmF0ZV9zdXBlcihzKTsKCQkJcmV0dXJuIEVSUl9QVFIoZXJyb3IpOwoJCX0KCQlzLT5zX2ZsYWdzIHw9IE1TX0FDVElWRTsKCX0KCWRvX3JlbW91bnRfc2IocywgZmxhZ3MsIGRhdGEsIDApOwoJcmV0dXJuIHM7Cn0KCkVYUE9SVF9TWU1CT0woZ2V0X3NiX3NpbmdsZSk7CgpzdHJ1Y3QgdmZzbW91bnQgKgpkb19rZXJuX21vdW50KGNvbnN0IGNoYXIgKmZzdHlwZSwgaW50IGZsYWdzLCBjb25zdCBjaGFyICpuYW1lLCB2b2lkICpkYXRhKQp7CglzdHJ1Y3QgZmlsZV9zeXN0ZW1fdHlwZSAqdHlwZSA9IGdldF9mc190eXBlKGZzdHlwZSk7CglzdHJ1Y3Qgc3VwZXJfYmxvY2sgKnNiID0gRVJSX1BUUigtRU5PTUVNKTsKCXN0cnVjdCB2ZnNtb3VudCAqbW50OwoJaW50IGVycm9yOwoJY2hhciAqc2VjZGF0YSA9IE5VTEw7CgoJaWYgKCF0eXBlKQoJCXJldHVybiBFUlJfUFRSKC1FTk9ERVYpOwoKCW1udCA9IGFsbG9jX3Zmc21udChuYW1lKTsKCWlmICghbW50KQoJCWdvdG8gb3V0OwoKCWlmIChkYXRhKSB7CgkJc2VjZGF0YSA9IGFsbG9jX3NlY2RhdGEoKTsKCQlpZiAoIXNlY2RhdGEpIHsKCQkJc2IgPSBFUlJfUFRSKC1FTk9NRU0pOwoJCQlnb3RvIG91dF9tbnQ7CgkJfQoKCQllcnJvciA9IHNlY3VyaXR5X3NiX2NvcHlfZGF0YSh0eXBlLCBkYXRhLCBzZWNkYXRhKTsKCQlpZiAoZXJyb3IpIHsKCQkJc2IgPSBFUlJfUFRSKGVycm9yKTsKCQkJZ290byBvdXRfZnJlZV9zZWNkYXRhOwoJCX0KCX0KCglzYiA9IHR5cGUtPmdldF9zYih0eXBlLCBmbGFncywgbmFtZSwgZGF0YSk7CglpZiAoSVNfRVJSKHNiKSkKCQlnb3RvIG91dF9mcmVlX3NlY2RhdGE7CiAJZXJyb3IgPSBzZWN1cml0eV9zYl9rZXJuX21vdW50KHNiLCBzZWNkYXRhKTsKIAlpZiAoZXJyb3IpCiAJCWdvdG8gb3V0X3NiOwoJbW50LT5tbnRfc2IgPSBzYjsKCW1udC0+bW50X3Jvb3QgPSBkZ2V0KHNiLT5zX3Jvb3QpOwoJbW50LT5tbnRfbW91bnRwb2ludCA9IHNiLT5zX3Jvb3Q7CgltbnQtPm1udF9wYXJlbnQgPSBtbnQ7Cgl1cF93cml0ZSgmc2ItPnNfdW1vdW50KTsKCWZyZWVfc2VjZGF0YShzZWNkYXRhKTsKCXB1dF9maWxlc3lzdGVtKHR5cGUpOwoJcmV0dXJuIG1udDsKb3V0X3NiOgoJdXBfd3JpdGUoJnNiLT5zX3Vtb3VudCk7CglkZWFjdGl2YXRlX3N1cGVyKHNiKTsKCXNiID0gRVJSX1BUUihlcnJvcik7Cm91dF9mcmVlX3NlY2RhdGE6CglmcmVlX3NlY2RhdGEoc2VjZGF0YSk7Cm91dF9tbnQ6CglmcmVlX3Zmc21udChtbnQpOwpvdXQ6CglwdXRfZmlsZXN5c3RlbSh0eXBlKTsKCXJldHVybiAoc3RydWN0IHZmc21vdW50ICopc2I7Cn0KCkVYUE9SVF9TWU1CT0xfR1BMKGRvX2tlcm5fbW91bnQpOwoKc3RydWN0IHZmc21vdW50ICprZXJuX21vdW50KHN0cnVjdCBmaWxlX3N5c3RlbV90eXBlICp0eXBlKQp7CglyZXR1cm4gZG9fa2Vybl9tb3VudCh0eXBlLT5uYW1lLCAwLCB0eXBlLT5uYW1lLCBOVUxMKTsKfQoKRVhQT1JUX1NZTUJPTChrZXJuX21vdW50KTsK