LyoKICogbGludXgvZHJpdmVycy9pZGUvaWRlLWNkLmMKICoKICogQ29weXJpZ2h0IChDKSAxOTk0LCAxOTk1LCAxOTk2ICBzY290dCBzbnlkZXIgIDxzbnlkZXJAZm5hbGQwLmZuYWwuZ292PgogKiBDb3B5cmlnaHQgKEMpIDE5OTYtMTk5OCAgRXJpayBBbmRlcnNlbiA8YW5kZXJzZWVAZGViaWFuLm9yZz4KICogQ29weXJpZ2h0IChDKSAxOTk4LTIwMDAgIEplbnMgQXhib2UgPGF4Ym9lQHN1c2UuZGU+CiAqCiAqIE1heSBiZSBjb3BpZWQgb3IgbW9kaWZpZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZS4gIFNlZSBsaW51eC9DT1BZSU5HIGZvciBtb3JlIGluZm9ybWF0aW9uLgogKgogKiBBVEFQSSBDRC1ST00gZHJpdmVyLiAgVG8gYmUgdXNlZCB3aXRoIGlkZS5jLgogKiBTZWUgRG9jdW1lbnRhdGlvbi9jZHJvbS9pZGUtY2QgZm9yIHVzYWdlIGluZm9ybWF0aW9uLgogKgogKiBTdWdnZXN0aW9ucyBhcmUgd2VsY29tZS4gUGF0Y2hlcyB0aGF0IHdvcmsgYXJlIG1vcmUgd2VsY29tZSB0aG91Z2guIDstKQogKiBGb3IgdGhvc2Ugd2lzaGluZyB0byB3b3JrIG9uIHRoaXMgZHJpdmVyLCBwbGVhc2UgYmUgc3VyZSB5b3UgZG93bmxvYWQKICogYW5kIGNvbXBseSB3aXRoIHRoZSBsYXRlc3QgTXQuIEZ1amkgKFNGRjgwOTAgdmVyc2lvbiA0KSBhbmQgQVRBUEkgCiAqIChTRkYtODAyMGkgcmV2IDIuNikgc3RhbmRhcmRzLiBUaGVzZSBkb2N1bWVudHMgY2FuIGJlIG9idGFpbmVkIGJ5IAogKiBhbm9ueW1vdXMgZnRwIGZyb206CiAqIGZ0cDovL2Zpc3Npb24uZHQud2RjLmNvbS9wdWIvc3RhbmRhcmRzL1NGRl9hdGFwaS9zcGVjL1NGRjgwMjAtcjIuNi9QUy84MDIwcjI2LnBzCiAqIGZ0cDovL2Z0cC5hdmMtcGlvbmVlci5jb20vTXRmdWppNC9TcGVjL0Z1amk0cjEwLnBkZgogKgogKiBEcml2ZXMgdGhhdCBkZXZpYXRlIGZyb20gdGhlc2Ugc3RhbmRhcmRzIHdpbGwgYmUgYWNjb21tb2RhdGVkIGFzIG11Y2gKICogYXMgcG9zc2libGUgdmlhIGNvbXBpbGUgdGltZSBvciBjb21tYW5kLWxpbmUgb3B0aW9ucy4gIFNpbmNlIEkgb25seSBoYXZlCiAqIGEgZmV3IGRyaXZlcywgeW91IGdlbmVyYWxseSBuZWVkIHRvIHNlbmQgbWUgcGF0Y2hlcy4uLgogKgogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIFRPIERPIExJU1Q6CiAqIC1NYWtlIGl0IHNvIHRoYXQgUGlvbmVlciBDRCBEUi1BMjRYIGFuZCBmcmllbmRzIGRvbid0IGdldCBzY3Jld2VkIHVwIG9uCiAqICAgYm9vdAogKgogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIDEuMDAgIE9jdCAzMSwgMTk5NCAtLSBJbml0aWFsIHZlcnNpb24uCiAqIDEuMDEgIE5vdiAgMiwgMTk5NCAtLSBGaXhlZCBwcm9ibGVtIHdpdGggc3RhcnRpbmcgcmVxdWVzdCBpbgogKiAgICAgICAgICAgICAgICAgICAgICAgY2Ryb21fY2hlY2tfc3RhdHVzLgogKiAxLjAzICBOb3YgMjUsIDE5OTQgLS0gbGVhdmluZyB1bm1hc2tfaW50cltdIGFzIGEgdXNlci1zZXR0aW5nIChhcyBmb3IgZGlza3MpCiAqIChmcm9tIG1sb3JkKSAgICAgICAtLSBtaW5vciBjaGFuZ2VzIHRvIGNkcm9tX3NldHVwKCkKICogICAgICAgICAgICAgICAgICAgIC0tIHJlbmFtZWQgaWRlX2Rldl9zIHRvIGlkZV9kcml2ZV90LCBlbmFibGUgaXJxIG9uIGNvbW1hbmQKICogMi4wMCAgTm92IDI3LCAxOTk0IC0tIEdlbmVyYWxpemUgcGFja2V0IGNvbW1hbmQgaW50ZXJmYWNlOwogKiAgICAgICAgICAgICAgICAgICAgICAgYWRkIGF1ZGlvIGlvY3Rscy4KICogMi4wMSAgRGVjICAzLCAxOTk0IC0tIFJld29yayBwYWNrZXQgY29tbWFuZCBpbnRlcmZhY2UgdG8gaGFuZGxlIGRldmljZXMKICogICAgICAgICAgICAgICAgICAgICAgIHdoaWNoIHNlbmQgYW4gaW50ZXJydXB0IHdoZW4gcmVhZHkgZm9yIGEgY29tbWFuZC4KICogMi4wMiAgRGVjIDExLCAxOTk0IC0tIENhY2hlIHRoZSBUT0MgaW4gdGhlIGRyaXZlci4KICogICAgICAgICAgICAgICAgICAgICAgIERvbid0IHVzZSBTQ01EX1BMQVlBVURJT19USTsgaXQncyBub3QgaW5jbHVkZWQKICogICAgICAgICAgICAgICAgICAgICAgIGluIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgQVRBUEkuCiAqICAgICAgICAgICAgICAgICAgICAgICBUcnkgdG8gdXNlIExCQSBpbnN0ZWFkIG9mIHRyYWNrIG9yIE1TRiBhZGRyZXNzaW5nCiAqICAgICAgICAgICAgICAgICAgICAgICB3aGVuIHBvc3NpYmxlLgogKiAgICAgICAgICAgICAgICAgICAgICAgRG9uJ3Qgd2FpdCBmb3IgUkVBRFlfU1RBVC4KICogMi4wMyAgSmFuIDEwLCAxOTk1IC0tIFJld3JpdGUgYmxvY2sgcmVhZCByb3V0aW5lcyB0byBoYW5kbGUgYmxvY2sgc2l6ZXMKICogICAgICAgICAgICAgICAgICAgICAgIG90aGVyIHRoYW4gMmsgYW5kIHRvIG1vdmUgbXVsdGlwbGUgc2VjdG9ycyBpbiBhCiAqICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGUgdHJhbnNhY3Rpb24uCiAqIDIuMDQgIEFwciAyMSwgMTk5NSAtLSBBZGQgd29yay1hcm91bmQgZm9yIENyZWF0aXZlIExhYnMgQ0QyMjBFIGRyaXZlcy4KICogICAgICAgICAgICAgICAgICAgICAgIFRoYW5rcyB0byBOaWNrIFNhdyA8Y3dzYXdAcHRzNy5wdHMubW90LmNvbT4gZm9yCiAqICAgICAgICAgICAgICAgICAgICAgICBoZWxwIGluIGZpZ3VyaW5nIHRoaXMgb3V0LiAgRGl0dG8gZm9yIEFjZXIgYW5kCiAqICAgICAgICAgICAgICAgICAgICAgICBBenRlY2ggZHJpdmVzLCB3aGljaCBzZWVtIHRvIGhhdmUgdGhlIHNhbWUgcHJvYmxlbS4KICogMi4wNGIgTWF5IDMwLCAxOTk1IC0tIEZpeCB0byBtYXRjaCBjaGFuZ2VzIGluIGlkZS5jIHZlcnNpb24gMy4xNiAtbWwKICogMi4wNSAgSnVuICA4LCAxOTk1IC0tIERvbid0IGF0dGVtcHQgdG8gcmV0cnkgYWZ0ZXIgYW4gaWxsZWdhbCByZXF1ZXN0CiAqICAgICAgICAgICAgICAgICAgICAgICAgb3IgZGF0YSBwcm90ZWN0IGVycm9yLgogKiAgICAgICAgICAgICAgICAgICAgICAgVXNlIEhXSUYgYW5kIERFVl9IV0lGIG1hY3JvcyBhcyBpbiBpZGUuYy4KICogICAgICAgICAgICAgICAgICAgICAgIEFsd2F5cyB0cnkgdG8gZG8gYSByZXF1ZXN0X3NlbnNlIGFmdGVyCiAqICAgICAgICAgICAgICAgICAgICAgICAgYSBmYWlsZWQgY29tbWFuZC4KICogICAgICAgICAgICAgICAgICAgICAgIEluY2x1ZGUgYW4gb3B0aW9uIHRvIGdpdmUgdGV4dHVhbCBkZXNjcmlwdGlvbnMKICogICAgICAgICAgICAgICAgICAgICAgICBvZiBBVEFQSSBlcnJvcnMuCiAqICAgICAgICAgICAgICAgICAgICAgICBGaXggYSBidWcgaW4gaGFuZGxpbmcgdGhlIHNlY3RvciBjYWNoZSB3aGljaAogKiAgICAgICAgICAgICAgICAgICAgICAgIHNob3dlZCB1cCBpZiB0aGUgZHJpdmUgcmV0dXJuZWQgZGF0YSBpbiA1MTIgYnl0ZQogKiAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrcyAobGlrZSBQaW9uZWVyIGRyaXZlcykuICBUaGFua3MgdG8KICogICAgICAgICAgICAgICAgICAgICAgICBSaWNoYXJkIEhpcnN0IDxzcmhAZ3B0LmNvLnVrPiBmb3IgZGlhZ25vc2luZyB0aGlzLgogKiAgICAgICAgICAgICAgICAgICAgICAgUHJvcGVybHkgc3VwcGx5IHRoZSBwYWdlIG51bWJlciBmaWVsZCBpbiB0aGUKICogICAgICAgICAgICAgICAgICAgICAgICBNT0RFX1NFTEVDVCBjb21tYW5kLgogKiAgICAgICAgICAgICAgICAgICAgICAgUExBWUFVRElPMTIgaXMgYnJva2VuIG9uIHRoZSBBenRlY2g7IHdvcmsgYXJvdW5kIGl0LgogKiAyLjA1eCBBdWcgMTEsIDE5OTUgLS0gbG90cyBvZiBkYXRhIHN0cnVjdHVyZSByZW5hbWluZy9yZXN0cnVjdHVyaW5nIGluIGlkZS5jCiAqICAgICAgICAgICAgICAgICAgICAgICAobXkgYXBvbG9naWVzIHRvIFNjb3R0LCBidXQgbm93IGlkZS1jZC5jIGlzIGluZGVwZW5kZW50KQogKiAzLjAwICBBdWcgMjIsIDE5OTUgLS0gSW1wbGVtZW50IENEUk9NTVVMVElTRVNTSU9OIGlvY3RsLgogKiAgICAgICAgICAgICAgICAgICAgICAgSW1wbGVtZW50IENEUk9NUkVBREFVRElPIGlvY3RsIChVTlRFU1RFRCkuCiAqICAgICAgICAgICAgICAgICAgICAgICBVc2UgaW5wdXRfaWRlX2RhdGEoKSBhbmQgb3V0cHV0X2lkZV9kYXRhKCkuCiAqICAgICAgICAgICAgICAgICAgICAgICBBZGQgZG9vciBsb2NraW5nLgogKiAgICAgICAgICAgICAgICAgICAgICAgRml4IHVzYWdlIGNvdW50IGxlYWsgaW4gY2Ryb21fb3Blbiwgd2hpY2ggaGFwcGVuZWQKICogICAgICAgICAgICAgICAgICAgICAgICB3aGVuIGEgcmVhZC13cml0ZSBtb3VudCB3YXMgYXR0ZW1wdGVkLgogKiAgICAgICAgICAgICAgICAgICAgICAgVHJ5IHRvIGxvYWQgdGhlIGRpc2sgb24gb3Blbi4KICogICAgICAgICAgICAgICAgICAgICAgIEltcGxlbWVudCBDRFJPTUVKRUNUX1NXIGlvY3RsIChvZmYgYnkgZGVmYXVsdCkuCiAqICAgICAgICAgICAgICAgICAgICAgICBSZWFkIHRvdGFsIGNkcm9tIGNhcGFjaXR5IGR1cmluZyBvcGVuLgogKiAgICAgICAgICAgICAgICAgICAgICAgUmVhcnJhbmdlIGxvZ2ljIGluIGNkcm9tX2RlY29kZV9zdGF0dXMuICBJc3N1ZQogKiAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3Qgc2Vuc2UgY29tbWFuZHMgZm9yIGZhaWxlZCBwYWNrZXQgY29tbWFuZHMKICogICAgICAgICAgICAgICAgICAgICAgICBmcm9tIGhlcmUgaW5zdGVhZCBvZiBmcm9tIGNkcm9tX3F1ZXVlX3BhY2tldF9jb21tYW5kLgogKiAgICAgICAgICAgICAgICAgICAgICAgIEZpeCBhIHJhY2UgY29uZGl0aW9uIGluIHJldHJpZXZpbmcgZXJyb3IgaW5mb3JtYXRpb24uCiAqICAgICAgICAgICAgICAgICAgICAgICBTdXBwcmVzcyBwcmludGluZyBub3JtYWwgdW5pdCBhdHRlbnRpb24gZXJyb3JzIGFuZAogKiAgICAgICAgICAgICAgICAgICAgICAgIHNvbWUgZHJpdmUgbm90IHJlYWR5IGVycm9ycy4KICogICAgICAgICAgICAgICAgICAgICAgIEltcGxlbWVudCBDRFJPTVZPTFJFQUQgaW9jdGwuCiAqICAgICAgICAgICAgICAgICAgICAgICBJbXBsZW1lbnQgQ0RST01SRUFETU9ERTEvMiBpb2N0bHMuCiAqICAgICAgICAgICAgICAgICAgICAgICBGaXggcmFjZSBjb25kaXRpb24gaW4gc2V0dGluZyB1cCBpbnRlcnJ1cHQgaGFuZGxlcnMKICogICAgICAgICAgICAgICAgICAgICAgICB3aGVuIHRoZSBgc2VyaWFsaXplJyBvcHRpb24gaXMgdXNlZC4KICogMy4wMSAgU2VwICAyLCAxOTk1IC0tIEZpeCBvcmRlcmluZyBvZiByZWVuYWJsaW5nIGludGVycnVwdHMgaW4KICogICAgICAgICAgICAgICAgICAgICAgICBjZHJvbV9xdWV1ZV9yZXF1ZXN0LgogKiAgICAgICAgICAgICAgICAgICAgICAgQW5vdGhlciB0cnkgYXQgdXNpbmcgaWRlX1tpbnB1dCxvdXRwdXRdX2RhdGEuCiAqIDMuMDIgIFNlcCAxNiwgMTk5NSAtLSBTdGljayB0b3RhbCBkaXNrIGNhcGFjaXR5IGluIHBhcnRpdGlvbiB0YWJsZSBhcyB3ZWxsLgogKiAgICAgICAgICAgICAgICAgICAgICAgTWFrZSBWRVJCT1NFX0lERV9DRF9FUlJPUlMgZHVtcCBmYWlsZWQgY29tbWFuZCBhZ2Fpbi4KICogICAgICAgICAgICAgICAgICAgICAgIER1bXAgb3V0IG1vcmUgaW5mb3JtYXRpb24gZm9yIElMTEVHQUwgUkVRVUVTVCBlcnJzLgogKiAgICAgICAgICAgICAgICAgICAgICAgRml4IGhhbmRsaW5nIG9mIGVycm9ycyBvY2N1cnJpbmcgYmVmb3JlIHRoZQogKiAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldCBjb21tYW5kIGlzIHRyYW5zZmVycmVkLgogKiAgICAgICAgICAgICAgICAgICAgICAgRml4IHRyYW5zZmVycyB3aXRoIG9kZCBieXRlbGVuZ3Rocy4KICogMy4wMyAgT2N0IDI3LCAxOTk1IC0tIFNvbWUgQ3JlYXRpdmUgZHJpdmVzIGhhdmUgYW4gaWQgb2YganVzdCBgQ0QnLgogKiAgICAgICAgICAgICAgICAgICAgICAgYERDSS0yUzEwJyBkcml2ZXMgYXJlIGJyb2tlbiB0b28uCiAqIDMuMDQgIE5vdiAyMCwgMTk5NSAtLSBTbyBhcmUgVmVydG9zIGRyaXZlcy4KICogMy4wNSAgRGVjICAxLCAxOTk1IC0tIENoYW5nZXMgdG8gZ28gd2l0aCBvdmVyaGF1bCBvZiBpZGUuYyBhbmQgaWRlLXRhcGUuYwogKiAzLjA2ICBEZWMgMTYsIDE5OTUgLS0gQWRkIHN1cHBvcnQgbmVlZGVkIGZvciBwYXJ0aXRpb25zLgogKiAgICAgICAgICAgICAgICAgICAgICAgTW9yZSB3b3JrYXJvdW5kcyBmb3IgVmVydG9zIGJ1Z3MgKGJhc2VkIG9uIHBhdGNoZXMKICogICAgICAgICAgICAgICAgICAgICAgICBmcm9tIEhvbGdlciBEaWV0emUgPGRpZXR6ZUBhaXg1MjAuaW5mb3JtYXRpay51bmktbGVpcHppZy5kZT4pLgogKiAgICAgICAgICAgICAgICAgICAgICAgVHJ5IHRvIGVsaW1pbmF0ZSBieXRlb3JkZXIgYXNzdW1wdGlvbnMuCiAqICAgICAgICAgICAgICAgICAgICAgICBVc2UgYXRhcGlfY2Ryb21fc3ViY2hubCBzdHJ1Y3QgZGVmaW5pdGlvbi4KICogICAgICAgICAgICAgICAgICAgICAgIEFkZCBTVEFOREFSRF9BVEFQSSBjb21waWxhdGlvbiBvcHRpb24uCiAqIDMuMDcgIEphbiAyOSwgMTk5NiAtLSBNb3JlIHR3aWRkbGluZyBmb3IgYnJva2VuIGRyaXZlczogU29ueSA1NUQsCiAqICAgICAgICAgICAgICAgICAgICAgICAgVmVydG9zIDMwMC4KICogICAgICAgICAgICAgICAgICAgICAgIEFkZCBOT19ET09SX0xPQ0tJTkcgY29uZmlndXJhdGlvbiBvcHRpb24uCiAqICAgICAgICAgICAgICAgICAgICAgICBIYW5kbGUgZHJpdmVfY21kIHJlcXVlc3RzIHcvTlVMTCBhcmdzIChmb3IgaGRwYXJtIC10KS4KICogICAgICAgICAgICAgICAgICAgICAgIFdvcmsgYXJvdW5kIHNwb3JhZGljIFNvbnk1NWUgYXVkaW8gcGxheSBwcm9ibGVtLgogKiAzLjA3YSBGZWIgMTEsIDE5OTYgLS0gY2hlY2sgZHJpdmUtPmlkIGZvciBOVUxMIGJlZm9yZSBkZXJlZmVyZW5jaW5nLCB0byBmaXgKICogICAgICAgICAgICAgICAgICAgICAgICBwcm9ibGVtIHdpdGggImhkZT1jZHJvbSIgd2l0aCBubyBkcml2ZSBwcmVzZW50LiAgLW1sCiAqIDMuMDggIE1hciAgNiwgMTk5NiAtLSBNb3JlIFZlcnRvcyB3b3JrYXJvdW5kcy4KICogMy4wOSAgQXByICA1LCAxOTk2IC0tIEFkZCBDRFJPTUNMT1NFVFJBWSBpb2N0bC4KICogICAgICAgICAgICAgICAgICAgICAgIFN3aXRjaCB0byB1c2luZyBNU0YgYWRkcmVzc2luZyBmb3IgYXVkaW8gY29tbWFuZHMuCiAqICAgICAgICAgICAgICAgICAgICAgICBSZWZvcm1hdCB0byBtYXRjaCBrZXJuZWwgdGFiYmluZyBzdHlsZS4KICogICAgICAgICAgICAgICAgICAgICAgIEFkZCBDRFJPTV9HRVRfVVBDIGlvY3RsLgogKiAzLjEwICBBcHIgMTAsIDE5OTYgLS0gRml4IGNvbXBpbGF0aW9uIGVycm9yIHdpdGggU1RBTkRBUkRfQVRBUEkuCiAqIDMuMTEgIEFwciAyOSwgMTk5NiAtLSBQYXRjaCBmcm9tIEhlaWtvIEVpc3NmZWxkdCA8aGVpa29AY29sb3NzdXMuZXNjYXBlLmRlPgogKiAgICAgICAgICAgICAgICAgICAgICAgdG8gcmVtb3ZlIHJlZHVuZGFudCB2ZXJpZnlfYXJlYSBjYWxscy4KICogMy4xMiAgTWF5ICA3LCAxOTk2IC0tIFJ1ZGltZW50YXJ5IGNoYW5nZXIgc3VwcG9ydC4gIEJhc2VkIG9uIHBhdGNoZXMKICogICAgICAgICAgICAgICAgICAgICAgICBmcm9tIEdlcmhhcmQgWnViZXIgPHp1YmVyQGJlcmxpbi5zbmFmdS5kZT4uCiAqICAgICAgICAgICAgICAgICAgICAgICBMZXQgb3BlbiBzdWNjZWVkIGV2ZW4gaWYgdGhlcmUncyBubyBsb2FkZWQgZGlzYy4KICogMy4xMyAgTWF5IDE5LCAxOTk2IC0tIEZpeGVzIGZvciBjaGFuZ2VyIGNvZGUuCiAqIDMuMTQgIE1heSAyOSwgMTk5NiAtLSBBZGQgd29yay1hcm91bmQgZm9yIFZlcnRvcyA2MDAuCiAqICAgICAgICAgICAgICAgICAgICAgICAgKEZyb20gSGVubnVzIEJlcmdtYW4gPGhlbm51c0Bza3kub3cubmw+LikKICogMy4xNSAgSnVseSAyLCAxOTk2IC0tIEFkZGVkIHN1cHBvcnQgZm9yIFNhbnlvIDMgQ0QgY2hhbmdlcnMKICogICAgICAgICAgICAgICAgICAgICAgICBmcm9tIEJlbiBHYWxsaWFydCA8YmdhbGxpYUBsdWMuZWR1PiB3aXRoIAogKiAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpYWwgaGVscCBmcm9tIEplZmYgTGlnaHRmb290IAogKiAgICAgICAgICAgICAgICAgICAgICAgIDxqZWZmbWxAcG9ib3guY29tPgogKiAzLjE1YSBKdWx5IDksIDE5OTYgLS0gSW1wcm92ZWQgU2FueW8gMyBDRCBjaGFuZ2VyIGlkZW50aWZpY2F0aW9uCiAqIDMuMTYgIEp1bCAyOCwgMTk5NiAtLSBGaXggZnJvbSBHYWRpIHRvIHJlZHVjZSBrZXJuZWwgc3RhY2sgdXNhZ2UgZm9yIGlvY3RsLgogKiAzLjE3ICBTZXAgMTcsIDE5OTYgLS0gVHdlYWsgYXVkaW8gcmVhZHMgZm9yIHNvbWUgZHJpdmVzLgogKiAgICAgICAgICAgICAgICAgICAgICAgU3RhcnQgY2hhbmdpbmcgQ0RST01MT0FERlJPTVNMT1QgdG8gQ0RST01fU0VMRUNUX0RJU0MuCiAqIDMuMTggIE9jdCAzMSwgMTk5NiAtLSBBZGRlZCBtb2R1bGUgYW5kIERNQSBzdXBwb3J0LgogKiAgICAgICAgICAgICAgICAgICAgICAgCiAqICAgICAgICAgICAgICAgICAgICAgICAKICogNC4wMCAgTm92IDUsIDE5OTYgICAtLSBOZXcgaWRlLWNkIG1haW50YWluZXIsCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXJpayBCLiBBbmRlcnNlbiA8YW5kZXJzZWVAZGViaWFuLm9yZz4KICogICAgICAgICAgICAgICAgICAgICAtLSBOZXdlciBDcmVhdGl2ZSBkcml2ZXMgZG9uJ3QgYWx3YXlzIHNldCB0aGUgZXJyb3IKICogICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyIGNvcnJlY3RseS4gIE1ha2Ugc3VyZSB3ZSBzZWUgbWVkaWEgY2hhbmdlcwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnYXJkbGVzcy4KICogICAgICAgICAgICAgICAgICAgICAtLSBJbnRlZ3JhdGUgd2l0aCBnZW5lcmljIGNkcm9tIGRyaXZlci4KICogICAgICAgICAgICAgICAgICAgICAtLSBDRFJPTUdFVFNQSU5ET1dOIGFuZCBDRFJPTVNFVFNQSU5ET1dOIGlvY3RscywgYmFzZWQgb24KICogICAgICAgICAgICAgICAgICAgICAgICAgIGEgcGF0Y2ggZnJvbSBDaXJvIENhdHR1dG8gPD4uCiAqICAgICAgICAgICAgICAgICAgICAgLS0gQ2FsbCBzZXRfZGV2aWNlX3JvLgogKiAgICAgICAgICAgICAgICAgICAgIC0tIEltcGxlbWVudCBDRFJPTU1FQ0hBTklTTVNUQVRVUyBhbmQgQ0RST01TTE9UVEFCTEUKICogICAgICAgICAgICAgICAgICAgICAgICAgIGlvY3RscywgYmFzZWQgb24gcGF0Y2ggYnkgRXJpayBBbmRlcnNlbgogKiAgICAgICAgICAgICAgICAgICAgIC0tIEFkZCBzb21lIHByb2JlcyBvZiBkcml2ZSBjYXBhYmlsaXR5IGR1cmluZyBzZXR1cC4KICoKICogNC4wMSAgTm92IDExLCAxOTk2ICAtLSBTcGxpdCBpbnRvIGlkZS1jZC5jIGFuZCBpZGUtY2QuaAogKiAgICAgICAgICAgICAgICAgICAgIC0tIFJlbW92ZWQgQ0RST01NRUNIQU5JU01TVEFUVVMgYW5kIENEUk9NU0xPVFRBQkxFIAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgaW9jdGxzIGluIGZhdm9yIG9mIGEgZ2VuZXJhbGl6ZWQgYXBwcm9hY2ggCiAqICAgICAgICAgICAgICAgICAgICAgICAgICB1c2luZyB0aGUgZ2VuZXJpYyBjZHJvbSBkcml2ZXIuCiAqICAgICAgICAgICAgICAgICAgICAgLS0gRnVsbHkgaW50ZWdyYXRlZCB3aXRoIHRoZSAyLjEuWCBrZXJuZWwuCiAqICAgICAgICAgICAgICAgICAgICAgLS0gT3RoZXIgc3R1ZmYgdGhhdCBJIGZvcmdvdCAobG90cyBvZiBjaGFuZ2VzKQogKgogKiA0LjAyICBEZWMgMDEsIDE5OTYgIC0tIEFwcGxpZWQgcGF0Y2ggZnJvbSBHYWRpIE94bWFuIDxnYWRpb0BuZXR2aXNpb24ubmV0LmlsPgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gZml4IHRoZSBkcml2ZSBkb29yIGxvY2tpbmcgcHJvYmxlbXMuCiAqCiAqIDQuMDMgIERlYyAwNCwgMTk5NiAgLS0gQWRkZWQgRFNDIG92ZXJsYXAgc3VwcG9ydC4KICogNC4wNCAgRGVjIDI5LCAxOTk2ICAtLSBBZGRlZCBDRFJPTVJFQURSQVcgaW9jbHQgYmFzZWQgb24gcGF0Y2ggCiAqICAgICAgICAgICAgICAgICAgICAgICAgICBieSBBbGVzIE1ha2Fyb3YgKHhtYWthcm92QHN1bi5mZWxrLmN2dXQuY3opCiAqCiAqIDQuMDUgIE5vdiAyMCwgMTk5NyAgLS0gTW9kaWZpZWQgdG8gcHJpbnQgbW9yZSBkcml2ZSBpbmZvIG9uIGluaXQKICogICAgICAgICAgICAgICAgICAgICAgICBNaW5vciBvdGhlciBjaGFuZ2VzCiAqICAgICAgICAgICAgICAgICAgICAgICAgRml4IGVycm9ycyBvbiBDRFJPTVNUT1AgKElmIHlvdSBoYXZlIGEgIkRvbHBoaW4iLAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgeW91IG11c3QgZGVmaW5lIElIQVZFQURPTFBISU4pCiAqICAgICAgICAgICAgICAgICAgICAgICAgQWRkZWQgaWRlbnRpZmllciBzbyBuZXcgU2FueW8gQ0QtY2hhbmdlciB3b3JrcwogKiAgICAgICAgICAgICAgICAgICAgICAgIEJldHRlciBkZXRlY3Rpb24gaWYgZG9vciBsb2NraW5nIGlzbid0IHN1cHBvcnRlZAogKgogKiA0LjA2ICBEZWMgMTcsIDE5OTcgIC0tIGZpeGVkIGVuZGxlc3MgInRyYXkgb3BlbiIgbWVzc2FnZXMgIC1tbAogKiA0LjA3ICBEZWMgMTcsIDE5OTcgIC0tIGZhbGxiYWNrIHRvIHNldCBwYy0+c3RhdCBvbiAidHJheSBvcGVuIgogKiA0LjA4ICBEZWMgMTgsIDE5OTcgIC0tIHNwZXcgbGVzcyBub2lzZSB3aGVuIHRyYXkgaXMgZW1wdHkKICogICAgICAgICAgICAgICAgICAgICAtLSBmaXggc3BlZWQgZGlzcGxheSBmb3IgQUNFUiAyNFgsIDE4WAogKiA0LjA5ICBKYW4gMDQsIDE5OTggIC0tIGZpeCBoYW5kbGluZyBvZiB0aGUgbGFzdCBibG9jayBzbyB3ZSByZXR1cm4KICogICAgICAgICAgICAgICAgICAgICAgICAgYW4gZW5kIG9mIGZpbGUgaW5zdGVhZCBvZiBhbiBJL08gZXJyb3IgKEdhZGkpCiAqIDQuMTAgIEphbiAyNCwgMTk5OCAgLS0gZml4ZWQgYSBidWcgc28gbm93IGNoYW5nZXJzIGNhbiBjaGFuZ2UgdG8gYSBuZXcKICogICAgICAgICAgICAgICAgICAgICAgICAgc2xvdCB3aGVuIHRoZXJlIGlzIG5vIGRpc2MgaW4gdGhlIGN1cnJlbnQgc2xvdC4KICogICAgICAgICAgICAgICAgICAgICAtLSBGaXhlZCBhIG1lbW9yeSBsZWFrIHdoZXJlIGluZm8tPmNoYW5nZXJfaW5mbyB3YXMKICogICAgICAgICAgICAgICAgICAgICAgICAgbWFsbG9jJ2VkIGJ1dCBuZXZlciBmcmVlJ2Qgd2hlbiBjbG9zaW5nIHRoZSBkZXZpY2UuCiAqICAgICAgICAgICAgICAgICAgICAgLS0gQ2xlYW5lZCB1cCB0aGUgZ2xvYmFsIG5hbWVzcGFjZSBhIGJpdCBieSBtYWtpbmcgbW9yZQogKiAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbnMgc3RhdGljIHRoYXQgc2hvdWxkIGFscmVhZHkgaGF2ZSBiZWVuLgogKiA0LjExICBNYXIgMTIsIDE5OTggIC0tIEFkZGVkIHN1cHBvcnQgZm9yIHRoZSBDRFJPTV9TRUxFQ1RfU1BFRUQgaW9jdGwKICogICAgICAgICAgICAgICAgICAgICAgICAgYmFzZWQgb24gYSBwYXRjaCBmb3IgMi4wLjMzIGJ5IEplbGxlIEZva3MgCiAqICAgICAgICAgICAgICAgICAgICAgICAgIDxqZWxsZUBzY2ludGlsbGEudXR3ZW50ZS5ubD4sIGEgcGF0Y2ggZm9yIDIuMC4zMwogKiAgICAgICAgICAgICAgICAgICAgICAgICBieSBUb25pIEdpb3JnaW5vIDx0b25pQHBjYXBlMi5waS5pbmZuLml0PiwgdGhlIFNDU0kKICogICAgICAgICAgICAgICAgICAgICAgICAgdmVyc2lvbiwgYW5kIG15IG93biBlZmZvcnRzLiAgLWVyaWsKICogICAgICAgICAgICAgICAgICAgICAtLSBGaXhlZCBhIHN0dXBpZCBidWcgd2hpY2ggZWdjcyB3YXMga2luZCBlbm91Z2ggdG8KICogICAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtIG1lIG9mIHdoZXJlICJJbGxlZ2FsIG1vZGUgZm9yIHRoaXMgdHJhY2siCiAqICAgICAgICAgICAgICAgICAgICAgICAgIHdhcyBuZXZlciByZXR1cm5lZCBkdWUgdG8gYSBjb21wYXJpc29uIG9uIGRhdGEKICogICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMgb2YgbGltaXRlZCByYW5nZS4KICogNC4xMiAgTWFyIDI5LCAxOTk4ICAtLSBGaXhlZCBidWcgaW4gQ0RST01fU0VMRUNUX1NQRUVEIHNvIHdyaXRlIHNwZWVkIGlzIAogKiAgICAgICAgICAgICAgICAgICAgICAgICBub3cgc2V0IGlvbmx5IGZvciBDRC1SIGFuZCBDRC1SVyBkcml2ZXMuICBJIGhhZCAKICogICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlZCB0aGlzIHN1cHBvcnQgYmVjYXVzZSBpdCBwcm9kdWNlZCBlcnJvcnMuCiAqICAgICAgICAgICAgICAgICAgICAgICAgIEl0IHByb2R1Y2VkIGVycm9ycyBfb25seV8gZm9yIG5vbi13cml0ZXJzLiBkdWguCiAqIDQuMTMgIE1heSAwNSwgMTk5OCAgLS0gU3VwcHJlc3MgdXNlbGVzcyAiaW4gcHJvZ3Jlc3Mgb2YgYmVjb21pbmcgcmVhZHkiCiAqICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VzLCBzaW5jZSB0aGlzIGlzIG5vdCBhbiBlcnJvci4KICogICAgICAgICAgICAgICAgICAgICAtLSBDaGFuZ2UgZXJyb3IgbWVzc2FnZXMgdG8gYmUgY29uc3QKICogICAgICAgICAgICAgICAgICAgICAtLSBSZW1vdmUgYSAiXHQiIHdoaWNoIGxvb2tzIHVnbHkgaW4gdGhlIHN5c2xvZ3MKICogNC4xNCAgSnVseSAxNywgMTk5OCAtLSBDaGFuZ2UgdG8gcG9pbnRpbmcgdG8gLnBzIHZlcnNpb24gb2YgQVRBUEkgc3BlYwogKiAgICAgICAgICAgICAgICAgICAgICAgICBzaW5jZSB0aGUgLnBkZiB2ZXJzaW9uIGRvZXNuJ3Qgc2VlbSB0byB3b3JrLi4uCiAqICAgICAgICAgICAgICAgICAgICAgLS0gVXBkYXRlZCB0aGUgVE9ETyBsaXN0IHRvIHNvbWV0aGluZyBtb3JlIGN1cnJlbnQuCiAqCiAqIDQuMTUgIEF1ZyAyNSwgMTk5OCAgLS0gVXBkYXRlZCBpZGUtY2QuaCB0byByZXNwZWN0IG1lY2hpbmUgZW5kaWFuZXNzLCAKICogICAgICAgICAgICAgICAgICAgICAgICAgcGF0Y2ggdGhhbmtzIHRvICJFZGRpZSBDLiBEb3N0IiA8ZWNkQHNreW5ldC5iZT4KICoKICogNC41MCAgT2N0IDE5LCAxOTk4ICAtLSBOZXcgbWFpbnRhaW5lcnMhCiAqICAgICAgICAgICAgICAgICAgICAgICAgIEplbnMgQXhib2UgPGF4Ym9lQGltYWdlLmRrPgogKiAgICAgICAgICAgICAgICAgICAgICAgICBDaHJpcyBad2lsbGluZyA8Y2hyaXNAY2xvdWRuZXQuY29tPgogKgogKiA0LjUxICBEZWMgMjMsIDE5OTggIC0tIEplbnMgQXhib2UgPGF4Ym9lQGltYWdlLmRrPgogKiAgICAgICAgICAgICAgICAgICAgICAtIGlkZV9jZHJvbV9yZXNldCBlbmFibGVkIHNpbmNlIHRoZSBpZGUgc3Vic3lzdGVtCiAqICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXMgcmVzZXRzIGZpbmUgbm93LiA8YXhib2VAaW1hZ2UuZGs+CiAqICAgICAgICAgICAgICAgICAgICAgIC0gVHJhbnNmZXIgc2l6ZSBmaXggZm9yIFNhbXN1bmcgQ0QtUk9NcywgdGhhbmtzIHRvCiAqICAgICAgICAgICAgICAgICAgICAgICAgIlZpbGxlIEhhbGxpayIgPHZpbGxlLmhhbGxpa0BtYWlsLmVlPi4KICogICAgICAgICAgICAgICAgICAgICAgLSBvdGhlciBtaW5vciBzdHVmZi4KICoKICogNC41MiAgSmFuIDE5LCAxOTk5ICAtLSBKZW5zIEF4Ym9lIDxheGJvZUBpbWFnZS5kaz4KICogICAgICAgICAgICAgICAgICAgICAgLSBEZXRlY3QgRFZELVJPTS9SQU0gZHJpdmVzCiAqCiAqIDQuNTMgIEZlYiAyMiwgMTk5OSAgIC0gSW5jbHVkZSBvdGhlciBtb2RlbCBTYW1zdW5nIGFuZCBvbmUgR29sZHN0YXIKICogICAgICAgICAgICAgICAgICAgICAgICAgZHJpdmUgaW4gdHJhbnNmZXIgc2l6ZSBsaW1pdC4KICogICAgICAgICAgICAgICAgICAgICAgLSBGaXggdGhlIEkvTyBlcnJvciB3aGVuIGRvaW5nIGVqZWN0IHdpdGhvdXQgYSBtZWRpdW0KICogICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVkIG9uIHNvbWUgZHJpdmVzLgogKiAgICAgICAgICAgICAgICAgICAgICAtIENEUk9NUkVBRE1PREUyIGlzIG5vdyBpbXBsZW1lbnRlZCB0aHJvdWdoCiAqICAgICAgICAgICAgICAgICAgICAgICAgIENEUk9NUkVBRFJBVywgc2luY2UgbWFueSBkcml2ZXMgZG9uJ3Qgc3VwcG9ydAogKiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFMiAoZXZlbiB0aG91Z2ggQVRBUEkgMi42IHNheXMgdGhleSBtdXN0KS4KICogICAgICAgICAgICAgICAgICAgICAgLSBBZGRlZCBpZ25vcmUgcGFyYW1ldGVyIHRvIGlkZS1jZCAoYXMgYSBtb2R1bGUpLCBlZwogKiAgICAgICAgICAgICAgICAgICAgICAgICAJaW5zbW9kIGlkZS1jZCBpZ25vcmU9J2hkYSBoZGInCiAqICAgICAgICAgICAgICAgICAgICAgICAgIFVzZWZ1bCB3aGVuIHVzaW5nIGlkZS1jZCBpbiBjb25qdW5jdGlvbiB3aXRoCiAqICAgICAgICAgICAgICAgICAgICAgICAgIGlkZS1zY3NpLiBUT0RPOiBub24tbW9kdWxhciB3YXkgb2YgZG9pbmcgdGhlCiAqICAgICAgICAgICAgICAgICAgICAgICAgIHNhbWUuCiAqCiAqIDQuNTQgIEF1ZyA1LCAxOTk5CS0gU3VwcG9ydCBmb3IgTU1DMiBjbGFzcyBjb21tYW5kcyB0aHJvdWdoIHRoZSBnZW5lcmljCiAqCQkJICBwYWNrZXQgaW50ZXJmYWNlIHRvIGNkcm9tLmMuCiAqCQkJLSBVbmlmaWVkIGF1ZGlvIGlvY3RsIHN1cHBvcnQsIG1vc3Qgb2YgaXQuCiAqCQkJLSBjbGVhbmVkIHVwIHZhcmlvdXMgZGVwcmVjYXRlZCB2ZXJpZnlfYXJlYSgpLgogKgkJCS0gQWRkZWQgaWRlX2Nkcm9tX3BhY2tldCgpIGFzIHRoZSBpbnRlcmZhY2UgZm9yCiAqCQkJICB0aGUgVW5pZm9ybSBnZW5lcmljX3BhY2tldCgpLgogKgkJCS0gYnVuY2ggb2Ygb3RoZXIgc3R1ZmYsIHdpbGwgZmlsbCBpbiBsb2dzIGxhdGVyLgogKgkJCS0gcmVwb3J0IDEgc2xvdCBmb3Igbm9uLWNoYW5nZXJzLCBsaWtlIHRoZSBvdGhlcgogKgkJCSAgY2Qtcm9tIGRyaXZlcnMuIGRvbid0IHJlcG9ydCBzZWxlY3QgZGlzYyBmb3IKICoJCQkgIG5vbi1jaGFuZ2VycyBhcyB3ZWxsLgogKgkJCS0gbWFzayBvdXQgYXVkaW8gcGxheWluZywgaWYgdGhlIGRldmljZSBjYW4ndCBkbyBpdC4KICoKICogNC41NSAgU2VwIDEsIDE5OTkJLSBFbGltaW5hdGVkIHRoZSByZXN0IG9mIHRoZSBhdWRpbyBpb2N0bHMsIGV4Y2VwdAogKgkJCSAgZm9yIENEUk9NUkVBRFRPQ1tFTlRSWXxIRUFERVJdLiBTb21lIG9mIHRoZSBkcml2ZXJzCiAqCQkJICB1c2UgdGhpcyBpbmRlcGVuZGVudGx5IG9mIHRoZSBhY3R1YWwgYXVkaW8gaGFuZGxpbmcuCiAqCQkJICBUaGV5IHdpbGwgZGlzYXBwZWFyIGxhdGVyIHdoZW4gSSBnZXQgdGhlIHRpbWUgdG8KICoJCQkgIGRvIGl0IGNsZWFubHkuCiAqCQkJLSBNaW5pbWl6ZSB0aGUgVE9DIHJlYWRpbmcgLSBvbmx5IGRvIGl0IHdoZW4gd2UKICoJCQkgIGtub3cgYSBtZWRpYSBjaGFuZ2UgaGFzIG9jY3VycmVkLgogKgkJCS0gTW92ZWQgYWxsIHRoZSBDRFJPTVJFQUR4IGlvY3RscyB0byB0aGUgVW5pZm9ybSBsYXllci4KICoJCQktIEhlaWtvIEVpc3NmZWxkdCA8aGVpa29AY29sb3NzdXMuZXNjYXBlLmRlPiBzdXBwbGllZAogKgkJCSAgc29tZSBmaXhlcyBmb3IgQ0RJLgogKgkJCS0gQ0QtUk9NIGxlYXZpbmcgZG9vciBsb2NrZWQgZml4IGZyb20gQW5kcmllcwogKgkJCSAgQnJvdXdlciA8QW5kcmllcy5Ccm91d2VyQGN3aS5ubD4KICoJCQktIEVyaWsgQW5kZXJzZW4gPGFuZGVyc2VuQHhtaXNzaW9uLmNvbT4gdW5pZmllZAogKgkJCSAgY29tbWFuZHMgYWNyb3NzIHRoZSB2YXJpb3VzIGRyaXZlcnMgYW5kIGhvdwogKgkJCSAgc2Vuc2UgZXJyb3JzIGFyZSBoYW5kbGVkLgogKgogKiA0LjU2ICBTZXAgMTIsIDE5OTkJLSBSZW1vdmVkIGNoYW5nZXIgc3VwcG9ydCAtIGl0IGlzIG5vdyBpbiB0aGUKICoJCQkgIFVuaWZvcm0gbGF5ZXIuCiAqCQkJLSBBZGRlZCBwYXJ0aXRpb24gYmFzZWQgbXVsdGlzZXNzaW9uIGhhbmRsaW5nLgogKgkJCS0gTW9kZSBzZW5zZSBhbmQgbW9kZSBzZWxlY3QgbW92ZWQgdG8gdGhlCiAqCQkJICBVbmlmb3JtIGxheWVyLgogKgkJCS0gRml4ZWQgYSBwcm9ibGVtIHdpdGggV1BJIENEUy0zMlggZHJpdmUgLSBpdAogKgkJCSAgZmFpbGVkIHRoZSBjYXBhYmlsaXRpZXMgCiAqCiAqIDQuNTcgIEFwciA3LCAyMDAwCS0gRml4ZWQgc2Vuc2UgcmVwb3J0aW5nLgogKgkJCS0gRml4ZWQgcG9zc2libGUgb29wcyBpbiBpZGVfY2Ryb21fZ2V0X2xhc3Rfc2Vzc2lvbigpCiAqCQkJLSBGaXggbG9ja2luZyBtYW5pYSBhbmQgbWFrZSBpZGVfY2Ryb21fcmVzZXQgcmVsb2NrCiAqCQkJLSBTdG9wIHNwZXdpbmcgZXJyb3JzIHRvIGxvZyB3aGVuIG1hZ2ljZGV2IHBvbGxzIHdpdGgKICoJCQkgIFRFU1RfVU5JVF9SRUFEWSBvbiBzb21lIGRyaXZlcy4KICoJCQktIFZhcmlvdXMgZml4ZXMgZnJvbSBUb2JpYXMgUmluZ3N0cm9tOgogKgkJCSAgdHJheSBpZiBpdCB3YXMgbG9ja2VkIHByaW9yIHRvIHRoZSByZXNldC4KICoJCQkgIC0gY2Ryb21fcmVhZF9jYXBhY2l0eSByZXR1cm5zIG9uZSBmcmFtZSB0b28gbGl0dGxlLgogKgkJCSAgLSBGaXggcmVhbCBjYXBhY2l0eSByZXBvcnRpbmcuCiAqCiAqIDQuNTggIE1heSAxLCAyMDAwCS0gQ2xlYW4gdXAgQUNFUjUwIHN0dWZmLgogKgkJCS0gRml4IHNtYWxsIHByb2JsZW0gd2l0aCBpZGVfY2Ryb21fY2FwYWNpdHkKICoKICogNC41OSAgQXVnIDExLCAyMDAwCS0gRml4IGNoYW5nZXIgcHJvYmxlbSBpbiBjZHJvbV9yZWFkX3RvYywgd2Ugd2VyZW4ndAogKgkJCSAgY29ycmVjdGx5IHNlbnNpbmcgYSBkaXNjIGNoYW5nZS4KICoJCQktIFJlYXJyYW5nZWQgc29tZSBjb2RlCiAqCQkJLSBVc2UgZXh0ZW5kZWQgc2Vuc2Ugb24gZHJpdmVzIHRoYXQgc3VwcG9ydCBpdCBmb3IKICoJCQkgIGNvcnJlY3RseSByZXBvcnRpbmcgdHJheSBzdGF0dXMgLS0gZnJvbQogKgkJCSAgTWljaGFlbCBEIEpvaG5zb24gPGpvaG5zb21Ab3JzdC5lZHU+CiAqIDQuNjAgIERlYyAxNywgMjAwMwktIEFkZCBtdCByYWluaWVyIHN1cHBvcnQKICoJCQktIEJ1bXAgdGltZW91dCBmb3IgcGFja2V0IGNvbW1hbmRzLCBtYXRjaGVzIHNyCiAqCQkJLSBPZGQgc3R1ZmYKICogNC42MSAgSmFuIDIyLCAyMDA0CS0gc3VwcG9ydCBoYXJkd2FyZSBzZWN0b3Igc2l6ZXMgb3RoZXIgdGhhbiAya0IsCiAqCQkJICBQYXNjYWwgU2NobWlkdCA8ZGVyLmVyZW1pdEBlbWFpbC5kZT4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAKI2RlZmluZSBJREVDRF9WRVJTSU9OICI0LjYxIgoKI2luY2x1ZGUgPGxpbnV4L2NvbmZpZy5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC90eXBlcy5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvdGltZXIuaD4KI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPgojaW5jbHVkZSA8bGludXgvZXJybm8uaD4KI2luY2x1ZGUgPGxpbnV4L2Nkcm9tLmg+CiNpbmNsdWRlIDxsaW51eC9pZGUuaD4KI2luY2x1ZGUgPGxpbnV4L2NvbXBsZXRpb24uaD4KCiNpbmNsdWRlIDxzY3NpL3Njc2kuaD4JLyogRm9yIFNDU0kgLT4gQVRBUEkgY29tbWFuZCBjb252ZXJzaW9uICovCgojaW5jbHVkZSA8YXNtL2lycS5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vYnl0ZW9yZGVyLmg+CiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgojaW5jbHVkZSA8YXNtL3VuYWxpZ25lZC5oPgoKI2luY2x1ZGUgImlkZS1jZC5oIgoKc3RhdGljIERFQ0xBUkVfTVVURVgoaWRlY2RfcmVmX3NlbSk7CgojZGVmaW5lIHRvX2lkZV9jZChvYmopIGNvbnRhaW5lcl9vZihvYmosIHN0cnVjdCBjZHJvbV9pbmZvLCBrcmVmKSAKCiNkZWZpbmUgaWRlX2NkX2coZGlzaykgXAoJY29udGFpbmVyX29mKChkaXNrKS0+cHJpdmF0ZV9kYXRhLCBzdHJ1Y3QgY2Ryb21faW5mbywgZHJpdmVyKQoKc3RhdGljIHN0cnVjdCBjZHJvbV9pbmZvICppZGVfY2RfZ2V0KHN0cnVjdCBnZW5kaXNrICpkaXNrKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqY2QgPSBOVUxMOwoKCWRvd24oJmlkZWNkX3JlZl9zZW0pOwoJY2QgPSBpZGVfY2RfZyhkaXNrKTsKCWlmIChjZCkKCQlrcmVmX2dldCgmY2QtPmtyZWYpOwoJdXAoJmlkZWNkX3JlZl9zZW0pOwoJcmV0dXJuIGNkOwp9CgpzdGF0aWMgdm9pZCBpZGVfY2RfcmVsZWFzZShzdHJ1Y3Qga3JlZiAqKTsKCnN0YXRpYyB2b2lkIGlkZV9jZF9wdXQoc3RydWN0IGNkcm9tX2luZm8gKmNkKQp7Cglkb3duKCZpZGVjZF9yZWZfc2VtKTsKCWtyZWZfcHV0KCZjZC0+a3JlZiwgaWRlX2NkX3JlbGVhc2UpOwoJdXAoJmlkZWNkX3JlZl9zZW0pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBHZW5lcmljIHBhY2tldCBjb21tYW5kIHN1cHBvcnQgYW5kIGVycm9yIGhhbmRsaW5nIHJvdXRpbmVzLgogKi8KCi8qIE1hcmsgdGhhdCB3ZSd2ZSBzZWVuIGEgbWVkaWEgY2hhbmdlLCBhbmQgaW52YWxpZGF0ZSBvdXIgaW50ZXJuYWwKICAgYnVmZmVycy4gKi8Kc3RhdGljIHZvaWQgY2Ryb21fc2F3X21lZGlhX2NoYW5nZSAoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCQoJQ0RST01fU1RBVEVfRkxBR1MgKGRyaXZlKS0+bWVkaWFfY2hhbmdlZCA9IDE7CglDRFJPTV9TVEFURV9GTEFHUyAoZHJpdmUpLT50b2NfdmFsaWQgPSAwOwoJaW5mby0+bnNlY3RvcnNfYnVmZmVyZWQgPSAwOwp9CgpzdGF0aWMgaW50IGNkcm9tX2xvZ19zZW5zZShpZGVfZHJpdmVfdCAqZHJpdmUsIHN0cnVjdCByZXF1ZXN0ICpycSwKCQkJICAgc3RydWN0IHJlcXVlc3Rfc2Vuc2UgKnNlbnNlKQp7CglpbnQgbG9nID0gMDsKCglpZiAoIXNlbnNlIHx8ICFycSB8fCAocnEtPmZsYWdzICYgUkVRX1FVSUVUKSkKCQlyZXR1cm4gMDsKCglzd2l0Y2ggKHNlbnNlLT5zZW5zZV9rZXkpIHsKCQljYXNlIE5PX1NFTlNFOiBjYXNlIFJFQ09WRVJFRF9FUlJPUjoKCQkJYnJlYWs7CgkJY2FzZSBOT1RfUkVBRFk6CgkJCS8qCgkJCSAqIGRvbid0IGNhcmUgYWJvdXQgdHJheSBzdGF0ZSBtZXNzYWdlcyBmb3IKCQkJICogZS5nLiBjYXBhY2l0eSBjb21tYW5kcyBvciBpbi1wcm9ncmVzcyBvcgoJCQkgKiBiZWNvbWluZyByZWFkeQoJCQkgKi8KCQkJaWYgKHNlbnNlLT5hc2MgPT0gMHgzYSB8fCBzZW5zZS0+YXNjID09IDB4MDQpCgkJCQlicmVhazsKCQkJbG9nID0gMTsKCQkJYnJlYWs7CgkJY2FzZSBJTExFR0FMX1JFUVVFU1Q6CgkJCS8qCgkJCSAqIGRvbid0IGxvZyBTVEFSVF9TVE9QIHVuaXQgd2l0aCBMb0VqIHNldCwgc2luY2UKCQkJICogd2UgY2Fubm90IHJlbGlhYmx5IGNoZWNrIGlmIGRyaXZlIGNhbiBhdXRvLWNsb3NlCgkJCSAqLwoJCQlpZiAocnEtPmNtZFswXSA9PSBHUENNRF9TVEFSVF9TVE9QX1VOSVQgJiYgc2Vuc2UtPmFzYyA9PSAweDI0KQoJCQkJbG9nID0gMDsKCQkJYnJlYWs7CgkJY2FzZSBVTklUX0FUVEVOVElPTjoKCQkJLyoKCQkJICogTWFrZSBnb29kIGFuZCBzdXJlIHdlJ3ZlIHNlZW4gdGhpcyBwb3RlbnRpYWwgbWVkaWEKCQkJICogY2hhbmdlLiBTb21lIGRyaXZlcyAoaS5lLiBDcmVhdGl2ZSkgZmFpbCB0byBwcmVzZW50CgkJCSAqIHRoZSBjb3JyZWN0IHNlbnNlIGtleSBpbiB0aGUgZXJyb3IgcmVnaXN0ZXIuCgkJCSAqLwoJCQljZHJvbV9zYXdfbWVkaWFfY2hhbmdlKGRyaXZlKTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJbG9nID0gMTsKCQkJYnJlYWs7Cgl9CglyZXR1cm4gbG9nOwp9CgpzdGF0aWMKdm9pZCBjZHJvbV9hbmFseXplX3NlbnNlX2RhdGEoaWRlX2RyaXZlX3QgKmRyaXZlLAoJCQkgICAgICBzdHJ1Y3QgcmVxdWVzdCAqZmFpbGVkX2NvbW1hbmQsCgkJCSAgICAgIHN0cnVjdCByZXF1ZXN0X3NlbnNlICpzZW5zZSkKewoJaWYgKCFjZHJvbV9sb2dfc2Vuc2UoZHJpdmUsIGZhaWxlZF9jb21tYW5kLCBzZW5zZSkpCgkJcmV0dXJuOwoKCS8qCgkgKiBJZiBhIHJlYWQgdG9jIGlzIGV4ZWN1dGVkIGZvciBhIENELVIgb3IgQ0QtUlcgbWVkaXVtIHdoZXJlCgkgKiB0aGUgZmlyc3QgdG9jIGhhcyBub3QgYmVlbiByZWNvcmRlZCB5ZXQsIGl0IHdpbGwgZmFpbCB3aXRoCgkgKiAwNS8yNC8wMCAod2hpY2ggaXMgYSBjb25mdXNpbmcgZXJyb3IpCgkgKi8KCWlmIChmYWlsZWRfY29tbWFuZCAmJiBmYWlsZWRfY29tbWFuZC0+Y21kWzBdID09IEdQQ01EX1JFQURfVE9DX1BNQV9BVElQKQoJCWlmIChzZW5zZS0+c2Vuc2Vfa2V5ID09IDB4MDUgJiYgc2Vuc2UtPmFzYyA9PSAweDI0KQoJCQlyZXR1cm47CgojaWYgVkVSQk9TRV9JREVfQ0RfRVJST1JTCgl7CgkJaW50IGk7CgkJY29uc3QgY2hhciAqcyA9ICJiYWQgc2Vuc2Uga2V5ISI7CgkJY2hhciBidWZbODBdOwoKCQlwcmludGsgKCJBVEFQSSBkZXZpY2UgJXM6XG4iLCBkcml2ZS0+bmFtZSk7CgkJaWYgKHNlbnNlLT5lcnJvcl9jb2RlPT0weDcwKQoJCQlwcmludGsoIiAgRXJyb3I6ICIpOwoJCWVsc2UgaWYgKHNlbnNlLT5lcnJvcl9jb2RlPT0weDcxKQoJCQlwcmludGsoIiAgRGVmZXJyZWQgRXJyb3I6ICIpOwoJCWVsc2UgaWYgKHNlbnNlLT5lcnJvcl9jb2RlID09IDB4N2YpCgkJCXByaW50aygiICBWZW5kb3Itc3BlY2lmaWMgRXJyb3I6ICIpOwoJCWVsc2UKCQkJcHJpbnRrKCIgIFVua25vd24gRXJyb3IgVHlwZTogIik7CgoJCWlmIChzZW5zZS0+c2Vuc2Vfa2V5IDwgQVJZX0xFTihzZW5zZV9rZXlfdGV4dHMpKQoJCQlzID0gc2Vuc2Vfa2V5X3RleHRzW3NlbnNlLT5zZW5zZV9rZXldOwoKCQlwcmludGsoIiVzIC0tIChTZW5zZSBrZXk9MHglMDJ4KVxuIiwgcywgc2Vuc2UtPnNlbnNlX2tleSk7CgoJCWlmIChzZW5zZS0+YXNjID09IDB4NDApIHsKCQkJc3ByaW50ZihidWYsICJEaWFnbm9zdGljIGZhaWx1cmUgb24gY29tcG9uZW50IDB4JTAyeCIsCgkJCQkgc2Vuc2UtPmFzY3EpOwoJCQlzID0gYnVmOwoJCX0gZWxzZSB7CgkJCWludCBsbyA9IDAsIG1pZCwgaGkgPSBBUllfTEVOKHNlbnNlX2RhdGFfdGV4dHMpOwoJCQl1bnNpZ25lZCBsb25nIGtleSA9IChzZW5zZS0+c2Vuc2Vfa2V5IDw8IDE2KTsKCQkJa2V5IHw9IChzZW5zZS0+YXNjIDw8IDgpOwoJCQlpZiAoIShzZW5zZS0+YXNjcSA+PSAweDgwICYmIHNlbnNlLT5hc2NxIDw9IDB4ZGQpKQoJCQkJa2V5IHw9IHNlbnNlLT5hc2NxOwoJCQlzID0gTlVMTDsKCgkJCXdoaWxlIChoaSA+IGxvKSB7CgkJCQltaWQgPSAobG8gKyBoaSkgLyAyOwoJCQkJaWYgKHNlbnNlX2RhdGFfdGV4dHNbbWlkXS5hc2NfYXNjcSA9PSBrZXkgfHwKCQkJCSAgICBzZW5zZV9kYXRhX3RleHRzW21pZF0uYXNjX2FzY3EgPT0gKDB4ZmYwMDAwfGtleSkpIHsKCQkJCQlzID0gc2Vuc2VfZGF0YV90ZXh0c1ttaWRdLnRleHQ7CgkJCQkJYnJlYWs7CgkJCQl9CgkJCQllbHNlIGlmIChzZW5zZV9kYXRhX3RleHRzW21pZF0uYXNjX2FzY3EgPiBrZXkpCgkJCQkJaGkgPSBtaWQ7CgkJCQllbHNlCgkJCQkJbG8gPSBtaWQrMTsKCQkJfQoJCX0KCgkJaWYgKHMgPT0gTlVMTCkgewoJCQlpZiAoc2Vuc2UtPmFzYyA+IDB4ODApCgkJCQlzID0gIih2ZW5kb3Itc3BlY2lmaWMgZXJyb3IpIjsKCQkJZWxzZQoJCQkJcyA9ICIocmVzZXJ2ZWQgZXJyb3IgY29kZSkiOwoJCX0KCgkJcHJpbnRrKEtFUk5fRVJSICIgICVzIC0tIChhc2M9MHglMDJ4LCBhc2NxPTB4JTAyeClcbiIsCgkJCXMsIHNlbnNlLT5hc2MsIHNlbnNlLT5hc2NxKTsKCgkJaWYgKGZhaWxlZF9jb21tYW5kICE9IE5VTEwpIHsKCgkJCWludCBsbz0wLCBtaWQsIGhpPSBBUllfTEVOIChwYWNrZXRfY29tbWFuZF90ZXh0cyk7CgkJCXMgPSBOVUxMOwoKCQkJd2hpbGUgKGhpID4gbG8pIHsKCQkJCW1pZCA9IChsbyArIGhpKSAvIDI7CgkJCQlpZiAocGFja2V0X2NvbW1hbmRfdGV4dHNbbWlkXS5wYWNrZXRfY29tbWFuZCA9PQoJCQkJICAgIGZhaWxlZF9jb21tYW5kLT5jbWRbMF0pIHsKCQkJCQlzID0gcGFja2V0X2NvbW1hbmRfdGV4dHNbbWlkXS50ZXh0OwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJaWYgKHBhY2tldF9jb21tYW5kX3RleHRzW21pZF0ucGFja2V0X2NvbW1hbmQgPgoJCQkJICAgIGZhaWxlZF9jb21tYW5kLT5jbWRbMF0pCgkJCQkJaGkgPSBtaWQ7CgkJCQllbHNlCgkJCQkJbG8gPSBtaWQrMTsKCQkJfQoKCQkJcHJpbnRrIChLRVJOX0VSUiAiICBUaGUgZmFpbGVkIFwiJXNcIiBwYWNrZXQgY29tbWFuZCB3YXM6IFxuICBcIiIsIHMpOwoJCQlmb3IgKGk9MDsgaTxzaXplb2YgKGZhaWxlZF9jb21tYW5kLT5jbWQpOyBpKyspCgkJCQlwcmludGsgKCIlMDJ4ICIsIGZhaWxlZF9jb21tYW5kLT5jbWRbaV0pOwoJCQlwcmludGsgKCJcIlxuIik7CgkJfQoKCQkvKiBUaGUgU0tTViBiaXQgc3BlY2lmaWVzIHZhbGlkaXR5IG9mIHRoZSBzZW5zZV9rZXlfc3BlY2lmaWMKCQkgKiBpbiB0aGUgbmV4dCB0d28gY29tbWFuZHMuIEl0IGlzIGJpdCA3IG9mIHRoZSBmaXJzdCBieXRlLgoJCSAqIEluIHRoZSBjYXNlIG9mIE5PVF9SRUFEWSwgaWYgU0tTViBpcyBzZXQgdGhlIGRyaXZlIGNhbgoJCSAqIGdpdmUgdXMgbmljZSBFVEEgcmVhZGluZ3MuCgkJICovCgkJaWYgKHNlbnNlLT5zZW5zZV9rZXkgPT0gTk9UX1JFQURZICYmIChzZW5zZS0+c2tzWzBdICYgMHg4MCkpIHsKCQkJaW50IHByb2dyZXNzID0gKHNlbnNlLT5za3NbMV0gPDwgOCB8IHNlbnNlLT5za3NbMl0pICogMTAwOwoJCQlwcmludGsoS0VSTl9FUlIgIiAgQ29tbWFuZCBpcyAlMDJkJSUgY29tcGxldGVcbiIsIHByb2dyZXNzIC8gMHhmZmZmKTsKCgkJfQoKCQlpZiAoc2Vuc2UtPnNlbnNlX2tleSA9PSBJTExFR0FMX1JFUVVFU1QgJiYKCQkgICAgKHNlbnNlLT5za3NbMF0gJiAweDgwKSAhPSAwKSB7CgkJCXByaW50ayhLRVJOX0VSUiAiICBFcnJvciBpbiAlcyBieXRlICVkIiwKCQkJCShzZW5zZS0+c2tzWzBdICYgMHg0MCkgIT0gMCA/CgkJCQkiY29tbWFuZCBwYWNrZXQiIDogImNvbW1hbmQgZGF0YSIsCgkJCQkoc2Vuc2UtPnNrc1sxXSA8PCA4KSArIHNlbnNlLT5za3NbMl0pOwoKCQkJaWYgKChzZW5zZS0+c2tzWzBdICYgMHg0MCkgIT0gMCkKCQkJCXByaW50ayAoIiBiaXQgJWQiLCBzZW5zZS0+c2tzWzBdICYgMHgwNyk7CgoJCQlwcmludGsgKCJcbiIpOwoJCX0KCX0KCiNlbHNlIC8qIG5vdCBWRVJCT1NFX0lERV9DRF9FUlJPUlMgKi8KCgkvKiBTdXBwcmVzcyBwcmludGluZyB1bml0IGF0dGVudGlvbiBhbmQgYGluIHByb2dyZXNzIG9mIGJlY29taW5nIHJlYWR5JwoJICAgZXJyb3JzIHdoZW4gd2UncmUgbm90IGJlaW5nIHZlcmJvc2UuICovCgoJaWYgKHNlbnNlLT5zZW5zZV9rZXkgPT0gVU5JVF9BVFRFTlRJT04gfHwKCSAgICAoc2Vuc2UtPnNlbnNlX2tleSA9PSBOT1RfUkVBRFkgJiYgKHNlbnNlLT5hc2MgPT0gNCB8fAoJCQkJCQlzZW5zZS0+YXNjID09IDB4M2EpKSkKCQlyZXR1cm47CgoJcHJpbnRrKEtFUk5fRVJSICIlczogZXJyb3IgY29kZTogMHglMDJ4ICBzZW5zZV9rZXk6IDB4JTAyeCAgYXNjOiAweCUwMnggIGFzY3E6IDB4JTAyeFxuIiwKCQlkcml2ZS0+bmFtZSwKCQlzZW5zZS0+ZXJyb3JfY29kZSwgc2Vuc2UtPnNlbnNlX2tleSwKCQlzZW5zZS0+YXNjLCBzZW5zZS0+YXNjcSk7CiNlbmRpZiAvKiBub3QgVkVSQk9TRV9JREVfQ0RfRVJST1JTICovCn0KCi8qCiAqIEluaXRpYWxpemUgYSBpZGUtY2QgcGFja2V0IGNvbW1hbmQgcmVxdWVzdAogKi8Kc3RhdGljIHZvaWQgY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGlkZV9kcml2ZV90ICpkcml2ZSwgc3RydWN0IHJlcXVlc3QgKnJxKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqY2QgPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CgoJaWRlX2luaXRfZHJpdmVfY21kKHJxKTsKCXJxLT5mbGFncyA9IFJFUV9QQzsKCXJxLT5ycV9kaXNrID0gY2QtPmRpc2s7Cn0KCnN0YXRpYyB2b2lkIGNkcm9tX3F1ZXVlX3JlcXVlc3Rfc2Vuc2UoaWRlX2RyaXZlX3QgKmRyaXZlLCB2b2lkICpzZW5zZSwKCQkJCSAgICAgIHN0cnVjdCByZXF1ZXN0ICpmYWlsZWRfY29tbWFuZCkKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8JCT0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJc3RydWN0IHJlcXVlc3QgKnJxCQk9ICZpbmZvLT5yZXF1ZXN0X3NlbnNlX3JlcXVlc3Q7CgoJaWYgKHNlbnNlID09IE5VTEwpCgkJc2Vuc2UgPSAmaW5mby0+c2Vuc2VfZGF0YTsKCgkvKiBzdHVmZiB0aGUgc2Vuc2UgcmVxdWVzdCBpbiBmcm9udCBvZiBvdXIgY3VycmVudCByZXF1ZXN0ICovCgljZHJvbV9wcmVwYXJlX3JlcXVlc3QoZHJpdmUsIHJxKTsKCglycS0+ZGF0YSA9IHNlbnNlOwoJcnEtPmNtZFswXSA9IEdQQ01EX1JFUVVFU1RfU0VOU0U7CglycS0+Y21kWzRdID0gcnEtPmRhdGFfbGVuID0gMTg7CgoJcnEtPmZsYWdzID0gUkVRX1NFTlNFOwoKCS8qIE5PVEUhIFNhdmUgdGhlIGZhaWxlZCBjb21tYW5kIGluICJycS0+YnVmZmVyIiAqLwoJcnEtPmJ1ZmZlciA9ICh2b2lkICopIGZhaWxlZF9jb21tYW5kOwoKCSh2b2lkKSBpZGVfZG9fZHJpdmVfY21kKGRyaXZlLCBycSwgaWRlX3ByZWVtcHQpOwp9CgpzdGF0aWMgdm9pZCBjZHJvbV9lbmRfcmVxdWVzdCAoaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgdXB0b2RhdGUpCnsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCWludCBuc2VjdG9ycyA9IHJxLT5oYXJkX2N1cl9zZWN0b3JzOwoKCWlmICgocnEtPmZsYWdzICYgUkVRX1NFTlNFKSAmJiB1cHRvZGF0ZSkgewoJCS8qCgkJICogRm9yIFJFUV9TRU5TRSwgInJxLT5idWZmZXIiIHBvaW50cyB0byB0aGUgb3JpZ2luYWwgZmFpbGVkCgkJICogcmVxdWVzdAoJCSAqLwoJCXN0cnVjdCByZXF1ZXN0ICpmYWlsZWQgPSAoc3RydWN0IHJlcXVlc3QgKikgcnEtPmJ1ZmZlcjsKCQlzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCQl2b2lkICpzZW5zZSA9ICZpbmZvLT5zZW5zZV9kYXRhOwoJCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJCWlmIChmYWlsZWQpIHsKCQkJaWYgKGZhaWxlZC0+c2Vuc2UpIHsKCQkJCXNlbnNlID0gZmFpbGVkLT5zZW5zZTsKCQkJCWZhaWxlZC0+c2Vuc2VfbGVuID0gcnEtPnNlbnNlX2xlbjsKCQkJfQoKCQkJLyoKCQkJICogbm93IGVuZCBmYWlsZWQgcmVxdWVzdAoJCQkgKi8KCQkJc3Bpbl9sb2NrX2lycXNhdmUoJmlkZV9sb2NrLCBmbGFncyk7CgkJCWVuZF90aGF0X3JlcXVlc3RfY2h1bmsoZmFpbGVkLCAwLCBmYWlsZWQtPmRhdGFfbGVuKTsKCQkJZW5kX3RoYXRfcmVxdWVzdF9sYXN0KGZhaWxlZCk7CgkJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmlkZV9sb2NrLCBmbGFncyk7CgkJfQoKCQljZHJvbV9hbmFseXplX3NlbnNlX2RhdGEoZHJpdmUsIGZhaWxlZCwgc2Vuc2UpOwoJfQoKCWlmICghcnEtPmN1cnJlbnRfbnJfc2VjdG9ycyAmJiBibGtfZnNfcmVxdWVzdChycSkpCgkJdXB0b2RhdGUgPSAxOwoJLyogbWFrZSBzdXJlIGl0J3MgZnVsbHkgZW5kZWQgKi8KCWlmIChibGtfcGNfcmVxdWVzdChycSkpCgkJbnNlY3RvcnMgPSAocnEtPmRhdGFfbGVuICsgNTExKSA+PiA5OwoJaWYgKCFuc2VjdG9ycykKCQluc2VjdG9ycyA9IDE7CgoJaWRlX2VuZF9yZXF1ZXN0KGRyaXZlLCB1cHRvZGF0ZSwgbnNlY3RvcnMpOwp9CgovKiBSZXR1cm5zIDAgaWYgdGhlIHJlcXVlc3Qgc2hvdWxkIGJlIGNvbnRpbnVlZC4KICAgUmV0dXJucyAxIGlmIHRoZSByZXF1ZXN0IHdhcyBlbmRlZC4gKi8Kc3RhdGljIGludCBjZHJvbV9kZWNvZGVfc3RhdHVzKGlkZV9kcml2ZV90ICpkcml2ZSwgaW50IGdvb2Rfc3RhdCwgaW50ICpzdGF0X3JldCkKewoJc3RydWN0IHJlcXVlc3QgKnJxID0gSFdHUk9VUChkcml2ZSktPnJxOwoJaW50IHN0YXQsIGVyciwgc2Vuc2Vfa2V5OwoJCgkvKiBDaGVjayBmb3IgZXJyb3JzLiAqLwoJc3RhdCA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX1NUQVRVU19SRUcpOwoJaWYgKHN0YXRfcmV0KQoJCSpzdGF0X3JldCA9IHN0YXQ7CgoJaWYgKE9LX1NUQVQoc3RhdCwgZ29vZF9zdGF0LCBCQURfUl9TVEFUKSkKCQlyZXR1cm4gMDsKCgkvKiBHZXQgdGhlIElERSBlcnJvciByZWdpc3Rlci4gKi8KCWVyciA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX0VSUk9SX1JFRyk7CglzZW5zZV9rZXkgPSBlcnIgPj4gNDsKCglpZiAocnEgPT0gTlVMTCkgewoJCXByaW50aygiJXM6IG1pc3NpbmcgcnEgaW4gY2Ryb21fZGVjb2RlX3N0YXR1c1xuIiwgZHJpdmUtPm5hbWUpOwoJCXJldHVybiAxOwoJfQoKCWlmIChycS0+ZmxhZ3MgJiBSRVFfU0VOU0UpIHsKCQkvKiBXZSBnb3QgYW4gZXJyb3IgdHJ5aW5nIHRvIGdldCBzZW5zZSBpbmZvCgkJICAgZnJvbSB0aGUgZHJpdmUgKHByb2JhYmx5IHdoaWxlIHRyeWluZwoJCSAgIHRvIHJlY292ZXIgZnJvbSBhIGZvcm1lciBlcnJvcikuICBKdXN0IGdpdmUgdXAuICovCgoJCXJxLT5mbGFncyB8PSBSRVFfRkFJTEVEOwoJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAwKTsKCQlpZGVfZXJyb3IoZHJpdmUsICJyZXF1ZXN0IHNlbnNlIGZhaWx1cmUiLCBzdGF0KTsKCQlyZXR1cm4gMTsKCgl9IGVsc2UgaWYgKHJxLT5mbGFncyAmIChSRVFfUEMgfCBSRVFfQkxPQ0tfUEMpKSB7CgkJLyogQWxsIG90aGVyIGZ1bmN0aW9ucywgZXhjZXB0IGZvciBSRUFELiAqLwoJCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJCS8qCgkJICogaWYgd2UgaGF2ZSBhbiBlcnJvciwgcGFzcyBiYWNrIENIRUNLX0NPTkRJVElPTiBhcyB0aGUKCQkgKiBzY3NpIHN0YXR1cyBieXRlCgkJICovCgkJaWYgKChycS0+ZmxhZ3MgJiBSRVFfQkxPQ0tfUEMpICYmICFycS0+ZXJyb3JzKQoJCQlycS0+ZXJyb3JzID0gU0FNX1NUQVRfQ0hFQ0tfQ09ORElUSU9OOwoKCQkvKiBDaGVjayBmb3IgdHJheSBvcGVuLiAqLwoJCWlmIChzZW5zZV9rZXkgPT0gTk9UX1JFQURZKSB7CgkJCWNkcm9tX3Nhd19tZWRpYV9jaGFuZ2UgKGRyaXZlKTsKCQl9IGVsc2UgaWYgKHNlbnNlX2tleSA9PSBVTklUX0FUVEVOVElPTikgewoJCQkvKiBDaGVjayBmb3IgbWVkaWEgY2hhbmdlLiAqLwoJCQljZHJvbV9zYXdfbWVkaWFfY2hhbmdlIChkcml2ZSk7CgkJCS8qcHJpbnRrKCIlczogbWVkaWEgY2hhbmdlZFxuIixkcml2ZS0+bmFtZSk7Ki8KCQkJcmV0dXJuIDA7CgkJfSBlbHNlIGlmICghKHJxLT5mbGFncyAmIFJFUV9RVUlFVCkpIHsKCQkJLyogT3RoZXJ3aXNlLCBwcmludCBhbiBlcnJvci4gKi8KCQkJaWRlX2R1bXBfc3RhdHVzKGRyaXZlLCAicGFja2V0IGNvbW1hbmQgZXJyb3IiLCBzdGF0KTsKCQl9CgkJCgkJcnEtPmZsYWdzIHw9IFJFUV9GQUlMRUQ7CgoJCS8qCgkJICogaW5zdGVhZCBvZiBwbGF5aW5nIGdhbWVzIHdpdGggbW92aW5nIGNvbXBsZXRpb25zIGFyb3VuZCwKCQkgKiByZW1vdmUgZmFpbGVkIHJlcXVlc3QgY29tcGxldGVseSBhbmQgZW5kIGl0IHdoZW4gdGhlCgkJICogcmVxdWVzdCBzZW5zZSBoYXMgY29tcGxldGVkCgkJICovCgkJaWYgKHN0YXQgJiBFUlJfU1RBVCkgewoJCQlzcGluX2xvY2tfaXJxc2F2ZSgmaWRlX2xvY2ssIGZsYWdzKTsKCQkJYmxrZGV2X2RlcXVldWVfcmVxdWVzdChycSk7CgkJCUhXR1JPVVAoZHJpdmUpLT5ycSA9IE5VTEw7CgkJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmlkZV9sb2NrLCBmbGFncyk7CgoJCQljZHJvbV9xdWV1ZV9yZXF1ZXN0X3NlbnNlKGRyaXZlLCBycS0+c2Vuc2UsIHJxKTsKCQl9IGVsc2UKCQkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDApOwoKCX0gZWxzZSBpZiAoYmxrX2ZzX3JlcXVlc3QocnEpKSB7CgkJaW50IGRvX2VuZF9yZXF1ZXN0ID0gMDsKCgkJLyogSGFuZGxlIGVycm9ycyBmcm9tIFJFQUQgYW5kIFdSSVRFIHJlcXVlc3RzLiAqLwoKCQlpZiAoYmxrX25vcmV0cnlfcmVxdWVzdChycSkpCgkJCWRvX2VuZF9yZXF1ZXN0ID0gMTsKCgkJaWYgKHNlbnNlX2tleSA9PSBOT1RfUkVBRFkpIHsKCQkJLyogVHJheSBvcGVuLiAqLwoJCQlpZiAocnFfZGF0YV9kaXIocnEpID09IFJFQUQpIHsKCQkJCWNkcm9tX3Nhd19tZWRpYV9jaGFuZ2UgKGRyaXZlKTsKCgkJCQkvKiBGYWlsIHRoZSByZXF1ZXN0LiAqLwoJCQkJcHJpbnRrICgiJXM6IHRyYXkgb3BlblxuIiwgZHJpdmUtPm5hbWUpOwoJCQkJZG9fZW5kX3JlcXVlc3QgPSAxOwoJCQl9IGVsc2UgewoJCQkJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CgoJCQkJLyogYWxsb3cgdGhlIGRyaXZlIDUgc2Vjb25kcyB0byByZWNvdmVyLCBzb21lCgkJCQkgKiBkZXZpY2VzIHdpbGwgcmV0dXJuIHRoaXMgZXJyb3Igd2hpbGUgZmx1c2hpbmcKCQkJCSAqIGRhdGEgZnJvbSBjYWNoZSAqLwoJCQkJaWYgKCFycS0+ZXJyb3JzKQoJCQkJCWluZm8tPndyaXRlX3RpbWVvdXQgPSBqaWZmaWVzICsgQVRBUElfV0FJVF9XUklURV9CVVNZOwoJCQkJcnEtPmVycm9ycyA9IDE7CgkJCQlpZiAodGltZV9hZnRlcihqaWZmaWVzLCBpbmZvLT53cml0ZV90aW1lb3V0KSkKCQkJCQlkb19lbmRfcmVxdWVzdCA9IDE7CgkJCQllbHNlIHsKCQkJCQl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCQkJCQkvKgoJCQkJCSAqIHRha2UgYSBicmVhdGhlciByZWx5aW5nIG9uIHRoZQoJCQkJCSAqIHVucGx1ZyB0aW1lciB0byBraWNrIHVzIGFnYWluCgkJCQkJICovCgkJCQkJc3Bpbl9sb2NrX2lycXNhdmUoJmlkZV9sb2NrLCBmbGFncyk7CgkJCQkJYmxrX3BsdWdfZGV2aWNlKGRyaXZlLT5xdWV1ZSk7CgkJCQkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmaWRlX2xvY2ssZmxhZ3MpOwoJCQkJCXJldHVybiAxOwoJCQkJfQoJCQl9CgkJfSBlbHNlIGlmIChzZW5zZV9rZXkgPT0gVU5JVF9BVFRFTlRJT04pIHsKCQkJLyogTWVkaWEgY2hhbmdlLiAqLwoJCQljZHJvbV9zYXdfbWVkaWFfY2hhbmdlIChkcml2ZSk7CgoJCQkvKiBBcnJhbmdlIHRvIHJldHJ5IHRoZSByZXF1ZXN0LgoJCQkgICBCdXQgYmUgc3VyZSB0byBnaXZlIHVwIGlmIHdlJ3ZlIHJldHJpZWQKCQkJICAgdG9vIG1hbnkgdGltZXMuICovCgkJCWlmICgrK3JxLT5lcnJvcnMgPiBFUlJPUl9NQVgpCgkJCQlkb19lbmRfcmVxdWVzdCA9IDE7CgkJfSBlbHNlIGlmIChzZW5zZV9rZXkgPT0gSUxMRUdBTF9SRVFVRVNUIHx8CgkJCSAgIHNlbnNlX2tleSA9PSBEQVRBX1BST1RFQ1QpIHsKCQkJLyogTm8gcG9pbnQgaW4gcmV0cnlpbmcgYWZ0ZXIgYW4gaWxsZWdhbAoJCQkgICByZXF1ZXN0IG9yIGRhdGEgcHJvdGVjdCBlcnJvci4qLwoJCQlpZGVfZHVtcF9zdGF0dXMgKGRyaXZlLCAiY29tbWFuZCBlcnJvciIsIHN0YXQpOwoJCQlkb19lbmRfcmVxdWVzdCA9IDE7CgkJfSBlbHNlIGlmIChzZW5zZV9rZXkgPT0gTUVESVVNX0VSUk9SKSB7CgkJCS8qIE5vIHBvaW50IGluIHJlLXRyeWluZyBhIHppbGxpb24gdGltZXMgb24gYSBiYWQgCgkJCSAqIHNlY3Rvci4uLiAgSWYgd2UgZ290IGhlcmUgdGhlIGVycm9yIGlzIG5vdCBjb3JyZWN0YWJsZSAqLwoJCQlpZGVfZHVtcF9zdGF0dXMgKGRyaXZlLCAibWVkaWEgZXJyb3IgKGJhZCBzZWN0b3IpIiwgc3RhdCk7CgkJCWRvX2VuZF9yZXF1ZXN0ID0gMTsKCQl9IGVsc2UgaWYgKHNlbnNlX2tleSA9PSBCTEFOS19DSEVDSykgewoJCQkvKiBEaXNrIGFwcGVhcnMgYmxhbmsgPz8gKi8KCQkJaWRlX2R1bXBfc3RhdHVzIChkcml2ZSwgIm1lZGlhIGVycm9yIChibGFuaykiLCBzdGF0KTsKCQkJZG9fZW5kX3JlcXVlc3QgPSAxOwoJCX0gZWxzZSBpZiAoKGVyciAmIH5BQlJUX0VSUikgIT0gMCkgewoJCQkvKiBHbyB0byB0aGUgZGVmYXVsdCBoYW5kbGVyCgkJCSAgIGZvciBvdGhlciBlcnJvcnMuICovCgkJCWlkZV9lcnJvcihkcml2ZSwgImNkcm9tX2RlY29kZV9zdGF0dXMiLCBzdGF0KTsKCQkJcmV0dXJuIDE7CgkJfSBlbHNlIGlmICgoKytycS0+ZXJyb3JzID4gRVJST1JfTUFYKSkgewoJCQkvKiBXZSd2ZSByYWNrZWQgdXAgdG9vIG1hbnkgcmV0cmllcy4gIEFib3J0LiAqLwoJCQlkb19lbmRfcmVxdWVzdCA9IDE7CgkJfQoKCQlpZiAoZG9fZW5kX3JlcXVlc3QpCgkJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAwKTsKCgkJLyogSWYgd2UgZ290IGEgQ0hFQ0tfQ09ORElUSU9OIHN0YXR1cywKCQkgICBxdWV1ZSBhIHJlcXVlc3Qgc2Vuc2UgY29tbWFuZC4gKi8KCQlpZiAoKHN0YXQgJiBFUlJfU1RBVCkgIT0gMCkKCQkJY2Ryb21fcXVldWVfcmVxdWVzdF9zZW5zZShkcml2ZSwgTlVMTCwgTlVMTCk7Cgl9IGVsc2UgewoJCWJsa19kdW1wX3JxX2ZsYWdzKHJxLCAiaWRlLWNkOiBiYWQgcnEiKTsKCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7Cgl9CgoJLyogUmV0cnksIG9yIGhhbmRsZSB0aGUgbmV4dCByZXF1ZXN0LiAqLwoJcmV0dXJuIDE7Cn0KCnN0YXRpYyBpbnQgY2Ryb21fdGltZXJfZXhwaXJ5KGlkZV9kcml2ZV90ICpkcml2ZSkKewoJc3RydWN0IHJlcXVlc3QgKnJxID0gSFdHUk9VUChkcml2ZSktPnJxOwoJdW5zaWduZWQgbG9uZyB3YWl0ID0gMDsKCgkvKgoJICogU29tZSBjb21tYW5kcyBhcmUgKnNsb3cqIGFuZCBub3JtYWxseSB0YWtlIGEgbG9uZyB0aW1lIHRvCgkgKiBjb21wbGV0ZS4gVXN1YWxseSB3ZSBjYW4gdXNlIHRoZSBBVEFQSSAiZGlzY29ubmVjdCIgdG8gYnlwYXNzCgkgKiB0aGlzLCBidXQgbm90IGFsbCBjb21tYW5kcy9kcml2ZXMgc3VwcG9ydCB0aGF0LiBMZXQKCSAqIGlkZV90aW1lcl9leHBpcnkga2VlcCBwb2xsaW5nIHVzIGZvciB0aGVzZS4KCSAqLwoJc3dpdGNoIChycS0+Y21kWzBdKSB7CgkJY2FzZSBHUENNRF9CTEFOSzoKCQljYXNlIEdQQ01EX0ZPUk1BVF9VTklUOgoJCWNhc2UgR1BDTURfUkVTRVJWRV9SWk9ORV9UUkFDSzoKCQljYXNlIEdQQ01EX0NMT1NFX1RSQUNLOgoJCWNhc2UgR1BDTURfRkxVU0hfQ0FDSEU6CgkJCXdhaXQgPSBBVEFQSV9XQUlUX1BDOwoJCQlicmVhazsKCQlkZWZhdWx0OgoJCQlpZiAoIShycS0+ZmxhZ3MgJiBSRVFfUVVJRVQpKQoJCQkJcHJpbnRrKEtFUk5fSU5GTyAiaWRlLWNkOiBjbWQgMHgleCB0aW1lZCBvdXRcbiIsIHJxLT5jbWRbMF0pOwoJCQl3YWl0ID0gMDsKCQkJYnJlYWs7Cgl9CglyZXR1cm4gd2FpdDsKfQoKLyogU2V0IHVwIHRoZSBkZXZpY2UgcmVnaXN0ZXJzIGZvciB0cmFuc2ZlcnJpbmcgYSBwYWNrZXQgY29tbWFuZCBvbiBERVYsCiAgIGV4cGVjdGluZyB0byBsYXRlciB0cmFuc2ZlciBYRkVSTEVOIGJ5dGVzLiAgSEFORExFUiBpcyB0aGUgcm91dGluZQogICB3aGljaCBhY3R1YWxseSB0cmFuc2ZlcnMgdGhlIGNvbW1hbmQgdG8gdGhlIGRyaXZlLiAgSWYgdGhpcyBpcyBhCiAgIGRycV9pbnRlcnJ1cHQgZGV2aWNlLCB0aGlzIHJvdXRpbmUgd2lsbCBhcnJhbmdlIGZvciBIQU5ETEVSIHRvIGJlCiAgIGNhbGxlZCB3aGVuIHRoZSBpbnRlcnJ1cHQgZnJvbSB0aGUgZHJpdmUgYXJyaXZlcy4gIE90aGVyd2lzZSwgSEFORExFUgogICB3aWxsIGJlIGNhbGxlZCBpbW1lZGlhdGVseSBhZnRlciB0aGUgZHJpdmUgaXMgcHJlcGFyZWQgZm9yIHRoZSB0cmFuc2Zlci4gKi8KCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fc3RhcnRfcGFja2V0X2NvbW1hbmQoaWRlX2RyaXZlX3QgKmRyaXZlLAoJCQkJCQkgIGludCB4ZmVybGVuLAoJCQkJCQkgIGlkZV9oYW5kbGVyX3QgKmhhbmRsZXIpCnsKCWlkZV9zdGFydHN0b3BfdCBzdGFydHN0b3A7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCWlkZV9od2lmX3QgKmh3aWYgPSBkcml2ZS0+aHdpZjsKCgkvKiBXYWl0IGZvciB0aGUgY29udHJvbGxlciB0byBiZSBpZGxlLiAqLwoJaWYgKGlkZV93YWl0X3N0YXQoJnN0YXJ0c3RvcCwgZHJpdmUsIDAsIEJVU1lfU1RBVCwgV0FJVF9SRUFEWSkpCgkJcmV0dXJuIHN0YXJ0c3RvcDsKCglpZiAoaW5mby0+ZG1hKQoJCWluZm8tPmRtYSA9ICFod2lmLT5kbWFfc2V0dXAoZHJpdmUpOwoKCS8qIFNldCB1cCB0aGUgY29udHJvbGxlciByZWdpc3RlcnMuICovCgkvKiBGSVhNRTogZm9yIFZpcnR1YWwgRE1BIHdlIG11c3QgY2hlY2sgaGFyZGVyICovCglIV0lGKGRyaXZlKS0+T1VUQihpbmZvLT5kbWEsIElERV9GRUFUVVJFX1JFRyk7CglIV0lGKGRyaXZlKS0+T1VUQigwLCBJREVfSVJFQVNPTl9SRUcpOwoJSFdJRihkcml2ZSktPk9VVEIoMCwgSURFX1NFQ1RPUl9SRUcpOwoKCUhXSUYoZHJpdmUpLT5PVVRCKHhmZXJsZW4gJiAweGZmLCBJREVfQkNPVU5UTF9SRUcpOwoJSFdJRihkcml2ZSktPk9VVEIoeGZlcmxlbiA+PiA4ICAsIElERV9CQ09VTlRIX1JFRyk7CglpZiAoSURFX0NPTlRST0xfUkVHKQoJCUhXSUYoZHJpdmUpLT5PVVRCKGRyaXZlLT5jdGwsIElERV9DT05UUk9MX1JFRyk7CiAKCWlmIChDRFJPTV9DT05GSUdfRkxBR1MgKGRyaXZlKS0+ZHJxX2ludGVycnVwdCkgewoJCS8qIHBhY2tldCBjb21tYW5kICovCgkJaWRlX2V4ZWN1dGVfY29tbWFuZChkcml2ZSwgV0lOX1BBQ0tFVENNRCwgaGFuZGxlciwgQVRBUElfV0FJVF9QQywgY2Ryb21fdGltZXJfZXhwaXJ5KTsKCQlyZXR1cm4gaWRlX3N0YXJ0ZWQ7Cgl9IGVsc2UgewoJCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJCS8qIHBhY2tldCBjb21tYW5kICovCgkJc3Bpbl9sb2NrX2lycXNhdmUoJmlkZV9sb2NrLCBmbGFncyk7CgkJaHdpZi0+T1VUQlNZTkMoZHJpdmUsIFdJTl9QQUNLRVRDTUQsIElERV9DT01NQU5EX1JFRyk7CgkJbmRlbGF5KDQwMCk7CgkJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmaWRlX2xvY2ssIGZsYWdzKTsKCgkJcmV0dXJuICgqaGFuZGxlcikgKGRyaXZlKTsKCX0KfQoKLyogU2VuZCBhIHBhY2tldCBjb21tYW5kIHRvIERSSVZFIGRlc2NyaWJlZCBieSBDTURfQlVGIGFuZCBDTURfTEVOLgogICBUaGUgZGV2aWNlIHJlZ2lzdGVycyBtdXN0IGhhdmUgYWxyZWFkeSBiZWVuIHByZXBhcmVkCiAgIGJ5IGNkcm9tX3N0YXJ0X3BhY2tldF9jb21tYW5kLgogICBIQU5ETEVSIGlzIHRoZSBpbnRlcnJ1cHQgaGFuZGxlciB0byBjYWxsIHdoZW4gdGhlIGNvbW1hbmQgY29tcGxldGVzCiAgIG9yIHRoZXJlJ3MgZGF0YSByZWFkeS4gKi8KLyoKICogY2hhbmdlZCA1IHBhcmFtZXRlcnMgdG8gMyBmb3IgZHZkLXJhbQogKiBzdHJ1Y3QgcGFja2V0X2NvbW1hbmQgKnBjOyBub3cgcGFja2V0X2NvbW1hbmRfdCAqcGM7CiAqLwojZGVmaW5lIEFUQVBJX01JTl9DREJfQllURVMgMTIKc3RhdGljIGlkZV9zdGFydHN0b3BfdCBjZHJvbV90cmFuc2Zlcl9wYWNrZXRfY29tbWFuZCAoaWRlX2RyaXZlX3QgKmRyaXZlLAoJCQkJCSAgc3RydWN0IHJlcXVlc3QgKnJxLAoJCQkJCSAgaWRlX2hhbmRsZXJfdCAqaGFuZGxlcikKewoJaWRlX2h3aWZfdCAqaHdpZiA9IGRyaXZlLT5od2lmOwoJaW50IGNtZF9sZW47CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCWlkZV9zdGFydHN0b3BfdCBzdGFydHN0b3A7CgoJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmRycV9pbnRlcnJ1cHQpIHsKCQkvKiBIZXJlIHdlIHNob3VsZCBoYXZlIGJlZW4gY2FsbGVkIGFmdGVyIHJlY2VpdmluZyBhbiBpbnRlcnJ1cHQKCQkgICBmcm9tIHRoZSBkZXZpY2UuICBEUlEgc2hvdWxkIGhvdyBiZSBzZXQuICovCgoJCS8qIENoZWNrIGZvciBlcnJvcnMuICovCgkJaWYgKGNkcm9tX2RlY29kZV9zdGF0dXMoZHJpdmUsIERSUV9TVEFULCBOVUxMKSkKCQkJcmV0dXJuIGlkZV9zdG9wcGVkOwoJfSBlbHNlIHsKCQkvKiBPdGhlcndpc2UsIHdlIG11c3Qgd2FpdCBmb3IgRFJRIHRvIGdldCBzZXQuICovCgkJaWYgKGlkZV93YWl0X3N0YXQoJnN0YXJ0c3RvcCwgZHJpdmUsIERSUV9TVEFULAoJCQkJQlVTWV9TVEFULCBXQUlUX1JFQURZKSkKCQkJcmV0dXJuIHN0YXJ0c3RvcDsKCX0KCgkvKiBBcm0gdGhlIGludGVycnVwdCBoYW5kbGVyLiAqLwoJaWRlX3NldF9oYW5kbGVyKGRyaXZlLCBoYW5kbGVyLCBycS0+dGltZW91dCwgY2Ryb21fdGltZXJfZXhwaXJ5KTsKCgkvKiBBVEFQSSBjb21tYW5kcyBnZXQgcGFkZGVkIG91dCB0byAxMiBieXRlcyBtaW5pbXVtICovCgljbWRfbGVuID0gQ09NTUFORF9TSVpFKHJxLT5jbWRbMF0pOwoJaWYgKGNtZF9sZW4gPCBBVEFQSV9NSU5fQ0RCX0JZVEVTKQoJCWNtZF9sZW4gPSBBVEFQSV9NSU5fQ0RCX0JZVEVTOwoKCS8qIFNlbmQgdGhlIGNvbW1hbmQgdG8gdGhlIGRldmljZS4gKi8KCUhXSUYoZHJpdmUpLT5hdGFwaV9vdXRwdXRfYnl0ZXMoZHJpdmUsIHJxLT5jbWQsIGNtZF9sZW4pOwoKCS8qIFN0YXJ0IHRoZSBETUEgaWYgbmVlZCBiZSAqLwoJaWYgKGluZm8tPmRtYSkKCQlod2lmLT5kbWFfc3RhcnQoZHJpdmUpOwoKCXJldHVybiBpZGVfc3RhcnRlZDsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogQmxvY2sgcmVhZCBmdW5jdGlvbnMuCiAqLwoKLyoKICogQnVmZmVyIHVwIHRvIFNFQ1RPUlNfVE9fVFJBTlNGRVIgc2VjdG9ycyBmcm9tIHRoZSBkcml2ZSBpbiBvdXIgc2VjdG9yCiAqIGJ1ZmZlci4gIE9uY2UgdGhlIGZpcnN0IHNlY3RvciBpcyBhZGRlZCwgYW55IHN1YnNlcXVlbnQgc2VjdG9ycyBhcmUKICogYXNzdW1lZCB0byBiZSBjb250aW51b3VzICh1bnRpbCB0aGUgYnVmZmVyIGlzIGNsZWFyZWQpLiAgRm9yIHRoZSBmaXJzdAogKiBzZWN0b3IgYWRkZWQsIFNFQ1RPUiBpcyBpdHMgc2VjdG9yIG51bWJlci4gIChTRUNUT1IgaXMgdGhlbiBpZ25vcmVkIHVudGlsCiAqIHRoZSBidWZmZXIgaXMgY2xlYXJlZC4pCiAqLwpzdGF0aWMgdm9pZCBjZHJvbV9idWZmZXJfc2VjdG9ycyAoaWRlX2RyaXZlX3QgKmRyaXZlLCB1bnNpZ25lZCBsb25nIHNlY3RvciwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGludCBzZWN0b3JzX3RvX3RyYW5zZmVyKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCgkvKiBOdW1iZXIgb2Ygc2VjdG9ycyB0byByZWFkIGludG8gdGhlIGJ1ZmZlci4gKi8KCWludCBzZWN0b3JzX3RvX2J1ZmZlciA9IG1pbl90KGludCwgc2VjdG9yc190b190cmFuc2ZlciwKCQkJCSAgICAgKFNFQ1RPUl9CVUZGRVJfU0laRSA+PiBTRUNUT1JfQklUUykgLQoJCQkJICAgICAgIGluZm8tPm5zZWN0b3JzX2J1ZmZlcmVkKTsKCgljaGFyICpkZXN0OwoKCS8qIElmIHdlIGNvdWxkbid0IGdldCBhIGJ1ZmZlciwgZG9uJ3QgdHJ5IHRvIGJ1ZmZlciBhbnl0aGluZy4uLiAqLwoJaWYgKGluZm8tPmJ1ZmZlciA9PSBOVUxMKQoJCXNlY3RvcnNfdG9fYnVmZmVyID0gMDsKCgkvKiBJZiB0aGlzIGlzIHRoZSBmaXJzdCBzZWN0b3IgaW4gdGhlIGJ1ZmZlciwgcmVtZW1iZXIgaXRzIG51bWJlci4gKi8KCWlmIChpbmZvLT5uc2VjdG9yc19idWZmZXJlZCA9PSAwKQoJCWluZm8tPnNlY3Rvcl9idWZmZXJlZCA9IHNlY3RvcjsKCgkvKiBSZWFkIHRoZSBkYXRhIGludG8gdGhlIGJ1ZmZlci4gKi8KCWRlc3QgPSBpbmZvLT5idWZmZXIgKyBpbmZvLT5uc2VjdG9yc19idWZmZXJlZCAqIFNFQ1RPUl9TSVpFOwoJd2hpbGUgKHNlY3RvcnNfdG9fYnVmZmVyID4gMCkgewoJCUhXSUYoZHJpdmUpLT5hdGFwaV9pbnB1dF9ieXRlcyhkcml2ZSwgZGVzdCwgU0VDVE9SX1NJWkUpOwoJCS0tc2VjdG9yc190b19idWZmZXI7CgkJLS1zZWN0b3JzX3RvX3RyYW5zZmVyOwoJCSsraW5mby0+bnNlY3RvcnNfYnVmZmVyZWQ7CgkJZGVzdCArPSBTRUNUT1JfU0laRTsKCX0KCgkvKiBUaHJvdyBhd2F5IGFueSByZW1haW5pbmcgZGF0YS4gKi8KCXdoaWxlIChzZWN0b3JzX3RvX3RyYW5zZmVyID4gMCkgewoJCXN0YXRpYyBjaGFyIGR1bVtTRUNUT1JfU0laRV07CgkJSFdJRihkcml2ZSktPmF0YXBpX2lucHV0X2J5dGVzKGRyaXZlLCBkdW0sIHNpemVvZiAoZHVtKSk7CgkJLS1zZWN0b3JzX3RvX3RyYW5zZmVyOwoJfQp9CgovKgogKiBDaGVjayB0aGUgY29udGVudHMgb2YgdGhlIGludGVycnVwdCByZWFzb24gcmVnaXN0ZXIgZnJvbSB0aGUgY2Ryb20KICogYW5kIGF0dGVtcHQgdG8gcmVjb3ZlciBpZiB0aGVyZSBhcmUgcHJvYmxlbXMuICBSZXR1cm5zICAwIGlmIGV2ZXJ5dGhpbmcncwogKiBvazsgbm9uemVybyBpZiB0aGUgcmVxdWVzdCBoYXMgYmVlbiB0ZXJtaW5hdGVkLgogKi8Kc3RhdGljIGlubGluZQppbnQgY2Ryb21fcmVhZF9jaGVja19pcmVhc29uIChpZGVfZHJpdmVfdCAqZHJpdmUsIGludCBsZW4sIGludCBpcmVhc29uKQp7CglpZiAoaXJlYXNvbiA9PSAyKQoJCXJldHVybiAwOwoJZWxzZSBpZiAoaXJlYXNvbiA9PSAwKSB7CgkJLyogV2hvb3BzLi4uIFRoZSBkcml2ZSBpcyBleHBlY3RpbmcgdG8gcmVjZWl2ZSBkYXRhIGZyb20gdXMhICovCgkJcHJpbnRrKEtFUk5fRVJSICIlczogcmVhZF9pbnRyOiBEcml2ZSB3YW50cyB0byB0cmFuc2ZlciBkYXRhIHRoZSAiCgkJCQkJCSJ3cm9uZyB3YXkhXG4iLCBkcml2ZS0+bmFtZSk7CgoJCS8qIFRocm93IHNvbWUgZGF0YSBhdCB0aGUgZHJpdmUgc28gaXQgZG9lc24ndCBoYW5nCgkJICAgYW5kIHF1aXQgdGhpcyByZXF1ZXN0LiAqLwoJCXdoaWxlIChsZW4gPiAwKSB7CgkJCWludCBkdW0gPSAwOwoJCQlIV0lGKGRyaXZlKS0+YXRhcGlfb3V0cHV0X2J5dGVzKGRyaXZlLCAmZHVtLCBzaXplb2YgKGR1bSkpOwoJCQlsZW4gLT0gc2l6ZW9mIChkdW0pOwoJCX0KCX0gZWxzZSAgaWYgKGlyZWFzb24gPT0gMSkgewoJCS8qIFNvbWUgZHJpdmVzIChBU1VTKSBzZWVtIHRvIHRlbGwgdXMgdGhhdCBzdGF0dXMKCQkgKiBpbmZvIGlzIGF2YWlsYWJsZS4ganVzdCBnZXQgaXQgYW5kIGlnbm9yZS4KCQkgKi8KCQkodm9pZCkgSFdJRihkcml2ZSktPklOQihJREVfU1RBVFVTX1JFRyk7CgkJcmV0dXJuIDA7Cgl9IGVsc2UgewoJCS8qIERyaXZlIHdhbnRzIGEgY29tbWFuZCBwYWNrZXQsIG9yIGludmFsaWQgaXJlYXNvbi4uLiAqLwoJCXByaW50ayhLRVJOX0VSUiAiJXM6IHJlYWRfaW50cjogYmFkIGludGVycnVwdCByZWFzb24gJXhcbiIsIGRyaXZlLT5uYW1lLAoJCQkJCQkJCWlyZWFzb24pOwoJfQoKCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAwKTsKCXJldHVybiAtMTsKfQoKLyoKICogSW50ZXJydXB0IHJvdXRpbmUuICBDYWxsZWQgd2hlbiBhIHJlYWQgcmVxdWVzdCBoYXMgY29tcGxldGVkLgogKi8Kc3RhdGljIGlkZV9zdGFydHN0b3BfdCBjZHJvbV9yZWFkX2ludHIgKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJaW50IHN0YXQ7CglpbnQgaXJlYXNvbiwgbGVuLCBzZWN0b3JzX3RvX3RyYW5zZmVyLCBuc2tpcDsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJdTggbG93Y3lsID0gMCwgaGlnaGN5bCA9IDA7CglpbnQgZG1hID0gaW5mby0+ZG1hLCBkbWFfZXJyb3IgPSAwOwoKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCgkvKgoJICogaGFuZGxlIGRtYSBjYXNlCgkgKi8KCWlmIChkbWEpIHsKCQlpbmZvLT5kbWEgPSAwOwoJCWlmICgoZG1hX2Vycm9yID0gSFdJRihkcml2ZSktPmlkZV9kbWFfZW5kKGRyaXZlKSkpCgkJCV9faWRlX2RtYV9vZmYoZHJpdmUpOwoJfQoKCWlmIChjZHJvbV9kZWNvZGVfc3RhdHVzKGRyaXZlLCAwLCAmc3RhdCkpCgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoKCWlmIChkbWEpIHsKCQlpZiAoIWRtYV9lcnJvcikgewoJCQlpZGVfZW5kX3JlcXVlc3QoZHJpdmUsIDEsIHJxLT5ucl9zZWN0b3JzKTsKCQkJcmV0dXJuIGlkZV9zdG9wcGVkOwoJCX0gZWxzZQoJCQlyZXR1cm4gaWRlX2Vycm9yKGRyaXZlLCAiZG1hIGVycm9yIiwgc3RhdCk7Cgl9CgoJLyogUmVhZCB0aGUgaW50ZXJydXB0IHJlYXNvbiBhbmQgdGhlIHRyYW5zZmVyIGxlbmd0aC4gKi8KCWlyZWFzb24gPSBIV0lGKGRyaXZlKS0+SU5CKElERV9JUkVBU09OX1JFRykgJiAweDM7Cglsb3djeWwgID0gSFdJRihkcml2ZSktPklOQihJREVfQkNPVU5UTF9SRUcpOwoJaGlnaGN5bCA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX0JDT1VOVEhfUkVHKTsKCglsZW4gPSBsb3djeWwgKyAoMjU2ICogaGlnaGN5bCk7CgoJLyogSWYgRFJRIGlzIGNsZWFyLCB0aGUgY29tbWFuZCBoYXMgY29tcGxldGVkLiAqLwoJaWYgKChzdGF0ICYgRFJRX1NUQVQpID09IDApIHsKCQkvKiBJZiB3ZSdyZSBub3QgZG9uZSBmaWxsaW5nIHRoZSBjdXJyZW50IGJ1ZmZlciwgY29tcGxhaW4uCgkJICAgT3RoZXJ3aXNlLCBjb21wbGV0ZSB0aGUgY29tbWFuZCBub3JtYWxseS4gKi8KCQlpZiAocnEtPmN1cnJlbnRfbnJfc2VjdG9ycyA+IDApIHsKCQkJcHJpbnRrIChLRVJOX0VSUiAiJXM6IGNkcm9tX3JlYWRfaW50cjogZGF0YSB1bmRlcnJ1biAoJWQgYmxvY2tzKVxuIiwKCQkJCWRyaXZlLT5uYW1lLCBycS0+Y3VycmVudF9ucl9zZWN0b3JzKTsKCQkJcnEtPmZsYWdzIHw9IFJFUV9GQUlMRUQ7CgkJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAwKTsKCQl9IGVsc2UKCQkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDEpOwoJCXJldHVybiBpZGVfc3RvcHBlZDsKCX0KCgkvKiBDaGVjayB0aGF0IHRoZSBkcml2ZSBpcyBleHBlY3RpbmcgdG8gZG8gdGhlIHNhbWUgdGhpbmcgd2UgYXJlLiAqLwoJaWYgKGNkcm9tX3JlYWRfY2hlY2tfaXJlYXNvbiAoZHJpdmUsIGxlbiwgaXJlYXNvbikpCgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoKCS8qIEFzc3VtZSB0aGF0IHRoZSBkcml2ZSB3aWxsIGFsd2F5cyBwcm92aWRlIGRhdGEgaW4gbXVsdGlwbGVzCgkgICBvZiBhdCBsZWFzdCBTRUNUT1JfU0laRSwgYXMgaXQgZ2V0cyBoYWlyeSB0byBrZWVwIHRyYWNrCgkgICBvZiB0aGUgdHJhbnNmZXJzIG90aGVyd2lzZS4gKi8KCWlmICgobGVuICUgU0VDVE9SX1NJWkUpICE9IDApIHsKCQlwcmludGsgKEtFUk5fRVJSICIlczogY2Ryb21fcmVhZF9pbnRyOiBCYWQgdHJhbnNmZXIgc2l6ZSAlZFxuIiwKCQkJZHJpdmUtPm5hbWUsIGxlbik7CgkJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmxpbWl0X25mcmFtZXMpCgkJCXByaW50ayAoS0VSTl9FUlIgIiAgVGhpcyBkcml2ZSBpcyBub3Qgc3VwcG9ydGVkIGJ5IHRoaXMgdmVyc2lvbiBvZiB0aGUgZHJpdmVyXG4iKTsKCQllbHNlIHsKCQkJcHJpbnRrIChLRVJOX0VSUiAiICBUcnlpbmcgdG8gbGltaXQgdHJhbnNmZXIgc2l6ZXNcbiIpOwoJCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5saW1pdF9uZnJhbWVzID0gMTsKCQl9CgkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDApOwoJCXJldHVybiBpZGVfc3RvcHBlZDsKCX0KCgkvKiBUaGUgbnVtYmVyIG9mIHNlY3RvcnMgd2UgbmVlZCB0byByZWFkIGZyb20gdGhlIGRyaXZlLiAqLwoJc2VjdG9yc190b190cmFuc2ZlciA9IGxlbiAvIFNFQ1RPUl9TSVpFOwoKCS8qIEZpcnN0LCBmaWd1cmUgb3V0IGlmIHdlIG5lZWQgdG8gYml0LWJ1Y2tldAoJICAgYW55IG9mIHRoZSBsZWFkaW5nIHNlY3RvcnMuICovCgluc2tpcCA9IG1pbl90KGludCwgcnEtPmN1cnJlbnRfbnJfc2VjdG9ycyAtIGJpb19jdXJfc2VjdG9ycyhycS0+YmlvKSwgc2VjdG9yc190b190cmFuc2Zlcik7CgoJd2hpbGUgKG5za2lwID4gMCkgewoJCS8qIFdlIG5lZWQgdG8gdGhyb3cgYXdheSBhIHNlY3Rvci4gKi8KCQlzdGF0aWMgY2hhciBkdW1bU0VDVE9SX1NJWkVdOwoJCUhXSUYoZHJpdmUpLT5hdGFwaV9pbnB1dF9ieXRlcyhkcml2ZSwgZHVtLCBzaXplb2YgKGR1bSkpOwoKCQktLXJxLT5jdXJyZW50X25yX3NlY3RvcnM7CgkJLS1uc2tpcDsKCQktLXNlY3RvcnNfdG9fdHJhbnNmZXI7Cgl9CgoJLyogTm93IGxvb3Agd2hpbGUgd2Ugc3RpbGwgaGF2ZSBkYXRhIHRvIHJlYWQgZnJvbSB0aGUgZHJpdmUuICovCgl3aGlsZSAoc2VjdG9yc190b190cmFuc2ZlciA+IDApIHsKCQlpbnQgdGhpc190cmFuc2ZlcjsKCgkJLyogSWYgd2UndmUgZmlsbGVkIHRoZSBwcmVzZW50IGJ1ZmZlciBidXQgdGhlcmUncyBhbm90aGVyCgkJICAgY2hhaW5lZCBidWZmZXIgYWZ0ZXIgaXQsIG1vdmUgb24uICovCgkJaWYgKHJxLT5jdXJyZW50X25yX3NlY3RvcnMgPT0gMCAmJiBycS0+bnJfc2VjdG9ycykKCQkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDEpOwoKCQkvKiBJZiB0aGUgYnVmZmVycyBhcmUgZnVsbCwgY2FjaGUgdGhlIHJlc3Qgb2YgdGhlIGRhdGEgaW4gb3VyCgkJICAgaW50ZXJuYWwgYnVmZmVyLiAqLwoJCWlmIChycS0+Y3VycmVudF9ucl9zZWN0b3JzID09IDApIHsKCQkJY2Ryb21fYnVmZmVyX3NlY3RvcnMoZHJpdmUsIHJxLT5zZWN0b3IsIHNlY3RvcnNfdG9fdHJhbnNmZXIpOwoJCQlzZWN0b3JzX3RvX3RyYW5zZmVyID0gMDsKCQl9IGVsc2UgewoJCQkvKiBUcmFuc2ZlciBkYXRhIHRvIHRoZSBidWZmZXJzLgoJCQkgICBGaWd1cmUgb3V0IGhvdyBtYW55IHNlY3RvcnMgd2UgY2FuIHRyYW5zZmVyCgkJCSAgIHRvIHRoZSBjdXJyZW50IGJ1ZmZlci4gKi8KCQkJdGhpc190cmFuc2ZlciA9IG1pbl90KGludCwgc2VjdG9yc190b190cmFuc2ZlciwKCQkJCQkgICAgIHJxLT5jdXJyZW50X25yX3NlY3RvcnMpOwoKCQkJLyogUmVhZCB0aGlzX3RyYW5zZmVyIHNlY3RvcnMKCQkJICAgaW50byB0aGUgY3VycmVudCBidWZmZXIuICovCgkJCXdoaWxlICh0aGlzX3RyYW5zZmVyID4gMCkgewoJCQkJSFdJRihkcml2ZSktPmF0YXBpX2lucHV0X2J5dGVzKGRyaXZlLCBycS0+YnVmZmVyLCBTRUNUT1JfU0laRSk7CgkJCQlycS0+YnVmZmVyICs9IFNFQ1RPUl9TSVpFOwoJCQkJLS1ycS0+bnJfc2VjdG9yczsKCQkJCS0tcnEtPmN1cnJlbnRfbnJfc2VjdG9yczsKCQkJCSsrcnEtPnNlY3RvcjsKCQkJCS0tdGhpc190cmFuc2ZlcjsKCQkJCS0tc2VjdG9yc190b190cmFuc2ZlcjsKCQkJfQoJCX0KCX0KCgkvKiBEb25lIG1vdmluZyBkYXRhISAgV2FpdCBmb3IgYW5vdGhlciBpbnRlcnJ1cHQuICovCglpZGVfc2V0X2hhbmRsZXIoZHJpdmUsICZjZHJvbV9yZWFkX2ludHIsIEFUQVBJX1dBSVRfUEMsIE5VTEwpOwoJcmV0dXJuIGlkZV9zdGFydGVkOwp9CgovKgogKiBUcnkgdG8gc2F0aXNmeSBzb21lIG9mIHRoZSBjdXJyZW50IHJlYWQgcmVxdWVzdCBmcm9tIG91ciBjYWNoZWQgZGF0YS4KICogUmV0dXJucyBub256ZXJvIGlmIHRoZSByZXF1ZXN0IGhhcyBiZWVuIGNvbXBsZXRlZCwgemVybyBvdGhlcndpc2UuCiAqLwpzdGF0aWMgaW50IGNkcm9tX3JlYWRfZnJvbV9idWZmZXIgKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7Cgl1bnNpZ25lZCBzaG9ydCBzZWN0b3JzX3Blcl9mcmFtZTsKCglzZWN0b3JzX3Blcl9mcmFtZSA9IHF1ZXVlX2hhcmRzZWN0X3NpemUoZHJpdmUtPnF1ZXVlKSA+PiBTRUNUT1JfQklUUzsKCgkvKiBDYW4ndCBkbyBhbnl0aGluZyBpZiB0aGVyZSdzIG5vIGJ1ZmZlci4gKi8KCWlmIChpbmZvLT5idWZmZXIgPT0gTlVMTCkgcmV0dXJuIDA7CgoJLyogTG9vcCB3aGlsZSB0aGlzIHJlcXVlc3QgbmVlZHMgZGF0YSBhbmQgdGhlIG5leHQgYmxvY2sgaXMgcHJlc2VudAoJICAgaW4gb3VyIGNhY2hlLiAqLwoJd2hpbGUgKHJxLT5ucl9zZWN0b3JzID4gMCAmJgoJICAgICAgIHJxLT5zZWN0b3IgPj0gaW5mby0+c2VjdG9yX2J1ZmZlcmVkICYmCgkgICAgICAgcnEtPnNlY3RvciA8IGluZm8tPnNlY3Rvcl9idWZmZXJlZCArIGluZm8tPm5zZWN0b3JzX2J1ZmZlcmVkKSB7CgkJaWYgKHJxLT5jdXJyZW50X25yX3NlY3RvcnMgPT0gMCkKCQkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDEpOwoKCQltZW1jcHkgKHJxLT5idWZmZXIsCgkJCWluZm8tPmJ1ZmZlciArCgkJCShycS0+c2VjdG9yIC0gaW5mby0+c2VjdG9yX2J1ZmZlcmVkKSAqIFNFQ1RPUl9TSVpFLAoJCQlTRUNUT1JfU0laRSk7CgkJcnEtPmJ1ZmZlciArPSBTRUNUT1JfU0laRTsKCQktLXJxLT5jdXJyZW50X25yX3NlY3RvcnM7CgkJLS1ycS0+bnJfc2VjdG9yczsKCQkrK3JxLT5zZWN0b3I7Cgl9CgoJLyogSWYgd2UndmUgc2F0aXNmaWVkIHRoZSBjdXJyZW50IHJlcXVlc3QsCgkgICB0ZXJtaW5hdGUgaXQgc3VjY2Vzc2Z1bGx5LiAqLwoJaWYgKHJxLT5ucl9zZWN0b3JzID09IDApIHsKCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMSk7CgkJcmV0dXJuIC0xOwoJfQoKCS8qIE1vdmUgb24gdG8gdGhlIG5leHQgYnVmZmVyIGlmIG5lZWRlZC4gKi8KCWlmIChycS0+Y3VycmVudF9ucl9zZWN0b3JzID09IDApCgkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDEpOwoKCS8qIElmIHRoaXMgY29uZGl0aW9uIGRvZXMgbm90IGhvbGQsIHRoZW4gdGhlIGtsdWdlIGkgdXNlIHRvCgkgICByZXByZXNlbnQgdGhlIG51bWJlciBvZiBzZWN0b3JzIHRvIHNraXAgYXQgdGhlIHN0YXJ0IG9mIGEgdHJhbnNmZXIKCSAgIHdpbGwgZmFpbC4gIEkgdGhpbmsgdGhhdCB0aGlzIHdpbGwgbmV2ZXIgaGFwcGVuLCBidXQgbGV0J3MgYmUKCSAgIHBhcmFub2lkIGFuZCBjaGVjay4gKi8KCWlmIChycS0+Y3VycmVudF9ucl9zZWN0b3JzIDwgYmlvX2N1cl9zZWN0b3JzKHJxLT5iaW8pICYmCgkgICAgKHJxLT5zZWN0b3IgJiAoc2VjdG9yc19wZXJfZnJhbWUgLSAxKSkpIHsKCQlwcmludGsoS0VSTl9FUlIgIiVzOiBjZHJvbV9yZWFkX2Zyb21fYnVmZmVyOiBidWZmZXIgYm90Y2ggKCVsZClcbiIsCgkJCWRyaXZlLT5uYW1lLCAobG9uZylycS0+c2VjdG9yKTsKCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7CgkJcmV0dXJuIC0xOwoJfQoKCXJldHVybiAwOwp9CgovKgogKiBSb3V0aW5lIHRvIHNlbmQgYSByZWFkIHBhY2tldCBjb21tYW5kIHRvIHRoZSBkcml2ZS4KICogVGhpcyBpcyB1c3VhbGx5IGNhbGxlZCBkaXJlY3RseSBmcm9tIGNkcm9tX3N0YXJ0X3JlYWQuCiAqIEhvd2V2ZXIsIGZvciBkcnFfaW50ZXJydXB0IGRldmljZXMsIGl0IGlzIGNhbGxlZCBmcm9tIGFuIGludGVycnVwdAogKiB3aGVuIHRoZSBkcml2ZSBpcyByZWFkeSB0byBhY2NlcHQgdGhlIGNvbW1hbmQuCiAqLwpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX3N0YXJ0X3JlYWRfY29udGludWF0aW9uIChpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCXVuc2lnbmVkIHNob3J0IHNlY3RvcnNfcGVyX2ZyYW1lOwoJaW50IG5za2lwOwoKCXNlY3RvcnNfcGVyX2ZyYW1lID0gcXVldWVfaGFyZHNlY3Rfc2l6ZShkcml2ZS0+cXVldWUpID4+IFNFQ1RPUl9CSVRTOwoKCS8qIElmIHRoZSByZXF1ZXN0ZWQgc2VjdG9yIGRvZXNuJ3Qgc3RhcnQgb24gYSBjZHJvbSBibG9jayBib3VuZGFyeSwKCSAgIHdlIG11c3QgYWRqdXN0IHRoZSBzdGFydCBvZiB0aGUgdHJhbnNmZXIgc28gdGhhdCBpdCBkb2VzLAoJICAgYW5kIHJlbWVtYmVyIHRvIHNraXAgdGhlIGZpcnN0IGZldyBzZWN0b3JzLgoJICAgSWYgdGhlIENVUlJFTlRfTlJfU0VDVE9SUyBmaWVsZCBpcyBsYXJnZXIgdGhhbiB0aGUgc2l6ZQoJICAgb2YgdGhlIGJ1ZmZlciwgaXQgd2lsbCBtZWFuIHRoYXQgd2UncmUgdG8gc2tpcCBhIG51bWJlcgoJICAgb2Ygc2VjdG9ycyBlcXVhbCB0byB0aGUgYW1vdW50IGJ5IHdoaWNoIENVUlJFTlRfTlJfU0VDVE9SUwoJICAgaXMgbGFyZ2VyIHRoYW4gdGhlIGJ1ZmZlciBzaXplLiAqLwoJbnNraXAgPSBycS0+c2VjdG9yICYgKHNlY3RvcnNfcGVyX2ZyYW1lIC0gMSk7CglpZiAobnNraXAgPiAwKSB7CgkJLyogU2FuaXR5IGNoZWNrLi4uICovCgkJaWYgKHJxLT5jdXJyZW50X25yX3NlY3RvcnMgIT0gYmlvX2N1cl9zZWN0b3JzKHJxLT5iaW8pICYmCgkJCShycS0+c2VjdG9yICYgKHNlY3RvcnNfcGVyX2ZyYW1lIC0gMSkpKSB7CgkJCXByaW50ayhLRVJOX0VSUiAiJXM6IGNkcm9tX3N0YXJ0X3JlYWRfY29udGludWF0aW9uOiBidWZmZXIgYm90Y2ggKCV1KVxuIiwKCQkJCWRyaXZlLT5uYW1lLCBycS0+Y3VycmVudF9ucl9zZWN0b3JzKTsKCQkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDApOwoJCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgkJfQoJCXJxLT5jdXJyZW50X25yX3NlY3RvcnMgKz0gbnNraXA7Cgl9CgoJLyogU2V0IHVwIHRoZSBjb21tYW5kICovCglycS0+dGltZW91dCA9IEFUQVBJX1dBSVRfUEM7CgoJLyogU2VuZCB0aGUgY29tbWFuZCB0byB0aGUgZHJpdmUgYW5kIHJldHVybi4gKi8KCXJldHVybiBjZHJvbV90cmFuc2Zlcl9wYWNrZXRfY29tbWFuZChkcml2ZSwgcnEsICZjZHJvbV9yZWFkX2ludHIpOwp9CgoKI2RlZmluZSBJREVDRF9TRUVLX1RIUkVTSE9MRAkoMTAwMCkJCQkvKiAxMDAwIGJsb2NrcyAqLwojZGVmaW5lIElERUNEX1NFRUtfVElNRVIJKDUgKiBXQUlUX01JTl9TTEVFUCkJLyogMTAwIG1zICovCiNkZWZpbmUgSURFQ0RfU0VFS19USU1FT1VUCSgyICogV0FJVF9DTUQpCQkvKiAyMCBzZWMgKi8KCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fc2Vla19pbnRyIChpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJaW50IHN0YXQ7CglzdGF0aWMgaW50IHJldHJ5ID0gMTA7CgoJaWYgKGNkcm9tX2RlY29kZV9zdGF0dXMoZHJpdmUsIDAsICZzdGF0KSkKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5zZWVraW5nID0gMTsKCglpZiAocmV0cnkgJiYgdGltZV9hZnRlcihqaWZmaWVzLCBpbmZvLT5zdGFydF9zZWVrICsgSURFQ0RfU0VFS19USU1FUikpIHsKCQlpZiAoLS1yZXRyeSA9PSAwKSB7CgkJCS8qCgkJCSAqIHRoaXMgY29uZGl0aW9uIGlzIGZhciB0b28gY29tbW9uLCB0byBib3RoZXIKCQkJICogdXNlcnMgYWJvdXQgaXQKCQkJICovCgkJCS8qIHByaW50aygiJXM6IGRpc2FibGVkIERTQyBzZWVrIG92ZXJsYXBcbiIsIGRyaXZlLT5uYW1lKTsqLyAKCQkJZHJpdmUtPmRzY19vdmVybGFwID0gMDsKCQl9Cgl9CglyZXR1cm4gaWRlX3N0b3BwZWQ7Cn0KCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fc3RhcnRfc2Vla19jb250aW51YXRpb24gKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJc3RydWN0IHJlcXVlc3QgKnJxID0gSFdHUk9VUChkcml2ZSktPnJxOwoJc2VjdG9yX3QgZnJhbWUgPSBycS0+c2VjdG9yOwoKCXNlY3Rvcl9kaXYoZnJhbWUsIHF1ZXVlX2hhcmRzZWN0X3NpemUoZHJpdmUtPnF1ZXVlKSA+PiBTRUNUT1JfQklUUyk7CgoJbWVtc2V0KHJxLT5jbWQsIDAsIHNpemVvZihycS0+Y21kKSk7CglycS0+Y21kWzBdID0gR1BDTURfU0VFSzsKCXB1dF91bmFsaWduZWQoY3B1X3RvX2JlMzIoZnJhbWUpLCAodW5zaWduZWQgaW50ICopICZycS0+Y21kWzJdKTsKCglycS0+dGltZW91dCA9IEFUQVBJX1dBSVRfUEM7CglyZXR1cm4gY2Ryb21fdHJhbnNmZXJfcGFja2V0X2NvbW1hbmQoZHJpdmUsIHJxLCAmY2Ryb21fc2Vla19pbnRyKTsKfQoKc3RhdGljIGlkZV9zdGFydHN0b3BfdCBjZHJvbV9zdGFydF9zZWVrIChpZGVfZHJpdmVfdCAqZHJpdmUsIHVuc2lnbmVkIGludCBibG9jaykKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CgoJaW5mby0+ZG1hID0gMDsKCWluZm8tPmNtZCA9IDA7CglpbmZvLT5zdGFydF9zZWVrID0gamlmZmllczsKCXJldHVybiBjZHJvbV9zdGFydF9wYWNrZXRfY29tbWFuZChkcml2ZSwgMCwgY2Ryb21fc3RhcnRfc2Vla19jb250aW51YXRpb24pOwp9CgovKiBGaXggdXAgYSBwb3NzaWJseSBwYXJ0aWFsbHktcHJvY2Vzc2VkIHJlcXVlc3Qgc28gdGhhdCB3ZSBjYW4KICAgc3RhcnQgaXQgb3ZlciBlbnRpcmVseSwgb3IgZXZlbiBwdXQgaXQgYmFjayBvbiB0aGUgcmVxdWVzdCBxdWV1ZS4gKi8Kc3RhdGljIHZvaWQgcmVzdG9yZV9yZXF1ZXN0IChzdHJ1Y3QgcmVxdWVzdCAqcnEpCnsKCWlmIChycS0+YnVmZmVyICE9IGJpb19kYXRhKHJxLT5iaW8pKSB7CgkJc2VjdG9yX3QgbiA9IChycS0+YnVmZmVyIC0gKGNoYXIgKikgYmlvX2RhdGEocnEtPmJpbykpIC8gU0VDVE9SX1NJWkU7CgoJCXJxLT5idWZmZXIgPSBiaW9fZGF0YShycS0+YmlvKTsKCQlycS0+bnJfc2VjdG9ycyArPSBuOwoJCXJxLT5zZWN0b3IgLT0gbjsKCX0KCXJxLT5oYXJkX2N1cl9zZWN0b3JzID0gcnEtPmN1cnJlbnRfbnJfc2VjdG9ycyA9IGJpb19jdXJfc2VjdG9ycyhycS0+YmlvKTsKCXJxLT5oYXJkX25yX3NlY3RvcnMgPSBycS0+bnJfc2VjdG9yczsKCXJxLT5oYXJkX3NlY3RvciA9IHJxLT5zZWN0b3I7CglycS0+cS0+cHJlcF9ycV9mbihycS0+cSwgcnEpOwp9CgovKgogKiBTdGFydCBhIHJlYWQgcmVxdWVzdCBmcm9tIHRoZSBDRC1ST00uCiAqLwpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX3N0YXJ0X3JlYWQgKGlkZV9kcml2ZV90ICpkcml2ZSwgdW5zaWduZWQgaW50IGJsb2NrKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCXVuc2lnbmVkIHNob3J0IHNlY3RvcnNfcGVyX2ZyYW1lOwoKCXNlY3RvcnNfcGVyX2ZyYW1lID0gcXVldWVfaGFyZHNlY3Rfc2l6ZShkcml2ZS0+cXVldWUpID4+IFNFQ1RPUl9CSVRTOwoKCS8qIFdlIG1heSBiZSByZXRyeWluZyB0aGlzIHJlcXVlc3QgYWZ0ZXIgYW4gZXJyb3IuICBGaXggdXAKCSAgIGFueSB3ZWlyZG5lc3Mgd2hpY2ggbWlnaHQgYmUgcHJlc2VudCBpbiB0aGUgcmVxdWVzdCBwYWNrZXQuICovCglyZXN0b3JlX3JlcXVlc3QocnEpOwoKCS8qIFNhdGlzZnkgd2hhdGV2ZXIgd2UgY2FuIG9mIHRoaXMgcmVxdWVzdCBmcm9tIG91ciBjYWNoZWQgc2VjdG9yLiAqLwoJaWYgKGNkcm9tX3JlYWRfZnJvbV9idWZmZXIoZHJpdmUpKQoJCXJldHVybiBpZGVfc3RvcHBlZDsKCglibGtfYXR0ZW1wdF9yZW1lcmdlKGRyaXZlLT5xdWV1ZSwgcnEpOwoKCS8qIENsZWFyIHRoZSBsb2NhbCBzZWN0b3IgYnVmZmVyLiAqLwoJaW5mby0+bnNlY3RvcnNfYnVmZmVyZWQgPSAwOwoKCS8qIHVzZSBkbWEsIGlmIHBvc3NpYmxlLiAqLwoJaW5mby0+ZG1hID0gZHJpdmUtPnVzaW5nX2RtYTsKCWlmICgocnEtPnNlY3RvciAmIChzZWN0b3JzX3Blcl9mcmFtZSAtIDEpKSB8fAoJICAgIChycS0+bnJfc2VjdG9ycyAmIChzZWN0b3JzX3Blcl9mcmFtZSAtIDEpKSkKCQlpbmZvLT5kbWEgPSAwOwoKCWluZm8tPmNtZCA9IFJFQUQ7CgoJLyogU3RhcnQgc2VuZGluZyB0aGUgcmVhZCByZXF1ZXN0IHRvIHRoZSBkcml2ZS4gKi8KCXJldHVybiBjZHJvbV9zdGFydF9wYWNrZXRfY29tbWFuZChkcml2ZSwgMzI3NjgsIGNkcm9tX3N0YXJ0X3JlYWRfY29udGludWF0aW9uKTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogRXhlY3V0ZSBhbGwgb3RoZXIgcGFja2V0IGNvbW1hbmRzLgogKi8KCi8qIEludGVycnVwdCByb3V0aW5lIGZvciBwYWNrZXQgY29tbWFuZCBjb21wbGV0aW9uLiAqLwpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX3BjX2ludHIgKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJaW50IGlyZWFzb24sIGxlbiwgdGhpc2xlbjsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCXU4IGxvd2N5bCA9IDAsIGhpZ2hjeWwgPSAwOwoJaW50IHN0YXQ7CgoJLyogQ2hlY2sgZm9yIGVycm9ycy4gKi8KCWlmIChjZHJvbV9kZWNvZGVfc3RhdHVzKGRyaXZlLCAwLCAmc3RhdCkpCgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoKCS8qIFJlYWQgdGhlIGludGVycnVwdCByZWFzb24gYW5kIHRoZSB0cmFuc2ZlciBsZW5ndGguICovCglpcmVhc29uID0gSFdJRihkcml2ZSktPklOQihJREVfSVJFQVNPTl9SRUcpOwoJbG93Y3lsICA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX0JDT1VOVExfUkVHKTsKCWhpZ2hjeWwgPSBIV0lGKGRyaXZlKS0+SU5CKElERV9CQ09VTlRIX1JFRyk7CgoJbGVuID0gbG93Y3lsICsgKDI1NiAqIGhpZ2hjeWwpOwoKCS8qIElmIERSUSBpcyBjbGVhciwgdGhlIGNvbW1hbmQgaGFzIGNvbXBsZXRlZC4KCSAgIENvbXBsYWluIGlmIHdlIHN0aWxsIGhhdmUgZGF0YSBsZWZ0IHRvIHRyYW5zZmVyLiAqLwoJaWYgKChzdGF0ICYgRFJRX1NUQVQpID09IDApIHsKCQkvKiBTb21lIG9mIHRoZSB0cmFpbGluZyByZXF1ZXN0IHNlbnNlIGZpZWxkcyBhcmUgb3B0aW9uYWwsIGFuZAoJCSAgIHNvbWUgZHJpdmVzIGRvbid0IHNlbmQgdGhlbS4gIFNpZ2guICovCgkJaWYgKHJxLT5jbWRbMF0gPT0gR1BDTURfUkVRVUVTVF9TRU5TRSAmJgoJCSAgICBycS0+ZGF0YV9sZW4gPiAwICYmCgkJICAgIHJxLT5kYXRhX2xlbiA8PSA1KSB7CgkJCXdoaWxlIChycS0+ZGF0YV9sZW4gPiAwKSB7CgkJCQkqKHVuc2lnbmVkIGNoYXIgKilycS0+ZGF0YSsrID0gMDsKCQkJCS0tcnEtPmRhdGFfbGVuOwoJCQl9CgkJfQoKCQlpZiAocnEtPmRhdGFfbGVuID09IDApCgkJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAxKTsKCQllbHNlIHsKCQkJLyogQ29tbWVudCB0aGlzIG91dCwgYmVjYXVzZSB0aGlzIGFsd2F5cyBoYXBwZW5zIAoJCQkgICByaWdodCBhZnRlciBhIHJlc2V0IG9jY3VycywgYW5kIGl0IGlzIGFubm95aW5nIHRvIAoJCQkgICBhbHdheXMgcHJpbnQgZXhwZWN0ZWQgc3R1ZmYuICAqLwoJCQkvKgoJCQlwcmludGsgKCIlczogY2Ryb21fcGNfaW50cjogZGF0YSB1bmRlcnJ1biAlZFxuIiwKCQkJCWRyaXZlLT5uYW1lLCBwYy0+YnVmbGVuKTsKCQkJKi8KCQkJcnEtPmZsYWdzIHw9IFJFUV9GQUlMRUQ7CgkJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAwKTsKCQl9CgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoJfQoKCS8qIEZpZ3VyZSBvdXQgaG93IG11Y2ggZGF0YSB0byB0cmFuc2Zlci4gKi8KCXRoaXNsZW4gPSBycS0+ZGF0YV9sZW47CglpZiAodGhpc2xlbiA+IGxlbikgdGhpc2xlbiA9IGxlbjsKCgkvKiBUaGUgZHJpdmUgd2FudHMgdG8gYmUgd3JpdHRlbiB0by4gKi8KCWlmICgoaXJlYXNvbiAmIDMpID09IDApIHsKCQlpZiAoIXJxLT5kYXRhKSB7CgkJCWJsa19kdW1wX3JxX2ZsYWdzKHJxLCAiY2Ryb21fcGNfaW50ciwgd3JpdGUiKTsKCQkJZ290byBjb25mdXNlZDsKCQl9CgkJLyogVHJhbnNmZXIgdGhlIGRhdGEuICovCgkJSFdJRihkcml2ZSktPmF0YXBpX291dHB1dF9ieXRlcyhkcml2ZSwgcnEtPmRhdGEsIHRoaXNsZW4pOwoKCQkvKiBJZiB3ZSBoYXZlbid0IG1vdmVkIGVub3VnaCBkYXRhIHRvIHNhdGlzZnkgdGhlIGRyaXZlLAoJCSAgIGFkZCBzb21lIHBhZGRpbmcuICovCgkJd2hpbGUgKGxlbiA+IHRoaXNsZW4pIHsKCQkJaW50IGR1bSA9IDA7CgkJCUhXSUYoZHJpdmUpLT5hdGFwaV9vdXRwdXRfYnl0ZXMoZHJpdmUsICZkdW0sIHNpemVvZihkdW0pKTsKCQkJbGVuIC09IHNpemVvZihkdW0pOwoJCX0KCgkJLyogS2VlcCBjb3VudCBvZiBob3cgbXVjaCBkYXRhIHdlJ3ZlIG1vdmVkLiAqLwoJCXJxLT5kYXRhICs9IHRoaXNsZW47CgkJcnEtPmRhdGFfbGVuIC09IHRoaXNsZW47Cgl9CgoJLyogU2FtZSBkcmlsbCBmb3IgcmVhZGluZy4gKi8KCWVsc2UgaWYgKChpcmVhc29uICYgMykgPT0gMikgewoJCWlmICghcnEtPmRhdGEpIHsKCQkJYmxrX2R1bXBfcnFfZmxhZ3MocnEsICJjZHJvbV9wY19pbnRyLCB3cml0ZSIpOwoJCQlnb3RvIGNvbmZ1c2VkOwoJCX0KCQkvKiBUcmFuc2ZlciB0aGUgZGF0YS4gKi8KCQlIV0lGKGRyaXZlKS0+YXRhcGlfaW5wdXRfYnl0ZXMoZHJpdmUsIHJxLT5kYXRhLCB0aGlzbGVuKTsKCgkJLyogSWYgd2UgaGF2ZW4ndCBtb3ZlZCBlbm91Z2ggZGF0YSB0byBzYXRpc2Z5IHRoZSBkcml2ZSwKCQkgICBhZGQgc29tZSBwYWRkaW5nLiAqLwoJCXdoaWxlIChsZW4gPiB0aGlzbGVuKSB7CgkJCWludCBkdW0gPSAwOwoJCQlIV0lGKGRyaXZlKS0+YXRhcGlfaW5wdXRfYnl0ZXMoZHJpdmUsICZkdW0sIHNpemVvZihkdW0pKTsKCQkJbGVuIC09IHNpemVvZihkdW0pOwoJCX0KCgkJLyogS2VlcCBjb3VudCBvZiBob3cgbXVjaCBkYXRhIHdlJ3ZlIG1vdmVkLiAqLwoJCXJxLT5kYXRhICs9IHRoaXNsZW47CgkJcnEtPmRhdGFfbGVuIC09IHRoaXNsZW47CgoJCWlmIChycS0+ZmxhZ3MgJiBSRVFfU0VOU0UpCgkJCXJxLT5zZW5zZV9sZW4gKz0gdGhpc2xlbjsKCX0gZWxzZSB7CmNvbmZ1c2VkOgoJCXByaW50ayAoS0VSTl9FUlIgIiVzOiBjZHJvbV9wY19pbnRyOiBUaGUgZHJpdmUgIgoJCQkiYXBwZWFycyBjb25mdXNlZCAoaXJlYXNvbiA9IDB4JTAyeClcbiIsCgkJCWRyaXZlLT5uYW1lLCBpcmVhc29uKTsKCQlycS0+ZmxhZ3MgfD0gUkVRX0ZBSUxFRDsKCX0KCgkvKiBOb3cgd2Ugd2FpdCBmb3IgYW5vdGhlciBpbnRlcnJ1cHQuICovCglpZGVfc2V0X2hhbmRsZXIoZHJpdmUsICZjZHJvbV9wY19pbnRyLCBBVEFQSV9XQUlUX1BDLCBjZHJvbV90aW1lcl9leHBpcnkpOwoJcmV0dXJuIGlkZV9zdGFydGVkOwp9CgpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX2RvX3BjX2NvbnRpbnVhdGlvbiAoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7CgoJaWYgKCFycS0+dGltZW91dCkKCQlycS0+dGltZW91dCA9IEFUQVBJX1dBSVRfUEM7CgoJLyogU2VuZCB0aGUgY29tbWFuZCB0byB0aGUgZHJpdmUgYW5kIHJldHVybi4gKi8KCXJldHVybiBjZHJvbV90cmFuc2Zlcl9wYWNrZXRfY29tbWFuZChkcml2ZSwgcnEsICZjZHJvbV9wY19pbnRyKTsKfQoKCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fZG9fcGFja2V0X2NvbW1hbmQgKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJaW50IGxlbjsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoKCWluZm8tPmRtYSA9IDA7CglpbmZvLT5jbWQgPSAwOwoJcnEtPmZsYWdzICY9IH5SRVFfRkFJTEVEOwoJbGVuID0gcnEtPmRhdGFfbGVuOwoKCS8qIFN0YXJ0IHNlbmRpbmcgdGhlIGNvbW1hbmQgdG8gdGhlIGRyaXZlLiAqLwoJcmV0dXJuIGNkcm9tX3N0YXJ0X3BhY2tldF9jb21tYW5kKGRyaXZlLCBsZW4sIGNkcm9tX2RvX3BjX2NvbnRpbnVhdGlvbik7Cn0KCgpzdGF0aWMKaW50IGNkcm9tX3F1ZXVlX3BhY2tldF9jb21tYW5kKGlkZV9kcml2ZV90ICpkcml2ZSwgc3RydWN0IHJlcXVlc3QgKnJxKQp7CglzdHJ1Y3QgcmVxdWVzdF9zZW5zZSBzZW5zZTsKCWludCByZXRyaWVzID0gMTA7Cgl1bnNpZ25lZCBpbnQgZmxhZ3MgPSBycS0+ZmxhZ3M7CgoJaWYgKHJxLT5zZW5zZSA9PSBOVUxMKQoJCXJxLT5zZW5zZSA9ICZzZW5zZTsKCgkvKiBTdGFydCBvZiByZXRyeSBsb29wLiAqLwoJZG8gewoJCWludCBlcnJvcjsKCQl1bnNpZ25lZCBsb25nIHRpbWUgPSBqaWZmaWVzOwoJCXJxLT5mbGFncyA9IGZsYWdzOwoKCQllcnJvciA9IGlkZV9kb19kcml2ZV9jbWQoZHJpdmUsIHJxLCBpZGVfd2FpdCk7CgkJdGltZSA9IGppZmZpZXMgLSB0aW1lOwoKCQkvKiBGSVhNRTogd2Ugc2hvdWxkIHByb2JhYmx5IGFib3J0L3JldHJ5IG9yIHNvbWV0aGluZyAKCQkgKiBpbiBjYXNlIG9mIGZhaWx1cmUgKi8KCQlpZiAocnEtPmZsYWdzICYgUkVRX0ZBSUxFRCkgewoJCQkvKiBUaGUgcmVxdWVzdCBmYWlsZWQuICBSZXRyeSBpZiBpdCB3YXMgZHVlIHRvIGEgdW5pdAoJCQkgICBhdHRlbnRpb24gc3RhdHVzCgkJCSAgICh1c3VhbGx5IG1lYW5zIG1lZGlhIHdhcyBjaGFuZ2VkKS4gKi8KCQkJc3RydWN0IHJlcXVlc3Rfc2Vuc2UgKnJlcWJ1ZiA9IHJxLT5zZW5zZTsKCgkJCWlmIChyZXFidWYtPnNlbnNlX2tleSA9PSBVTklUX0FUVEVOVElPTikKCQkJCWNkcm9tX3Nhd19tZWRpYV9jaGFuZ2UoZHJpdmUpOwoJCQllbHNlIGlmIChyZXFidWYtPnNlbnNlX2tleSA9PSBOT1RfUkVBRFkgJiYKCQkJCSByZXFidWYtPmFzYyA9PSA0ICYmIHJlcWJ1Zi0+YXNjcSAhPSA0KSB7CgkJCQkvKiBUaGUgZHJpdmUgaXMgaW4gdGhlIHByb2Nlc3Mgb2YgbG9hZGluZwoJCQkJICAgYSBkaXNrLiAgUmV0cnksIGJ1dCB3YWl0IGEgbGl0dGxlIHRvIGdpdmUKCQkJCSAgIHRoZSBkcml2ZSB0aW1lIHRvIGNvbXBsZXRlIHRoZSBsb2FkLiAqLwoJCQkJc3NsZWVwKDIpOwoJCQl9IGVsc2UgewoJCQkJLyogT3RoZXJ3aXNlLCBkb24ndCByZXRyeS4gKi8KCQkJCXJldHJpZXMgPSAwOwoJCQl9CgkJCS0tcmV0cmllczsKCQl9CgoJCS8qIEVuZCBvZiByZXRyeSBsb29wLiAqLwoJfSB3aGlsZSAoKHJxLT5mbGFncyAmIFJFUV9GQUlMRUQpICYmIHJldHJpZXMgPj0gMCk7CgoJLyogUmV0dXJuIGFuIGVycm9yIGlmIHRoZSBjb21tYW5kIGZhaWxlZC4gKi8KCXJldHVybiAocnEtPmZsYWdzICYgUkVRX0ZBSUxFRCkgPyAtRUlPIDogMDsKfQoKLyoKICogV3JpdGUgaGFuZGxpbmcKICovCnN0YXRpYyBpbmxpbmUgaW50IGNkcm9tX3dyaXRlX2NoZWNrX2lyZWFzb24oaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgbGVuLCBpbnQgaXJlYXNvbikKewoJLyogVHdvIG5vdGVzIGFib3V0IElERSBpbnRlcnJ1cHQgcmVhc29uIGhlcmUgLSAwIG1lYW5zIHRoYXQKCSAqIHRoZSBkcml2ZSB3YW50cyB0byByZWNlaXZlIGRhdGEgZnJvbSB1cywgMiBtZWFucyB0aGF0CgkgKiB0aGUgZHJpdmUgaXMgZXhwZWN0aW5nIHRvIHRyYW5zZmVyIGRhdGEgdG8gdXMuCgkgKi8KCWlmIChpcmVhc29uID09IDApCgkJcmV0dXJuIDA7CgllbHNlIGlmIChpcmVhc29uID09IDIpIHsKCQkvKiBXaG9vcHMuLi4gVGhlIGRyaXZlIHdhbnRzIHRvIHNlbmQgZGF0YS4gKi8KCQlwcmludGsoS0VSTl9FUlIgIiVzOiB3cml0ZV9pbnRyOiB3cm9uZyB0cmFuc2ZlciBkaXJlY3Rpb24hXG4iLAoJCQkJCQkJZHJpdmUtPm5hbWUpOwoKCQl3aGlsZSAobGVuID4gMCkgewoJCQlpbnQgZHVtID0gMDsKCQkJSFdJRihkcml2ZSktPmF0YXBpX2lucHV0X2J5dGVzKGRyaXZlLCAmZHVtLCBzaXplb2YoZHVtKSk7CgkJCWxlbiAtPSBzaXplb2YoZHVtKTsKCQl9Cgl9IGVsc2UgewoJCS8qIERyaXZlIHdhbnRzIGEgY29tbWFuZCBwYWNrZXQsIG9yIGludmFsaWQgaXJlYXNvbi4uLiAqLwoJCXByaW50ayhLRVJOX0VSUiAiJXM6IHdyaXRlX2ludHI6IGJhZCBpbnRlcnJ1cHQgcmVhc29uICV4XG4iLAoJCQkJCQkJZHJpdmUtPm5hbWUsIGlyZWFzb24pOwoJfQoKCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAwKTsKCXJldHVybiAxOwp9CgpzdGF0aWMgdm9pZCBwb3N0X3RyYW5zZm9ybV9jb21tYW5kKHN0cnVjdCByZXF1ZXN0ICpyZXEpCnsKCXU4ICpjID0gcmVxLT5jbWQ7CgljaGFyICppYnVmOwoKCWlmICghYmxrX3BjX3JlcXVlc3QocmVxKSkKCQlyZXR1cm47CgoJaWYgKHJlcS0+YmlvKQoJCWlidWYgPSBiaW9fZGF0YShyZXEtPmJpbyk7CgllbHNlCgkJaWJ1ZiA9IHJlcS0+ZGF0YTsKCglpZiAoIWlidWYpCgkJcmV0dXJuOwoKCS8qCgkgKiBzZXQgYW5zaS1yZXZpc2lvbiBhbmQgcmVzcG9uc2UgZGF0YSBhcyBhdGFwaQoJICovCglpZiAoY1swXSA9PSBHUENNRF9JTlFVSVJZKSB7CgkJaWJ1ZlsyXSB8PSAyOwoJCWlidWZbM10gPSAoaWJ1ZlszXSAmIDB4ZjApIHwgMjsKCX0KfQoKdHlwZWRlZiB2b2lkICh4ZmVyX2Z1bmNfdCkoaWRlX2RyaXZlX3QgKiwgdm9pZCAqLCB1MzIpOwoKLyoKICogYmVzdCB3YXkgdG8gZGVhbCB3aXRoIGRtYSB0aGF0IGlzIG5vdCBzZWN0b3IgYWxpZ25lZCByaWdodCBub3cuLi4gbm90ZQogKiB0aGF0IGluIHRoaXMgcGF0aCB3ZSBhcmUgbm90IHVzaW5nIC0+ZGF0YSBvciAtPmJ1ZmZlciBhdCBhbGwuIHRoaXMgaXJzCiAqIGNhbiByZXBsYWNlIGNkcm9tX3BjX2ludHIsIGNkcm9tX3JlYWRfaW50ciwgYW5kIGNkcm9tX3dyaXRlX2ludHIgaW4gdGhlCiAqIGZ1dHVyZS4KICovCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fbmV3cGNfaW50cihpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJc3RydWN0IHJlcXVlc3QgKnJxID0gSFdHUk9VUChkcml2ZSktPnJxOwoJaW50IGRtYV9lcnJvciwgZG1hLCBzdGF0LCBpcmVhc29uLCBsZW4sIHRoaXNsZW47Cgl1OCBsb3djeWwsIGhpZ2hjeWw7Cgl4ZmVyX2Z1bmNfdCAqeGZlcmZ1bmM7Cgl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCS8qIENoZWNrIGZvciBlcnJvcnMuICovCglkbWFfZXJyb3IgPSAwOwoJZG1hID0gaW5mby0+ZG1hOwoJaWYgKGRtYSkgewoJCWluZm8tPmRtYSA9IDA7CgkJZG1hX2Vycm9yID0gSFdJRihkcml2ZSktPmlkZV9kbWFfZW5kKGRyaXZlKTsKCX0KCglpZiAoY2Ryb21fZGVjb2RlX3N0YXR1cyhkcml2ZSwgMCwgJnN0YXQpKQoJCXJldHVybiBpZGVfc3RvcHBlZDsKCgkvKgoJICogdXNpbmcgZG1hLCB0cmFuc2ZlciBpcyBjb21wbGV0ZSBub3cKCSAqLwoJaWYgKGRtYSkgewoJCWlmIChkbWFfZXJyb3IpIHsKCQkJcHJpbnRrKEtFUk5fRVJSICJpZGUtY2Q6IGRtYSBlcnJvclxuIik7CgkJCV9faWRlX2RtYV9vZmYoZHJpdmUpOwoJCQlyZXR1cm4gaWRlX2Vycm9yKGRyaXZlLCAiZG1hIGVycm9yIiwgc3RhdCk7CgkJfQoKCQllbmRfdGhhdF9yZXF1ZXN0X2NodW5rKHJxLCAxLCBycS0+ZGF0YV9sZW4pOwoJCXJxLT5kYXRhX2xlbiA9IDA7CgkJZ290byBlbmRfcmVxdWVzdDsKCX0KCgkvKgoJICogb2sgd2UgZmFsbCB0byBwaW8gOi8KCSAqLwoJaXJlYXNvbiA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX0lSRUFTT05fUkVHKSAmIDB4MzsKCWxvd2N5bCAgPSBIV0lGKGRyaXZlKS0+SU5CKElERV9CQ09VTlRMX1JFRyk7CgloaWdoY3lsID0gSFdJRihkcml2ZSktPklOQihJREVfQkNPVU5USF9SRUcpOwoKCWxlbiA9IGxvd2N5bCArICgyNTYgKiBoaWdoY3lsKTsKCXRoaXNsZW4gPSBycS0+ZGF0YV9sZW47CglpZiAodGhpc2xlbiA+IGxlbikKCQl0aGlzbGVuID0gbGVuOwoKCS8qCgkgKiBJZiBEUlEgaXMgY2xlYXIsIHRoZSBjb21tYW5kIGhhcyBjb21wbGV0ZWQuCgkgKi8KCWlmICgoc3RhdCAmIERSUV9TVEFUKSA9PSAwKQoJCWdvdG8gZW5kX3JlcXVlc3Q7CgoJLyoKCSAqIGNoZWNrIHdoaWNoIHdheSB0byB0cmFuc2ZlciBkYXRhCgkgKi8KCWlmIChycV9kYXRhX2RpcihycSkgPT0gV1JJVEUpIHsKCQkvKgoJCSAqIHdyaXRlIHRvIGRyaXZlCgkJICovCgkJaWYgKGNkcm9tX3dyaXRlX2NoZWNrX2lyZWFzb24oZHJpdmUsIGxlbiwgaXJlYXNvbikpCgkJCXJldHVybiBpZGVfc3RvcHBlZDsKCgkJeGZlcmZ1bmMgPSBIV0lGKGRyaXZlKS0+YXRhcGlfb3V0cHV0X2J5dGVzOwoJfSBlbHNlICB7CgkJLyoKCQkgKiByZWFkIGZyb20gZHJpdmUKCQkgKi8KCQlpZiAoY2Ryb21fcmVhZF9jaGVja19pcmVhc29uKGRyaXZlLCBsZW4sIGlyZWFzb24pKQoJCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgoJCXhmZXJmdW5jID0gSFdJRihkcml2ZSktPmF0YXBpX2lucHV0X2J5dGVzOwoJfQoKCS8qCgkgKiB0cmFuc2ZlciBkYXRhCgkgKi8KCXdoaWxlICh0aGlzbGVuID4gMCkgewoJCWludCBibGVuID0gYmxlbiA9IHJxLT5kYXRhX2xlbjsKCQljaGFyICpwdHIgPSBycS0+ZGF0YTsKCgkJLyoKCQkgKiBiaW8gYmFja2VkPwoJCSAqLwoJCWlmIChycS0+YmlvKSB7CgkJCXB0ciA9IGJpb19kYXRhKHJxLT5iaW8pOwoJCQlibGVuID0gYmlvX2lvdmVjKHJxLT5iaW8pLT5idl9sZW47CgkJfQoKCQlpZiAoIXB0cikgewoJCQlwcmludGsoS0VSTl9FUlIgIiVzOiBjb25mdXNlZCwgbWlzc2luZyBkYXRhXG4iLCBkcml2ZS0+bmFtZSk7CgkJCWJyZWFrOwoJCX0KCgkJaWYgKGJsZW4gPiB0aGlzbGVuKQoJCQlibGVuID0gdGhpc2xlbjsKCgkJeGZlcmZ1bmMoZHJpdmUsIHB0ciwgYmxlbik7CgoJCXRoaXNsZW4gLT0gYmxlbjsKCQlsZW4gLT0gYmxlbjsKCQlycS0+ZGF0YV9sZW4gLT0gYmxlbjsKCgkJaWYgKHJxLT5iaW8pCgkJCWVuZF90aGF0X3JlcXVlc3RfY2h1bmsocnEsIDEsIGJsZW4pOwoJCWVsc2UKCQkJcnEtPmRhdGEgKz0gYmxlbjsKCX0KCgkvKgoJICogcGFkLCBpZiBuZWNlc3NhcnkKCSAqLwoJaWYgKGxlbiA+IDApIHsKCQl3aGlsZSAobGVuID4gMCkgewoJCQlpbnQgcGFkID0gMDsKCgkJCXhmZXJmdW5jKGRyaXZlLCAmcGFkLCBzaXplb2YocGFkKSk7CgkJCWxlbiAtPSBzaXplb2YocGFkKTsKCQl9Cgl9CgoJaWYgKEhXR1JPVVAoZHJpdmUpLT5oYW5kbGVyICE9IE5VTEwpCgkJQlVHKCk7CgoJaWRlX3NldF9oYW5kbGVyKGRyaXZlLCBjZHJvbV9uZXdwY19pbnRyLCBycS0+dGltZW91dCwgTlVMTCk7CglyZXR1cm4gaWRlX3N0YXJ0ZWQ7CgplbmRfcmVxdWVzdDoKCWlmICghcnEtPmRhdGFfbGVuKQoJCXBvc3RfdHJhbnNmb3JtX2NvbW1hbmQocnEpOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZpZGVfbG9jaywgZmxhZ3MpOwoJYmxrZGV2X2RlcXVldWVfcmVxdWVzdChycSk7CgllbmRfdGhhdF9yZXF1ZXN0X2xhc3QocnEpOwoJSFdHUk9VUChkcml2ZSktPnJxID0gTlVMTDsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmlkZV9sb2NrLCBmbGFncyk7CglyZXR1cm4gaWRlX3N0b3BwZWQ7Cn0KCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fd3JpdGVfaW50cihpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCWludCBzdGF0LCBpcmVhc29uLCBsZW4sIHNlY3RvcnNfdG9fdHJhbnNmZXIsIHVwdG9kYXRlOwoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglpbnQgZG1hX2Vycm9yID0gMCwgZG1hID0gaW5mby0+ZG1hOwoJdTggbG93Y3lsID0gMCwgaGlnaGN5bCA9IDA7CgoJc3RydWN0IHJlcXVlc3QgKnJxID0gSFdHUk9VUChkcml2ZSktPnJxOwoKCS8qIENoZWNrIGZvciBlcnJvcnMuICovCglpZiAoZG1hKSB7CgkJaW5mby0+ZG1hID0gMDsKCQlpZiAoKGRtYV9lcnJvciA9IEhXSUYoZHJpdmUpLT5pZGVfZG1hX2VuZChkcml2ZSkpKSB7CgkJCXByaW50ayhLRVJOX0VSUiAiaWRlLWNkOiB3cml0ZSBkbWEgZXJyb3JcbiIpOwoJCQlfX2lkZV9kbWFfb2ZmKGRyaXZlKTsKCQl9Cgl9CgoJaWYgKGNkcm9tX2RlY29kZV9zdGF0dXMoZHJpdmUsIDAsICZzdGF0KSkKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgoJLyoKCSAqIHVzaW5nIGRtYSwgdHJhbnNmZXIgaXMgY29tcGxldGUgbm93CgkgKi8KCWlmIChkbWEpIHsKCQlpZiAoZG1hX2Vycm9yKQoJCQlyZXR1cm4gaWRlX2Vycm9yKGRyaXZlLCAiZG1hIGVycm9yIiwgc3RhdCk7CgoJCWlkZV9lbmRfcmVxdWVzdChkcml2ZSwgMSwgcnEtPm5yX3NlY3RvcnMpOwoJCXJldHVybiBpZGVfc3RvcHBlZDsKCX0KCgkvKiBSZWFkIHRoZSBpbnRlcnJ1cHQgcmVhc29uIGFuZCB0aGUgdHJhbnNmZXIgbGVuZ3RoLiAqLwoJaXJlYXNvbiA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX0lSRUFTT05fUkVHKTsKCWxvd2N5bCAgPSBIV0lGKGRyaXZlKS0+SU5CKElERV9CQ09VTlRMX1JFRyk7CgloaWdoY3lsID0gSFdJRihkcml2ZSktPklOQihJREVfQkNPVU5USF9SRUcpOwoKCWxlbiA9IGxvd2N5bCArICgyNTYgKiBoaWdoY3lsKTsKCgkvKiBJZiBEUlEgaXMgY2xlYXIsIHRoZSBjb21tYW5kIGhhcyBjb21wbGV0ZWQuICovCglpZiAoKHN0YXQgJiBEUlFfU1RBVCkgPT0gMCkgewoJCS8qIElmIHdlJ3JlIG5vdCBkb25lIHdyaXRpbmcsIGNvbXBsYWluLgoJCSAqIE90aGVyd2lzZSwgY29tcGxldGUgdGhlIGNvbW1hbmQgbm9ybWFsbHkuCgkJICovCgkJdXB0b2RhdGUgPSAxOwoJCWlmIChycS0+Y3VycmVudF9ucl9zZWN0b3JzID4gMCkgewoJCQlwcmludGsoS0VSTl9FUlIgIiVzOiB3cml0ZV9pbnRyOiBkYXRhIHVuZGVycnVuICglZCBibG9ja3MpXG4iLAoJCQlkcml2ZS0+bmFtZSwgcnEtPmN1cnJlbnRfbnJfc2VjdG9ycyk7CgkJCXVwdG9kYXRlID0gMDsKCQl9CgkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIHVwdG9kYXRlKTsKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7Cgl9CgoJLyogQ2hlY2sgdGhhdCB0aGUgZHJpdmUgaXMgZXhwZWN0aW5nIHRvIGRvIHRoZSBzYW1lIHRoaW5nIHdlIGFyZS4gKi8KCWlmIChjZHJvbV93cml0ZV9jaGVja19pcmVhc29uKGRyaXZlLCBsZW4sIGlyZWFzb24pKQoJCXJldHVybiBpZGVfc3RvcHBlZDsKCglzZWN0b3JzX3RvX3RyYW5zZmVyID0gbGVuIC8gU0VDVE9SX1NJWkU7CgoJLyoKCSAqIG5vdyBsb29wIGFuZCB3cml0ZSBvdXQgdGhlIGRhdGEKCSAqLwoJd2hpbGUgKHNlY3RvcnNfdG9fdHJhbnNmZXIgPiAwKSB7CgkJaW50IHRoaXNfdHJhbnNmZXI7CgoJCWlmICghcnEtPmN1cnJlbnRfbnJfc2VjdG9ycykgewoJCQlwcmludGsoS0VSTl9FUlIgImlkZS1jZDogd3JpdGVfaW50cjogb29wc1xuIik7CgkJCWJyZWFrOwoJCX0KCgkJLyoKCQkgKiBGaWd1cmUgb3V0IGhvdyBtYW55IHNlY3RvcnMgd2UgY2FuIHRyYW5zZmVyCgkJICovCgkJdGhpc190cmFuc2ZlciA9IG1pbl90KGludCwgc2VjdG9yc190b190cmFuc2ZlciwgcnEtPmN1cnJlbnRfbnJfc2VjdG9ycyk7CgoJCXdoaWxlICh0aGlzX3RyYW5zZmVyID4gMCkgewoJCQlIV0lGKGRyaXZlKS0+YXRhcGlfb3V0cHV0X2J5dGVzKGRyaXZlLCBycS0+YnVmZmVyLCBTRUNUT1JfU0laRSk7CgkJCXJxLT5idWZmZXIgKz0gU0VDVE9SX1NJWkU7CgkJCS0tcnEtPm5yX3NlY3RvcnM7CgkJCS0tcnEtPmN1cnJlbnRfbnJfc2VjdG9yczsKCQkJKytycS0+c2VjdG9yOwoJCQktLXRoaXNfdHJhbnNmZXI7CgkJCS0tc2VjdG9yc190b190cmFuc2ZlcjsKCQl9CgoJCS8qCgkJICogY3VycmVudCBidWZmZXIgY29tcGxldGUsIG1vdmUgb24KCQkgKi8KCQlpZiAocnEtPmN1cnJlbnRfbnJfc2VjdG9ycyA9PSAwICYmIHJxLT5ucl9zZWN0b3JzKQoJCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMSk7Cgl9CgoJLyogcmUtYXJtIGhhbmRsZXIgKi8KCWlkZV9zZXRfaGFuZGxlcihkcml2ZSwgJmNkcm9tX3dyaXRlX2ludHIsIEFUQVBJX1dBSVRfUEMsIE5VTEwpOwoJcmV0dXJuIGlkZV9zdGFydGVkOwp9CgpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX3N0YXJ0X3dyaXRlX2NvbnQoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7CgojaWYgMAkvKiB0aGUgaW1tZWRpYXRlIGJpdCAqLwoJcnEtPmNtZFsxXSA9IDEgPDwgMzsKI2VuZGlmCglycS0+dGltZW91dCA9IEFUQVBJX1dBSVRfUEM7CgoJcmV0dXJuIGNkcm9tX3RyYW5zZmVyX3BhY2tldF9jb21tYW5kKGRyaXZlLCBycSwgY2Ryb21fd3JpdGVfaW50cik7Cn0KCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fc3RhcnRfd3JpdGUoaWRlX2RyaXZlX3QgKmRyaXZlLCBzdHJ1Y3QgcmVxdWVzdCAqcnEpCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJc3RydWN0IGdlbmRpc2sgKmcgPSBpbmZvLT5kaXNrOwoJdW5zaWduZWQgc2hvcnQgc2VjdG9yc19wZXJfZnJhbWUgPSBxdWV1ZV9oYXJkc2VjdF9zaXplKGRyaXZlLT5xdWV1ZSkgPj4gU0VDVE9SX0JJVFM7CgoJLyoKCSAqIHdyaXRlcyAqbXVzdCogYmUgaGFyZHdhcmUgZnJhbWUgYWxpZ25lZAoJICovCglpZiAoKHJxLT5ucl9zZWN0b3JzICYgKHNlY3RvcnNfcGVyX2ZyYW1lIC0gMSkpIHx8CgkgICAgKHJxLT5zZWN0b3IgJiAoc2VjdG9yc19wZXJfZnJhbWUgLSAxKSkpIHsKCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7CgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoJfQoKCS8qCgkgKiBkaXNrIGhhcyBiZWNvbWUgd3JpdGUgcHJvdGVjdGVkCgkgKi8KCWlmIChnLT5wb2xpY3kpIHsKCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7CgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoJfQoKCS8qCgkgKiBmb3IgZHZkLXJhbSBhbmQgc3VjaCBtZWRpYSwgaXQncyBhIHJlYWxseSBiaWcgZGVhbCB0byBnZXQKCSAqIGJpZyB3cml0ZXMgYWxsIHRoZSB0aW1lLiBzbyBzY291ciB0aGUgcXVldWUgYW5kIGF0dGVtcHQgdG8KCSAqIHJlbWVyZ2UgcmVxdWVzdHMsIG9mdGVuIHRoZSBwbHVnZ2luZyB3aWxsIG5vdCBoYXZlIGhhZCB0aW1lCgkgKiB0byBkbyB0aGlzIHByb3Blcmx5CgkgKi8KCWJsa19hdHRlbXB0X3JlbWVyZ2UoZHJpdmUtPnF1ZXVlLCBycSk7CgoJaW5mby0+bnNlY3RvcnNfYnVmZmVyZWQgPSAwOwoKCS8qIHVzZSBkbWEsIGlmIHBvc3NpYmxlLiB3ZSBkb24ndCBuZWVkIHRvIGNoZWNrIG1vcmUsIHNpbmNlIHdlCgkgKiBrbm93IHRoYXQgdGhlIHRyYW5zZmVyIGlzIGFsd2F5cyAoYXQgbGVhc3QhKSBmcmFtZSBhbGlnbmVkICovCglpbmZvLT5kbWEgPSBkcml2ZS0+dXNpbmdfZG1hID8gMSA6IDA7CglpbmZvLT5jbWQgPSBXUklURTsKCglpbmZvLT5kZXZpbmZvLm1lZGlhX3dyaXR0ZW4gPSAxOwoKCS8qIFN0YXJ0IHNlbmRpbmcgdGhlIHdyaXRlIHJlcXVlc3QgdG8gdGhlIGRyaXZlLiAqLwoJcmV0dXJuIGNkcm9tX3N0YXJ0X3BhY2tldF9jb21tYW5kKGRyaXZlLCAzMjc2OCwgY2Ryb21fc3RhcnRfd3JpdGVfY29udCk7Cn0KCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fZG9fbmV3cGNfY29udChpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCglpZiAoIXJxLT50aW1lb3V0KQoJCXJxLT50aW1lb3V0ID0gQVRBUElfV0FJVF9QQzsKCglyZXR1cm4gY2Ryb21fdHJhbnNmZXJfcGFja2V0X2NvbW1hbmQoZHJpdmUsIHJxLCBjZHJvbV9uZXdwY19pbnRyKTsKfQoKc3RhdGljIGlkZV9zdGFydHN0b3BfdCBjZHJvbV9kb19ibG9ja19wYyhpZGVfZHJpdmVfdCAqZHJpdmUsIHN0cnVjdCByZXF1ZXN0ICpycSkKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CgoJcnEtPmZsYWdzIHw9IFJFUV9RVUlFVDsKCglpbmZvLT5kbWEgPSAwOwoJaW5mby0+Y21kID0gMDsKCgkvKgoJICogc2cgcmVxdWVzdAoJICovCglpZiAocnEtPmJpbykgewoJCWludCBtYXNrID0gZHJpdmUtPnF1ZXVlLT5kbWFfYWxpZ25tZW50OwoJCXVuc2lnbmVkIGxvbmcgYWRkciA9ICh1bnNpZ25lZCBsb25nKSBwYWdlX2FkZHJlc3MoYmlvX3BhZ2UocnEtPmJpbykpOwoKCQlpbmZvLT5jbWQgPSBycV9kYXRhX2RpcihycSk7CgkJaW5mby0+ZG1hID0gZHJpdmUtPnVzaW5nX2RtYTsKCgkJLyoKCQkgKiBjaGVjayBpZiBkbWEgaXMgc2FmZQoJCSAqCgkJICogTk9URSEgVGhlICJsZW4iIGFuZCAiYWRkciIgY2hlY2tzIHNob3VsZCBwb3NzaWJseSBoYXZlCgkJICogc2VwYXJhdGUgbWFza3MuCgkJICovCgkJaWYgKChycS0+ZGF0YV9sZW4gJiAxNSkgfHwgKGFkZHIgJiBtYXNrKSkKCQkJaW5mby0+ZG1hID0gMDsKCX0KCgkvKiBTdGFydCBzZW5kaW5nIHRoZSBjb21tYW5kIHRvIHRoZSBkcml2ZS4gKi8KCXJldHVybiBjZHJvbV9zdGFydF9wYWNrZXRfY29tbWFuZChkcml2ZSwgcnEtPmRhdGFfbGVuLCBjZHJvbV9kb19uZXdwY19jb250KTsKfQoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogY2Ryb20gZHJpdmVyIHJlcXVlc3Qgcm91dGluZS4KICovCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QKaWRlX2RvX3J3X2Nkcm9tIChpZGVfZHJpdmVfdCAqZHJpdmUsIHN0cnVjdCByZXF1ZXN0ICpycSwgc2VjdG9yX3QgYmxvY2spCnsKCWlkZV9zdGFydHN0b3BfdCBhY3Rpb247CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCglpZiAoYmxrX2ZzX3JlcXVlc3QocnEpKSB7CgkJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnNlZWtpbmcpIHsKCQkJdW5zaWduZWQgbG9uZyBlbGFwc2VkID0gamlmZmllcyAtIGluZm8tPnN0YXJ0X3NlZWs7CgkJCWludCBzdGF0ID0gSFdJRihkcml2ZSktPklOQihJREVfU1RBVFVTX1JFRyk7CgoJCQlpZiAoKHN0YXQgJiBTRUVLX1NUQVQpICE9IFNFRUtfU1RBVCkgewoJCQkJaWYgKGVsYXBzZWQgPCBJREVDRF9TRUVLX1RJTUVPVVQpIHsKCQkJCQlpZGVfc3RhbGxfcXVldWUoZHJpdmUsIElERUNEX1NFRUtfVElNRVIpOwoJCQkJCXJldHVybiBpZGVfc3RvcHBlZDsKCQkJCX0KCQkJCXByaW50ayAoS0VSTl9FUlIgIiVzOiBEU0MgdGltZW91dFxuIiwgZHJpdmUtPm5hbWUpOwoJCQl9CgkJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnNlZWtpbmcgPSAwOwoJCX0KCQlpZiAoKHJxX2RhdGFfZGlyKHJxKSA9PSBSRUFEKSAmJiBJREVfTEFSR0VfU0VFSyhpbmZvLT5sYXN0X2Jsb2NrLCBibG9jaywgSURFQ0RfU0VFS19USFJFU0hPTEQpICYmIGRyaXZlLT5kc2Nfb3ZlcmxhcCkgewoJCQlhY3Rpb24gPSBjZHJvbV9zdGFydF9zZWVrKGRyaXZlLCBibG9jayk7CgkJfSBlbHNlIHsKCQkJaWYgKHJxX2RhdGFfZGlyKHJxKSA9PSBSRUFEKQoJCQkJYWN0aW9uID0gY2Ryb21fc3RhcnRfcmVhZChkcml2ZSwgYmxvY2spOwoJCQllbHNlCgkJCQlhY3Rpb24gPSBjZHJvbV9zdGFydF93cml0ZShkcml2ZSwgcnEpOwoJCX0KCQlpbmZvLT5sYXN0X2Jsb2NrID0gYmxvY2s7CgkJcmV0dXJuIGFjdGlvbjsKCX0gZWxzZSBpZiAocnEtPmZsYWdzICYgKFJFUV9QQyB8IFJFUV9TRU5TRSkpIHsKCQlyZXR1cm4gY2Ryb21fZG9fcGFja2V0X2NvbW1hbmQoZHJpdmUpOwoJfSBlbHNlIGlmIChycS0+ZmxhZ3MgJiBSRVFfQkxPQ0tfUEMpIHsKCQlyZXR1cm4gY2Ryb21fZG9fYmxvY2tfcGMoZHJpdmUsIHJxKTsKCX0gZWxzZSBpZiAocnEtPmZsYWdzICYgUkVRX1NQRUNJQUwpIHsKCQkvKgoJCSAqIHJpZ2h0IG5vdyB0aGlzIGNhbiBvbmx5IGJlIGEgcmVzZXQuLi4KCQkgKi8KCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMSk7CgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoJfQoKCWJsa19kdW1wX3JxX2ZsYWdzKHJxLCAiaWRlLWNkIGJhZCBmbGFncyIpOwoJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDApOwoJcmV0dXJuIGlkZV9zdG9wcGVkOwp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIElvY3RsIGhhbmRsaW5nLgogKgogKiBSb3V0aW5lcyB3aGljaCBxdWV1ZSBwYWNrZXQgY29tbWFuZHMgdGFrZSBhcyBhIGZpbmFsIGFyZ3VtZW50IGEgcG9pbnRlcgogKiB0byBhIHJlcXVlc3Rfc2Vuc2Ugc3RydWN0LiAgSWYgZXhlY3V0aW9uIG9mIHRoZSBjb21tYW5kIHJlc3VsdHMKICogaW4gYW4gZXJyb3Igd2l0aCBhIENIRUNLIENPTkRJVElPTiBzdGF0dXMsIHRoaXMgc3RydWN0dXJlIHdpbGwgYmUgZmlsbGVkCiAqIHdpdGggdGhlIHJlc3VsdHMgb2YgdGhlIHN1YnNlcXVlbnQgcmVxdWVzdCBzZW5zZSBjb21tYW5kLiAgVGhlIHBvaW50ZXIKICogY2FuIGFsc28gYmUgTlVMTCwgaW4gd2hpY2ggY2FzZSBubyBzZW5zZSBpbmZvcm1hdGlvbiBpcyByZXR1cm5lZC4KICovCgojaWYgISBTVEFOREFSRF9BVEFQSQpzdGF0aWMgaW5saW5lCmludCBiaW4yYmNkIChpbnQgeCkKewoJcmV0dXJuICh4JTEwKSB8ICgoeC8xMCkgPDwgNCk7Cn0KCgpzdGF0aWMgaW5saW5lCmludCBiY2QyYmluIChpbnQgeCkKewoJcmV0dXJuICh4ID4+IDQpICogMTAgKyAoeCAmIDB4MGYpOwp9CgpzdGF0aWMKdm9pZCBtc2ZfZnJvbV9iY2QgKHN0cnVjdCBhdGFwaV9tc2YgKm1zZikKewoJbXNmLT5taW51dGUgPSBiY2QyYmluIChtc2YtPm1pbnV0ZSk7Cgltc2YtPnNlY29uZCA9IGJjZDJiaW4gKG1zZi0+c2Vjb25kKTsKCW1zZi0+ZnJhbWUgID0gYmNkMmJpbiAobXNmLT5mcmFtZSk7Cn0KCiNlbmRpZiAvKiBub3QgU1RBTkRBUkRfQVRBUEkgKi8KCgpzdGF0aWMgaW5saW5lCnZvaWQgbGJhX3RvX21zZiAoaW50IGxiYSwgYnl0ZSAqbSwgYnl0ZSAqcywgYnl0ZSAqZikKewoJbGJhICs9IENEX01TRl9PRkZTRVQ7CglsYmEgJj0gMHhmZmZmZmY7ICAvKiBuZWdhdGl2ZSBsYmFzIHVzZSBvbmx5IDI0IGJpdHMgKi8KCSptID0gbGJhIC8gKENEX1NFQ1MgKiBDRF9GUkFNRVMpOwoJbGJhICU9IChDRF9TRUNTICogQ0RfRlJBTUVTKTsKCSpzID0gbGJhIC8gQ0RfRlJBTUVTOwoJKmYgPSBsYmEgJSBDRF9GUkFNRVM7Cn0KCgpzdGF0aWMgaW5saW5lCmludCBtc2ZfdG9fbGJhIChieXRlIG0sIGJ5dGUgcywgYnl0ZSBmKQp7CglyZXR1cm4gKCgobSAqIENEX1NFQ1MpICsgcykgKiBDRF9GUkFNRVMgKyBmKSAtIENEX01TRl9PRkZTRVQ7Cn0KCnN0YXRpYyBpbnQgY2Ryb21fY2hlY2tfc3RhdHVzKGlkZV9kcml2ZV90ICpkcml2ZSwgc3RydWN0IHJlcXVlc3Rfc2Vuc2UgKnNlbnNlKQp7CglzdHJ1Y3QgcmVxdWVzdCByZXE7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpID0gJmluZm8tPmRldmluZm87CgoJY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGRyaXZlLCAmcmVxKTsKCglyZXEuc2Vuc2UgPSBzZW5zZTsKCXJlcS5jbWRbMF0gPSBHUENNRF9URVNUX1VOSVRfUkVBRFk7CglyZXEuZmxhZ3MgfD0gUkVRX1FVSUVUOwoKI2lmICEgU1RBTkRBUkRfQVRBUEkKICAgICAgICAvKiB0aGUgU2FueW8gMyBDRCBjaGFuZ2VyIHVzZXMgYnl0ZSA3IG9mIFRFU1RfVU5JVF9SRUFEWSB0byAKICAgICAgICAgICBzd2l0Y2ggQ0RzIGluc3RlYWQgb2Ygc3VwcG9ydGluZyB0aGUgTE9BRF9VTkxPQUQgb3Bjb2RlICAgKi8KCglyZXEuY21kWzddID0gY2RpLT5zYW55b19zbG90ICUgMzsKI2VuZGlmIC8qIG5vdCBTVEFOREFSRF9BVEFQSSAqLwoKCXJldHVybiBjZHJvbV9xdWV1ZV9wYWNrZXRfY29tbWFuZChkcml2ZSwgJnJlcSk7Cn0KCgovKiBMb2NrIHRoZSBkb29yIGlmIExPQ0tGTEFHIGlzIG5vbnplcm87IHVubG9jayBpdCBvdGhlcndpc2UuICovCnN0YXRpYyBpbnQKY2Ryb21fbG9ja2Rvb3IoaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgbG9ja2ZsYWcsIHN0cnVjdCByZXF1ZXN0X3NlbnNlICpzZW5zZSkKewoJc3RydWN0IHJlcXVlc3Rfc2Vuc2UgbXlfc2Vuc2U7CglzdHJ1Y3QgcmVxdWVzdCByZXE7CglpbnQgc3RhdDsKCglpZiAoc2Vuc2UgPT0gTlVMTCkKCQlzZW5zZSA9ICZteV9zZW5zZTsKCgkvKiBJZiB0aGUgZHJpdmUgY2Fubm90IGxvY2sgdGhlIGRvb3IsIGp1c3QgcHJldGVuZC4gKi8KCWlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5ub19kb29ybG9jaykgewoJCXN0YXQgPSAwOwoJfSBlbHNlIHsKCQljZHJvbV9wcmVwYXJlX3JlcXVlc3QoZHJpdmUsICZyZXEpOwoJCXJlcS5zZW5zZSA9IHNlbnNlOwoJCXJlcS5jbWRbMF0gPSBHUENNRF9QUkVWRU5UX0FMTE9XX01FRElVTV9SRU1PVkFMOwoJCXJlcS5jbWRbNF0gPSBsb2NrZmxhZyA/IDEgOiAwOwoJCXN0YXQgPSBjZHJvbV9xdWV1ZV9wYWNrZXRfY29tbWFuZChkcml2ZSwgJnJlcSk7Cgl9CgoJLyogSWYgd2UgZ290IGFuIGlsbGVnYWwgZmllbGQgZXJyb3IsIHRoZSBkcml2ZQoJICAgcHJvYmFibHkgY2Fubm90IGxvY2sgdGhlIGRvb3IuICovCglpZiAoc3RhdCAhPSAwICYmCgkgICAgc2Vuc2UtPnNlbnNlX2tleSA9PSBJTExFR0FMX1JFUVVFU1QgJiYKCSAgICAoc2Vuc2UtPmFzYyA9PSAweDI0IHx8IHNlbnNlLT5hc2MgPT0gMHgyMCkpIHsKCQlwcmludGsgKEtFUk5fRVJSICIlczogZG9vciBsb2NraW5nIG5vdCBzdXBwb3J0ZWRcbiIsCgkJCWRyaXZlLT5uYW1lKTsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5ub19kb29ybG9jayA9IDE7CgkJc3RhdCA9IDA7Cgl9CgkKCS8qIG5vIG1lZGl1bSwgdGhhdCdzIGFscmlnaHQuICovCglpZiAoc3RhdCAhPSAwICYmIHNlbnNlLT5zZW5zZV9rZXkgPT0gTk9UX1JFQURZICYmIHNlbnNlLT5hc2MgPT0gMHgzYSkKCQlzdGF0ID0gMDsKCglpZiAoc3RhdCA9PSAwKQoJCUNEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+ZG9vcl9sb2NrZWQgPSBsb2NrZmxhZzsKCglyZXR1cm4gc3RhdDsKfQoKCi8qIEVqZWN0IHRoZSBkaXNrIGlmIEVKRUNURkxBRyBpcyAwLgogICBJZiBFSkVDVEZMQUcgaXMgMSwgdHJ5IHRvIHJlbG9hZCB0aGUgZGlzay4gKi8Kc3RhdGljIGludCBjZHJvbV9lamVjdChpZGVfZHJpdmVfdCAqZHJpdmUsIGludCBlamVjdGZsYWcsCgkJICAgICAgIHN0cnVjdCByZXF1ZXN0X3NlbnNlICpzZW5zZSkKewoJc3RydWN0IHJlcXVlc3QgcmVxOwoJY2hhciBsb2VqID0gMHgwMjsKCglpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bm9fZWplY3QgJiYgIWVqZWN0ZmxhZykKCQlyZXR1cm4gLUVEUklWRV9DQU5UX0RPX1RISVM7CgkKCS8qIHJlbG9hZCBmYWlscyBvbiBzb21lIGRyaXZlcywgaWYgdGhlIHRyYXkgaXMgbG9ja2VkICovCglpZiAoQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT5kb29yX2xvY2tlZCAmJiBlamVjdGZsYWcpCgkJcmV0dXJuIDA7CgoJY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGRyaXZlLCAmcmVxKTsKCgkvKiBvbmx5IHRlbGwgZHJpdmUgdG8gY2xvc2UgdHJheSBpZiBvcGVuLCBpZiBpdCBjYW4gZG8gdGhhdCAqLwoJaWYgKGVqZWN0ZmxhZyAmJiAhQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2xvc2VfdHJheSkKCQlsb2VqID0gMDsKCglyZXEuc2Vuc2UgPSBzZW5zZTsKCXJlcS5jbWRbMF0gPSBHUENNRF9TVEFSVF9TVE9QX1VOSVQ7CglyZXEuY21kWzRdID0gbG9laiB8IChlamVjdGZsYWcgIT0gMCk7CglyZXR1cm4gY2Ryb21fcXVldWVfcGFja2V0X2NvbW1hbmQoZHJpdmUsICZyZXEpOwp9CgpzdGF0aWMgaW50IGNkcm9tX3JlYWRfY2FwYWNpdHkoaWRlX2RyaXZlX3QgKmRyaXZlLCB1bnNpZ25lZCBsb25nICpjYXBhY2l0eSwKCQkJICAgICAgIHVuc2lnbmVkIGxvbmcgKnNlY3RvcnNfcGVyX2ZyYW1lLAoJCQkgICAgICAgc3RydWN0IHJlcXVlc3Rfc2Vuc2UgKnNlbnNlKQp7CglzdHJ1Y3QgewoJCV9fdTMyIGxiYTsKCQlfX3UzMiBibG9ja2xlbjsKCX0gY2FwYnVmOwoKCWludCBzdGF0OwoJc3RydWN0IHJlcXVlc3QgcmVxOwoKCWNkcm9tX3ByZXBhcmVfcmVxdWVzdChkcml2ZSwgJnJlcSk7CgoJcmVxLnNlbnNlID0gc2Vuc2U7CglyZXEuY21kWzBdID0gR1BDTURfUkVBRF9DRFZEX0NBUEFDSVRZOwoJcmVxLmRhdGEgPSAoY2hhciAqKSZjYXBidWY7CglyZXEuZGF0YV9sZW4gPSBzaXplb2YoY2FwYnVmKTsKCglzdGF0ID0gY2Ryb21fcXVldWVfcGFja2V0X2NvbW1hbmQoZHJpdmUsICZyZXEpOwoJaWYgKHN0YXQgPT0gMCkgewoJCSpjYXBhY2l0eSA9IDEgKyBiZTMyX3RvX2NwdShjYXBidWYubGJhKTsKCQkqc2VjdG9yc19wZXJfZnJhbWUgPQoJCQliZTMyX3RvX2NwdShjYXBidWYuYmxvY2tsZW4pID4+IFNFQ1RPUl9CSVRTOwoJfQoKCXJldHVybiBzdGF0Owp9CgpzdGF0aWMgaW50IGNkcm9tX3JlYWRfdG9jZW50cnkoaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgdHJhY2tubywgaW50IG1zZl9mbGFnLAoJCQkJaW50IGZvcm1hdCwgY2hhciAqYnVmLCBpbnQgYnVmbGVuLAoJCQkJc3RydWN0IHJlcXVlc3Rfc2Vuc2UgKnNlbnNlKQp7CglzdHJ1Y3QgcmVxdWVzdCByZXE7CgoJY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGRyaXZlLCAmcmVxKTsKCglyZXEuc2Vuc2UgPSBzZW5zZTsKCXJlcS5kYXRhID0gIGJ1ZjsKCXJlcS5kYXRhX2xlbiA9IGJ1ZmxlbjsKCXJlcS5mbGFncyB8PSBSRVFfUVVJRVQ7CglyZXEuY21kWzBdID0gR1BDTURfUkVBRF9UT0NfUE1BX0FUSVA7CglyZXEuY21kWzZdID0gdHJhY2tubzsKCXJlcS5jbWRbN10gPSAoYnVmbGVuID4+IDgpOwoJcmVxLmNtZFs4XSA9IChidWZsZW4gJiAweGZmKTsKCXJlcS5jbWRbOV0gPSAoZm9ybWF0IDw8IDYpOwoKCWlmIChtc2ZfZmxhZykKCQlyZXEuY21kWzFdID0gMjsKCglyZXR1cm4gY2Ryb21fcXVldWVfcGFja2V0X2NvbW1hbmQoZHJpdmUsICZyZXEpOwp9CgoKLyogVHJ5IHRvIHJlYWQgdGhlIGVudGlyZSBUT0MgZm9yIHRoZSBkaXNrIGludG8gb3VyIGludGVybmFsIGJ1ZmZlci4gKi8Kc3RhdGljIGludCBjZHJvbV9yZWFkX3RvYyhpZGVfZHJpdmVfdCAqZHJpdmUsIHN0cnVjdCByZXF1ZXN0X3NlbnNlICpzZW5zZSkKewoJaW50IHN0YXQsIG50cmFja3MsIGk7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpID0gJmluZm8tPmRldmluZm87CglzdHJ1Y3QgYXRhcGlfdG9jICp0b2MgPSBpbmZvLT50b2M7CglzdHJ1Y3QgewoJCXN0cnVjdCBhdGFwaV90b2NfaGVhZGVyIGhkcjsKCQlzdHJ1Y3QgYXRhcGlfdG9jX2VudHJ5ICBlbnQ7Cgl9IG1zX3RtcDsKCWxvbmcgbGFzdF93cml0dGVuOwoJdW5zaWduZWQgbG9uZyBzZWN0b3JzX3Blcl9mcmFtZSA9IFNFQ1RPUlNfUEVSX0ZSQU1FOwoKCWlmICh0b2MgPT0gTlVMTCkgewoJCS8qIFRyeSB0byBhbGxvY2F0ZSBzcGFjZS4gKi8KCQl0b2MgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgYXRhcGlfdG9jKSwgR0ZQX0tFUk5FTCk7CgkJaWYgKHRvYyA9PSBOVUxMKSB7CgkJCXByaW50ayAoS0VSTl9FUlIgIiVzOiBObyBjZHJvbSBUT0MgYnVmZmVyIVxuIiwgZHJpdmUtPm5hbWUpOwoJCQlyZXR1cm4gLUVOT01FTTsKCQl9CgkJaW5mby0+dG9jID0gdG9jOwoJfQoKCS8qIENoZWNrIHRvIHNlZSBpZiB0aGUgZXhpc3RpbmcgZGF0YSBpcyBzdGlsbCB2YWxpZC4KCSAgIElmIGl0IGlzLCBqdXN0IHJldHVybi4gKi8KCSh2b2lkKSBjZHJvbV9jaGVja19zdGF0dXMoZHJpdmUsIHNlbnNlKTsKCglpZiAoQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT50b2NfdmFsaWQpCgkJcmV0dXJuIDA7CgoJLyogVHJ5IHRvIGdldCB0aGUgdG90YWwgY2Ryb20gY2FwYWNpdHkgYW5kIHNlY3RvciBzaXplLiAqLwoJc3RhdCA9IGNkcm9tX3JlYWRfY2FwYWNpdHkoZHJpdmUsICZ0b2MtPmNhcGFjaXR5LCAmc2VjdG9yc19wZXJfZnJhbWUsCgkJCQkgICBzZW5zZSk7CglpZiAoc3RhdCkKCQl0b2MtPmNhcGFjaXR5ID0gMHgxZmZmZmY7CgoJc2V0X2NhcGFjaXR5KGluZm8tPmRpc2ssIHRvYy0+Y2FwYWNpdHkgKiBzZWN0b3JzX3Blcl9mcmFtZSk7CglibGtfcXVldWVfaGFyZHNlY3Rfc2l6ZShkcml2ZS0+cXVldWUsCgkJCQlzZWN0b3JzX3Blcl9mcmFtZSA8PCBTRUNUT1JfQklUUyk7CgoJLyogRmlyc3QgcmVhZCBqdXN0IHRoZSBoZWFkZXIsIHNvIHdlIGtub3cgaG93IGxvbmcgdGhlIFRPQyBpcy4gKi8KCXN0YXQgPSBjZHJvbV9yZWFkX3RvY2VudHJ5KGRyaXZlLCAwLCAxLCAwLCAoY2hhciAqKSAmdG9jLT5oZHIsCgkJCQkgICAgc2l6ZW9mKHN0cnVjdCBhdGFwaV90b2NfaGVhZGVyKSwgc2Vuc2UpOwoJaWYgKHN0YXQpCgkJcmV0dXJuIHN0YXQ7CgojaWYgISBTVEFOREFSRF9BVEFQSQoJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnRvY3RyYWNrc19hc19iY2QpIHsKCQl0b2MtPmhkci5maXJzdF90cmFjayA9IGJjZDJiaW4odG9jLT5oZHIuZmlyc3RfdHJhY2spOwoJCXRvYy0+aGRyLmxhc3RfdHJhY2sgID0gYmNkMmJpbih0b2MtPmhkci5sYXN0X3RyYWNrKTsKCX0KI2VuZGlmICAvKiBub3QgU1RBTkRBUkRfQVRBUEkgKi8KCgludHJhY2tzID0gdG9jLT5oZHIubGFzdF90cmFjayAtIHRvYy0+aGRyLmZpcnN0X3RyYWNrICsgMTsKCWlmIChudHJhY2tzIDw9IDApCgkJcmV0dXJuIC1FSU87CglpZiAobnRyYWNrcyA+IE1BWF9UUkFDS1MpCgkJbnRyYWNrcyA9IE1BWF9UUkFDS1M7CgoJLyogTm93IHJlYWQgdGhlIHdob2xlIHNjaG1lZXIuICovCglzdGF0ID0gY2Ryb21fcmVhZF90b2NlbnRyeShkcml2ZSwgdG9jLT5oZHIuZmlyc3RfdHJhY2ssIDEsIDAsCgkJCQkgIChjaGFyICopJnRvYy0+aGRyLAoJCQkJICAgc2l6ZW9mKHN0cnVjdCBhdGFwaV90b2NfaGVhZGVyKSArCgkJCQkgICAobnRyYWNrcyArIDEpICoKCQkJCSAgIHNpemVvZihzdHJ1Y3QgYXRhcGlfdG9jX2VudHJ5KSwgc2Vuc2UpOwoKCWlmIChzdGF0ICYmIHRvYy0+aGRyLmZpcnN0X3RyYWNrID4gMSkgewoJCS8qIENkcyB3aXRoIENESSB0cmFja3Mgb25seSBkb24ndCBoYXZlIGFueSBUT0MgZW50cmllcywKCQkgICBkZXNwaXRlIG9mIHRoaXMgdGhlIHJldHVybmVkIHZhbHVlcyBhcmUKCQkgICBmaXJzdF90cmFjayA9PSBsYXN0X3RyYWNrID0gbnVtYmVyIG9mIENESSB0cmFja3MgKyAxLAoJCSAgIHNvIHRoYXQgdGhpcyBjYXNlIGlzIGluZGlzdGluZ3Vpc2hhYmxlIGZyb20gdGhlIHNhbWUKCQkgICBsYXlvdXQgcGx1cyBhbiBhZGRpdGlvbmFsIGF1ZGlvIHRyYWNrLgoJCSAgIElmIHdlIGdldCBhbiBlcnJvciBmb3IgdGhlIHJlZ3VsYXIgY2FzZSwgd2UgYXNzdW1lCgkJICAgYSBDREkgd2l0aG91dCBhZGRpdGlvbmFsIGF1ZGlvIHRyYWNrcy4gSW4gdGhpcyBjYXNlCgkJICAgdGhlIHJlYWRhYmxlIFRPQyBpcyBlbXB0eSAoQ0RJIHRyYWNrcyBhcmUgbm90IGluY2x1ZGVkKQoJCSAgIGFuZCBvbmx5IGhvbGRzIHRoZSBMZWFkb3V0IGVudHJ5LiBIZWlrbyBFad9mZWxkdCAqLwoJCW50cmFja3MgPSAwOwoJCXN0YXQgPSBjZHJvbV9yZWFkX3RvY2VudHJ5KGRyaXZlLCBDRFJPTV9MRUFET1VULCAxLCAwLAoJCQkJCSAgIChjaGFyICopJnRvYy0+aGRyLAoJCQkJCSAgIHNpemVvZihzdHJ1Y3QgYXRhcGlfdG9jX2hlYWRlcikgKwoJCQkJCSAgIChudHJhY2tzICsgMSkgKgoJCQkJCSAgIHNpemVvZihzdHJ1Y3QgYXRhcGlfdG9jX2VudHJ5KSwKCQkJCQkgICBzZW5zZSk7CgkJaWYgKHN0YXQpIHsKCQkJcmV0dXJuIHN0YXQ7CgkJfQojaWYgISBTVEFOREFSRF9BVEFQSQoJCWlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT50b2N0cmFja3NfYXNfYmNkKSB7CgkJCXRvYy0+aGRyLmZpcnN0X3RyYWNrID0gYmluMmJjZChDRFJPTV9MRUFET1VUKTsKCQkJdG9jLT5oZHIubGFzdF90cmFjayA9IGJpbjJiY2QoQ0RST01fTEVBRE9VVCk7CgkJfSBlbHNlCiNlbmRpZiAgLyogbm90IFNUQU5EQVJEX0FUQVBJICovCgkJewoJCQl0b2MtPmhkci5maXJzdF90cmFjayA9IENEUk9NX0xFQURPVVQ7CgkJCXRvYy0+aGRyLmxhc3RfdHJhY2sgPSBDRFJPTV9MRUFET1VUOwoJCX0KCX0KCglpZiAoc3RhdCkKCQlyZXR1cm4gc3RhdDsKCgl0b2MtPmhkci50b2NfbGVuZ3RoID0gbnRvaHMgKHRvYy0+aGRyLnRvY19sZW5ndGgpOwoKI2lmICEgU1RBTkRBUkRfQVRBUEkKCWlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT50b2N0cmFja3NfYXNfYmNkKSB7CgkJdG9jLT5oZHIuZmlyc3RfdHJhY2sgPSBiY2QyYmluKHRvYy0+aGRyLmZpcnN0X3RyYWNrKTsKCQl0b2MtPmhkci5sYXN0X3RyYWNrICA9IGJjZDJiaW4odG9jLT5oZHIubGFzdF90cmFjayk7Cgl9CiNlbmRpZiAgLyogbm90IFNUQU5EQVJEX0FUQVBJICovCgoJZm9yIChpPTA7IGk8PW50cmFja3M7IGkrKykgewojaWYgISBTVEFOREFSRF9BVEFQSQoJCWlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT50b2NhZGRyX2FzX2JjZCkgewoJCQlpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dG9jdHJhY2tzX2FzX2JjZCkKCQkJCXRvYy0+ZW50W2ldLnRyYWNrID0gYmNkMmJpbih0b2MtPmVudFtpXS50cmFjayk7CgkJCW1zZl9mcm9tX2JjZCgmdG9jLT5lbnRbaV0uYWRkci5tc2YpOwoJCX0KI2VuZGlmICAvKiBub3QgU1RBTkRBUkRfQVRBUEkgKi8KCQl0b2MtPmVudFtpXS5hZGRyLmxiYSA9IG1zZl90b19sYmEgKHRvYy0+ZW50W2ldLmFkZHIubXNmLm1pbnV0ZSwKCQkJCQkJICAgdG9jLT5lbnRbaV0uYWRkci5tc2Yuc2Vjb25kLAoJCQkJCQkgICB0b2MtPmVudFtpXS5hZGRyLm1zZi5mcmFtZSk7Cgl9CgoJLyogUmVhZCB0aGUgbXVsdGlzZXNzaW9uIGluZm9ybWF0aW9uLiAqLwoJaWYgKHRvYy0+aGRyLmZpcnN0X3RyYWNrICE9IENEUk9NX0xFQURPVVQpIHsKCQkvKiBSZWFkIHRoZSBtdWx0aXNlc3Npb24gaW5mb3JtYXRpb24uICovCgkJc3RhdCA9IGNkcm9tX3JlYWRfdG9jZW50cnkoZHJpdmUsIDAsIDAsIDEsIChjaGFyICopJm1zX3RtcCwKCQkJCQkgICBzaXplb2YobXNfdG1wKSwgc2Vuc2UpOwoJCWlmIChzdGF0KQoJCQlyZXR1cm4gc3RhdDsKCgkJdG9jLT5sYXN0X3Nlc3Npb25fbGJhID0gYmUzMl90b19jcHUobXNfdG1wLmVudC5hZGRyLmxiYSk7Cgl9IGVsc2UgewoJCW1zX3RtcC5oZHIuZmlyc3RfdHJhY2sgPSBtc190bXAuaGRyLmxhc3RfdHJhY2sgPSBDRFJPTV9MRUFET1VUOwoJCXRvYy0+bGFzdF9zZXNzaW9uX2xiYSA9IG1zZl90b19sYmEoMCwgMiwgMCk7IC8qIDBtIDJzIDBmICovCgl9CgojaWYgISBTVEFOREFSRF9BVEFQSQoJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnRvY2FkZHJfYXNfYmNkKSB7CgkJLyogUmUtcmVhZCBtdWx0aXNlc3Npb24gaW5mb3JtYXRpb24gdXNpbmcgTVNGIGZvcm1hdCAqLwoJCXN0YXQgPSBjZHJvbV9yZWFkX3RvY2VudHJ5KGRyaXZlLCAwLCAxLCAxLCAoY2hhciAqKSZtc190bXAsCgkJCQkJICAgc2l6ZW9mKG1zX3RtcCksIHNlbnNlKTsKCQlpZiAoc3RhdCkKCQkJcmV0dXJuIHN0YXQ7CgoJCW1zZl9mcm9tX2JjZCAoJm1zX3RtcC5lbnQuYWRkci5tc2YpOwoJCXRvYy0+bGFzdF9zZXNzaW9uX2xiYSA9IG1zZl90b19sYmEobXNfdG1wLmVudC5hZGRyLm1zZi5taW51dGUsCgkJCQkJICAJICAgbXNfdG1wLmVudC5hZGRyLm1zZi5zZWNvbmQsCgkJCQkJCSAgIG1zX3RtcC5lbnQuYWRkci5tc2YuZnJhbWUpOwoJfQojZW5kaWYgIC8qIG5vdCBTVEFOREFSRF9BVEFQSSAqLwoKCXRvYy0+eGFfZmxhZyA9IChtc190bXAuaGRyLmZpcnN0X3RyYWNrICE9IG1zX3RtcC5oZHIubGFzdF90cmFjayk7CgoJLyogTm93IHRyeSB0byBnZXQgdGhlIHRvdGFsIGNkcm9tIGNhcGFjaXR5LiAqLwoJc3RhdCA9IGNkcm9tX2dldF9sYXN0X3dyaXR0ZW4oY2RpLCAmbGFzdF93cml0dGVuKTsKCWlmICghc3RhdCAmJiAobGFzdF93cml0dGVuID4gdG9jLT5jYXBhY2l0eSkpIHsKCQl0b2MtPmNhcGFjaXR5ID0gbGFzdF93cml0dGVuOwoJCXNldF9jYXBhY2l0eShpbmZvLT5kaXNrLCB0b2MtPmNhcGFjaXR5ICogc2VjdG9yc19wZXJfZnJhbWUpOwoJfQoKCS8qIFJlbWVtYmVyIHRoYXQgd2UndmUgcmVhZCB0aGlzIHN0dWZmLiAqLwoJQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT50b2NfdmFsaWQgPSAxOwoKCXJldHVybiAwOwp9CgoKc3RhdGljIGludCBjZHJvbV9yZWFkX3N1YmNoYW5uZWwoaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgZm9ybWF0LCBjaGFyICpidWYsCgkJCQkgaW50IGJ1Zmxlbiwgc3RydWN0IHJlcXVlc3Rfc2Vuc2UgKnNlbnNlKQp7CglzdHJ1Y3QgcmVxdWVzdCByZXE7CgoJY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGRyaXZlLCAmcmVxKTsKCglyZXEuc2Vuc2UgPSBzZW5zZTsKCXJlcS5kYXRhID0gYnVmOwoJcmVxLmRhdGFfbGVuID0gYnVmbGVuOwoJcmVxLmNtZFswXSA9IEdQQ01EX1JFQURfU1VCQ0hBTk5FTDsKCXJlcS5jbWRbMV0gPSAyOyAgICAgLyogTVNGIGFkZHJlc3NpbmcgKi8KCXJlcS5jbWRbMl0gPSAweDQwOyAgLyogcmVxdWVzdCBzdWJRIGRhdGEgKi8KCXJlcS5jbWRbM10gPSBmb3JtYXQ7CglyZXEuY21kWzddID0gKGJ1ZmxlbiA+PiA4KTsKCXJlcS5jbWRbOF0gPSAoYnVmbGVuICYgMHhmZik7CglyZXR1cm4gY2Ryb21fcXVldWVfcGFja2V0X2NvbW1hbmQoZHJpdmUsICZyZXEpOwp9CgovKiBBVEFQSSBjZHJvbSBkcml2ZXMgYXJlIGZyZWUgdG8gc2VsZWN0IHRoZSBzcGVlZCB5b3UgcmVxdWVzdCBvciBhbnkgc2xvd2VyCiAgIHJhdGUgOi0oIFJlcXVlc3RpbmcgdG9vIGZhc3QgYSBzcGVlZCB3aWxsIF9ub3RfIHByb2R1Y2UgYW4gZXJyb3IuICovCnN0YXRpYyBpbnQgY2Ryb21fc2VsZWN0X3NwZWVkKGlkZV9kcml2ZV90ICpkcml2ZSwgaW50IHNwZWVkLAoJCQkgICAgICBzdHJ1Y3QgcmVxdWVzdF9zZW5zZSAqc2Vuc2UpCnsKCXN0cnVjdCByZXF1ZXN0IHJlcTsKCWNkcm9tX3ByZXBhcmVfcmVxdWVzdChkcml2ZSwgJnJlcSk7CgoJcmVxLnNlbnNlID0gc2Vuc2U7CglpZiAoc3BlZWQgPT0gMCkKCQlzcGVlZCA9IDB4ZmZmZjsgLyogc2V0IHRvIG1heCAqLwoJZWxzZQoJCXNwZWVkICo9IDE3NzsgICAvKiBOeCB0byBrYnl0ZXMvcyAqLwoKCXJlcS5jbWRbMF0gPSBHUENNRF9TRVRfU1BFRUQ7CgkvKiBSZWFkIERyaXZlIHNwZWVkIGluIGtieXRlcy9zZWNvbmQgTVNCICovCglyZXEuY21kWzJdID0gKHNwZWVkID4+IDgpICYgMHhmZjsJCgkvKiBSZWFkIERyaXZlIHNwZWVkIGluIGtieXRlcy9zZWNvbmQgTFNCICovCglyZXEuY21kWzNdID0gc3BlZWQgJiAweGZmOwoJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNkX3IgfHwKCSAgICBDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5jZF9ydyB8fAoJICAgIENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZF9yKSB7CgkJLyogV3JpdGUgRHJpdmUgc3BlZWQgaW4ga2J5dGVzL3NlY29uZCBNU0IgKi8KCQlyZXEuY21kWzRdID0gKHNwZWVkID4+IDgpICYgMHhmZjsKCQkvKiBXcml0ZSBEcml2ZSBzcGVlZCBpbiBrYnl0ZXMvc2Vjb25kIExTQiAqLwoJCXJlcS5jbWRbNV0gPSBzcGVlZCAmIDB4ZmY7CiAgICAgICB9CgoJcmV0dXJuIGNkcm9tX3F1ZXVlX3BhY2tldF9jb21tYW5kKGRyaXZlLCAmcmVxKTsKfQoKc3RhdGljIGludCBjZHJvbV9wbGF5X2F1ZGlvKGlkZV9kcml2ZV90ICpkcml2ZSwgaW50IGxiYV9zdGFydCwgaW50IGxiYV9lbmQpCnsKCXN0cnVjdCByZXF1ZXN0X3NlbnNlIHNlbnNlOwoJc3RydWN0IHJlcXVlc3QgcmVxOwoKCWNkcm9tX3ByZXBhcmVfcmVxdWVzdChkcml2ZSwgJnJlcSk7CgoJcmVxLnNlbnNlID0gJnNlbnNlOwoJcmVxLmNtZFswXSA9IEdQQ01EX1BMQVlfQVVESU9fTVNGOwoJbGJhX3RvX21zZihsYmFfc3RhcnQsICZyZXEuY21kWzNdLCAmcmVxLmNtZFs0XSwgJnJlcS5jbWRbNV0pOwoJbGJhX3RvX21zZihsYmFfZW5kLTEsICZyZXEuY21kWzZdLCAmcmVxLmNtZFs3XSwgJnJlcS5jbWRbOF0pOwoKCXJldHVybiBjZHJvbV9xdWV1ZV9wYWNrZXRfY29tbWFuZChkcml2ZSwgJnJlcSk7Cn0KCnN0YXRpYyBpbnQgY2Ryb21fZ2V0X3RvY19lbnRyeShpZGVfZHJpdmVfdCAqZHJpdmUsIGludCB0cmFjaywKCQkJCXN0cnVjdCBhdGFwaV90b2NfZW50cnkgKiplbnQpCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJc3RydWN0IGF0YXBpX3RvYyAqdG9jID0gaW5mby0+dG9jOwoJaW50IG50cmFja3M7CgoJLyoKCSAqIGRvbid0IHNlcnZlIGNhY2hlZCBkYXRhLCBpZiB0aGUgdG9jIGlzbid0IHZhbGlkCgkgKi8KCWlmICghQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT50b2NfdmFsaWQpCgkJcmV0dXJuIC1FSU5WQUw7CgoJLyogQ2hlY2sgdmFsaWRpdHkgb2YgcmVxdWVzdGVkIHRyYWNrIG51bWJlci4gKi8KCW50cmFja3MgPSB0b2MtPmhkci5sYXN0X3RyYWNrIC0gdG9jLT5oZHIuZmlyc3RfdHJhY2sgKyAxOwoJaWYgKHRvYy0+aGRyLmZpcnN0X3RyYWNrID09IENEUk9NX0xFQURPVVQpIG50cmFja3MgPSAwOwoJaWYgKHRyYWNrID09IENEUk9NX0xFQURPVVQpCgkJKmVudCA9ICZ0b2MtPmVudFtudHJhY2tzXTsKCWVsc2UgaWYgKHRyYWNrIDwgdG9jLT5oZHIuZmlyc3RfdHJhY2sgfHwKCQkgdHJhY2sgPiB0b2MtPmhkci5sYXN0X3RyYWNrKQoJCXJldHVybiAtRUlOVkFMOwoJZWxzZQoJCSplbnQgPSAmdG9jLT5lbnRbdHJhY2sgLSB0b2MtPmhkci5maXJzdF90cmFja107CgoJcmV0dXJuIDA7Cn0KCi8qIHRoZSBnZW5lcmljIHBhY2tldCBpbnRlcmZhY2UgdG8gY2Ryb20uYyAqLwpzdGF0aWMgaW50IGlkZV9jZHJvbV9wYWNrZXQoc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGksCgkJCSAgICBzdHJ1Y3QgcGFja2V0X2NvbW1hbmQgKmNnYykKewoJc3RydWN0IHJlcXVlc3QgcmVxOwoJaWRlX2RyaXZlX3QgKmRyaXZlID0gY2RpLT5oYW5kbGU7CgoJaWYgKGNnYy0+dGltZW91dCA8PSAwKQoJCWNnYy0+dGltZW91dCA9IEFUQVBJX1dBSVRfUEM7CgoJLyogaGVyZSB3ZSBxdWV1ZSB0aGUgY29tbWFuZHMgZnJvbSB0aGUgdW5pZm9ybSBDRC1ST00KCSAgIGxheWVyLiB0aGUgcGFja2V0IG11c3QgYmUgY29tcGxldGUsIGFzIHdlIGRvIG5vdAoJICAgdG91Y2ggaXQgYXQgYWxsLiAqLwoJY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGRyaXZlLCAmcmVxKTsKCW1lbWNweShyZXEuY21kLCBjZ2MtPmNtZCwgQ0RST01fUEFDS0VUX1NJWkUpOwoJaWYgKGNnYy0+c2Vuc2UpCgkJbWVtc2V0KGNnYy0+c2Vuc2UsIDAsIHNpemVvZihzdHJ1Y3QgcmVxdWVzdF9zZW5zZSkpOwoJcmVxLmRhdGEgPSBjZ2MtPmJ1ZmZlcjsKCXJlcS5kYXRhX2xlbiA9IGNnYy0+YnVmbGVuOwoJcmVxLnRpbWVvdXQgPSBjZ2MtPnRpbWVvdXQ7CgoJaWYgKGNnYy0+cXVpZXQpCgkJcmVxLmZsYWdzIHw9IFJFUV9RVUlFVDsKCglyZXEuc2Vuc2UgPSBjZ2MtPnNlbnNlOwoJY2djLT5zdGF0ID0gY2Ryb21fcXVldWVfcGFja2V0X2NvbW1hbmQoZHJpdmUsICZyZXEpOwoJaWYgKCFjZ2MtPnN0YXQpCgkJY2djLT5idWZsZW4gLT0gcmVxLmRhdGFfbGVuOwoJcmV0dXJuIGNnYy0+c3RhdDsKfQoKc3RhdGljCmludCBpZGVfY2Ryb21fZGV2X2lvY3RsIChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSwKCQkJIHVuc2lnbmVkIGludCBjbWQsIHVuc2lnbmVkIGxvbmcgYXJnKQp7CglzdHJ1Y3QgcGFja2V0X2NvbW1hbmQgY2djOwoJY2hhciBidWZmZXJbMTZdOwoJaW50IHN0YXQ7CgoJaW5pdF9jZHJvbV9jb21tYW5kKCZjZ2MsIGJ1ZmZlciwgc2l6ZW9mKGJ1ZmZlciksIENHQ19EQVRBX1VOS05PV04pOwoKCS8qIFRoZXNlIHdpbGwgYmUgbW92ZWQgaW50byB0aGUgVW5pZm9ybSBsYXllciBzaG9ydGx5Li4uICovCglzd2l0Y2ggKGNtZCkgewogCWNhc2UgQ0RST01TRVRTUElORE9XTjogewogCQljaGFyIHNwaW5kb3duOwogCiAJCWlmIChjb3B5X2Zyb21fdXNlcigmc3BpbmRvd24sICh2b2lkIF9fdXNlciAqKSBhcmcsIHNpemVvZihjaGFyKSkpCgkJCXJldHVybiAtRUZBVUxUOwogCiAgICAgICAgICAgICAgICBpZiAoKHN0YXQgPSBjZHJvbV9tb2RlX3NlbnNlKGNkaSwgJmNnYywgR1BNT0RFX0NEUk9NX1BBR0UsIDApKSkKCQkJcmV0dXJuIHN0YXQ7CgogCQlidWZmZXJbMTFdID0gKGJ1ZmZlclsxMV0gJiAweGYwKSB8IChzcGluZG93biAmIDB4MGYpOwoKIAkJcmV0dXJuIGNkcm9tX21vZGVfc2VsZWN0KGNkaSwgJmNnYyk7CiAJfSAKIAogCWNhc2UgQ0RST01HRVRTUElORE9XTjogewogCQljaGFyIHNwaW5kb3duOwogCiAgICAgICAgICAgICAgICBpZiAoKHN0YXQgPSBjZHJvbV9tb2RlX3NlbnNlKGNkaSwgJmNnYywgR1BNT0RFX0NEUk9NX1BBR0UsIDApKSkKCQkJcmV0dXJuIHN0YXQ7CiAKIAkJc3BpbmRvd24gPSBidWZmZXJbMTFdICYgMHgwZjsKIAoJCWlmIChjb3B5X3RvX3VzZXIoKHZvaWQgX191c2VyICopIGFyZywgJnNwaW5kb3duLCBzaXplb2YgKGNoYXIpKSkKCQkJcmV0dXJuIC1FRkFVTFQ7CiAKIAkJcmV0dXJuIDA7CiAJfQogIAoJZGVmYXVsdDoKCQlyZXR1cm4gLUVJTlZBTDsKCX0KCn0KCnN0YXRpYwppbnQgaWRlX2Nkcm9tX2F1ZGlvX2lvY3RsIChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSwKCQkJICAgdW5zaWduZWQgaW50IGNtZCwgdm9pZCAqYXJnKQoJCQkgICAKewoJaWRlX2RyaXZlX3QgKmRyaXZlID0gY2RpLT5oYW5kbGU7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCWludCBzdGF0OwoKCXN3aXRjaCAoY21kKSB7CgkvKgoJICogZW11bGF0ZSBQTEFZX0FVRElPX1RJIGNvbW1hbmQgd2l0aCBQTEFZX0FVRElPXzEwLCBzaW5jZQoJICogYXRhcGkgZG9lc24ndCBzdXBwb3J0IGl0CgkgKi8KCWNhc2UgQ0RST01QTEFZVFJLSU5EOiB7CgkJdW5zaWduZWQgbG9uZyBsYmFfc3RhcnQsIGxiYV9lbmQ7CgkJc3RydWN0IGNkcm9tX3RpICp0aSA9IGFyZzsKCQlzdHJ1Y3QgYXRhcGlfdG9jX2VudHJ5ICpmaXJzdF90b2MsICpsYXN0X3RvYzsKCgkJc3RhdCA9IGNkcm9tX2dldF90b2NfZW50cnkoZHJpdmUsIHRpLT5jZHRpX3RyazAsICZmaXJzdF90b2MpOwoJCWlmIChzdGF0KQoJCQlyZXR1cm4gc3RhdDsKCgkJc3RhdCA9IGNkcm9tX2dldF90b2NfZW50cnkoZHJpdmUsIHRpLT5jZHRpX3RyazEsICZsYXN0X3RvYyk7CgkJaWYgKHN0YXQpCgkJCXJldHVybiBzdGF0OwoKCQlpZiAodGktPmNkdGlfdHJrMSAhPSBDRFJPTV9MRUFET1VUKQoJCQkrK2xhc3RfdG9jOwoJCWxiYV9zdGFydCA9IGZpcnN0X3RvYy0+YWRkci5sYmE7CgkJbGJhX2VuZCAgID0gbGFzdF90b2MtPmFkZHIubGJhOwoKCQlpZiAobGJhX2VuZCA8PSBsYmFfc3RhcnQpCgkJCXJldHVybiAtRUlOVkFMOwoKCQlyZXR1cm4gY2Ryb21fcGxheV9hdWRpbyhkcml2ZSwgbGJhX3N0YXJ0LCBsYmFfZW5kKTsKCX0KCgljYXNlIENEUk9NUkVBRFRPQ0hEUjogewoJCXN0cnVjdCBjZHJvbV90b2NoZHIgKnRvY2hkciA9IGFyZzsKCQlzdHJ1Y3QgYXRhcGlfdG9jICp0b2M7CgoJCS8qIE1ha2Ugc3VyZSBvdXIgc2F2ZWQgVE9DIGlzIHZhbGlkLiAqLwoJCXN0YXQgPSBjZHJvbV9yZWFkX3RvYyhkcml2ZSwgTlVMTCk7CgkJaWYgKHN0YXQpCgkJCXJldHVybiBzdGF0OwoKCQl0b2MgPSBpbmZvLT50b2M7CgkJdG9jaGRyLT5jZHRoX3RyazAgPSB0b2MtPmhkci5maXJzdF90cmFjazsKCQl0b2NoZHItPmNkdGhfdHJrMSA9IHRvYy0+aGRyLmxhc3RfdHJhY2s7CgoJCXJldHVybiAwOwoJfQoKCWNhc2UgQ0RST01SRUFEVE9DRU5UUlk6IHsKCQlzdHJ1Y3QgY2Ryb21fdG9jZW50cnkgKnRvY2VudHJ5ID0gYXJnOwoJCXN0cnVjdCBhdGFwaV90b2NfZW50cnkgKnRvY2U7CgoJCXN0YXQgPSBjZHJvbV9nZXRfdG9jX2VudHJ5KGRyaXZlLCB0b2NlbnRyeS0+Y2R0ZV90cmFjaywgJnRvY2UpOwoJCWlmIChzdGF0KQoJCQlyZXR1cm4gc3RhdDsKCgkJdG9jZW50cnktPmNkdGVfY3RybCA9IHRvY2UtPmNvbnRyb2w7CgkJdG9jZW50cnktPmNkdGVfYWRyICA9IHRvY2UtPmFkcjsKCQlpZiAodG9jZW50cnktPmNkdGVfZm9ybWF0ID09IENEUk9NX01TRikgewoJCQlsYmFfdG9fbXNmICh0b2NlLT5hZGRyLmxiYSwKCQkJCSAgICZ0b2NlbnRyeS0+Y2R0ZV9hZGRyLm1zZi5taW51dGUsCgkJCQkgICAmdG9jZW50cnktPmNkdGVfYWRkci5tc2Yuc2Vjb25kLAoJCQkJICAgJnRvY2VudHJ5LT5jZHRlX2FkZHIubXNmLmZyYW1lKTsKCQl9IGVsc2UKCQkJdG9jZW50cnktPmNkdGVfYWRkci5sYmEgPSB0b2NlLT5hZGRyLmxiYTsKCgkJcmV0dXJuIDA7Cgl9CgoJZGVmYXVsdDoKCQlyZXR1cm4gLUVJTlZBTDsKCX0KfQoKc3RhdGljCmludCBpZGVfY2Ryb21fcmVzZXQgKHN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpKQp7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSBjZGktPmhhbmRsZTsKCXN0cnVjdCByZXF1ZXN0X3NlbnNlIHNlbnNlOwoJc3RydWN0IHJlcXVlc3QgcmVxOwoJaW50IHJldDsKCgljZHJvbV9wcmVwYXJlX3JlcXVlc3QoZHJpdmUsICZyZXEpOwoJcmVxLmZsYWdzID0gUkVRX1NQRUNJQUwgfCBSRVFfUVVJRVQ7CglyZXQgPSBpZGVfZG9fZHJpdmVfY21kKGRyaXZlLCAmcmVxLCBpZGVfd2FpdCk7CgoJLyoKCSAqIEEgcmVzZXQgd2lsbCB1bmxvY2sgdGhlIGRvb3IuIElmIGl0IHdhcyBwcmV2aW91c2x5IGxvY2tlZCwKCSAqIGxvY2sgaXQgYWdhaW4uCgkgKi8KCWlmIChDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPmRvb3JfbG9ja2VkKQoJCSh2b2lkKSBjZHJvbV9sb2NrZG9vcihkcml2ZSwgMSwgJnNlbnNlKTsKCglyZXR1cm4gcmV0Owp9CgoKc3RhdGljCmludCBpZGVfY2Ryb21fdHJheV9tb3ZlIChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSwgaW50IHBvc2l0aW9uKQp7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSBjZGktPmhhbmRsZTsKCXN0cnVjdCByZXF1ZXN0X3NlbnNlIHNlbnNlOwoKCWlmIChwb3NpdGlvbikgewoJCWludCBzdGF0ID0gY2Ryb21fbG9ja2Rvb3IoZHJpdmUsIDAsICZzZW5zZSk7CgkJaWYgKHN0YXQpCgkJCXJldHVybiBzdGF0OwoJfQoKCXJldHVybiBjZHJvbV9lamVjdChkcml2ZSwgIXBvc2l0aW9uLCAmc2Vuc2UpOwp9CgpzdGF0aWMKaW50IGlkZV9jZHJvbV9sb2NrX2Rvb3IgKHN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpLCBpbnQgbG9jaykKewoJaWRlX2RyaXZlX3QgKmRyaXZlID0gY2RpLT5oYW5kbGU7CglyZXR1cm4gY2Ryb21fbG9ja2Rvb3IoZHJpdmUsIGxvY2ssIE5VTEwpOwp9CgpzdGF0aWMKaW50IGlkZV9jZHJvbV9nZXRfY2FwYWJpbGl0aWVzKGlkZV9kcml2ZV90ICpkcml2ZSwgc3RydWN0IGF0YXBpX2NhcGFiaWxpdGllc19wYWdlICpjYXApCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGkgPSAmaW5mby0+ZGV2aW5mbzsKCXN0cnVjdCBwYWNrZXRfY29tbWFuZCBjZ2M7CglpbnQgc3RhdCwgYXR0ZW1wdHMgPSAzLCBzaXplID0gc2l6ZW9mKCpjYXApOwoKCS8qCgkgKiBBQ0VSNTAgKGFuZCBvdGhlcnM/KSByZXF1aXJlIHRoZSBmdWxsIHNwZWMgbGVuZ3RoIG1vZGUgc2Vuc2UKCSAqIHBhZ2UgY2FwYWJpbGl0aWVzIHNpemUsIGJ1dCBvbGRlciBkcml2ZXMgYnJlYWsuCgkgKi8KCWlmICghKCFzdHJjbXAoZHJpdmUtPmlkLT5tb2RlbCwgIkFUQVBJIENEIFJPTSBEUklWRSA1MFggTUFYIikgfHwKCSAgICAhc3RyY21wKGRyaXZlLT5pZC0+bW9kZWwsICJXUEkgQ0RTLTMyWCIpKSkKCQlzaXplIC09IHNpemVvZihjYXAtPnBhZCk7CgoJaW5pdF9jZHJvbV9jb21tYW5kKCZjZ2MsIGNhcCwgc2l6ZSwgQ0dDX0RBVEFfVU5LTk9XTik7CglkbyB7IC8qIHdlIHNlZW0gdG8gZ2V0IHN0YXQ9MHgwMSxlcnI9MHgwMCB0aGUgZmlyc3QgdGltZSAoPz8pICovCgkJc3RhdCA9IGNkcm9tX21vZGVfc2Vuc2UoY2RpLCAmY2djLCBHUE1PREVfQ0FQQUJJTElUSUVTX1BBR0UsIDApOwoJCWlmICghc3RhdCkKCQkJYnJlYWs7Cgl9IHdoaWxlICgtLWF0dGVtcHRzKTsKCXJldHVybiBzdGF0Owp9CgpzdGF0aWMKdm9pZCBpZGVfY2Ryb21fdXBkYXRlX3NwZWVkIChpZGVfZHJpdmVfdCAqZHJpdmUsIHN0cnVjdCBhdGFwaV9jYXBhYmlsaXRpZXNfcGFnZSAqY2FwKQp7CgkvKiBUaGUgQUNFUi9BT3BlbiAyNFggY2Ryb20gaGFzIHRoZSBzcGVlZCBmaWVsZHMgYnl0ZS1zd2FwcGVkICovCglpZiAoIWRyaXZlLT5pZC0+bW9kZWxbMF0gJiYKCSAgICAhc3RybmNtcChkcml2ZS0+aWQtPmZ3X3JldiwgIjI0MU4iLCA0KSkgewoJCUNEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+Y3VycmVudF9zcGVlZCAgPQoJCQkoKCh1bnNpZ25lZCBpbnQpY2FwLT5jdXJzcGVlZCkgKyAoMTc2LzIpKSAvIDE3NjsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5tYXhfc3BlZWQgPQoJCQkoKCh1bnNpZ25lZCBpbnQpY2FwLT5tYXhzcGVlZCkgKyAoMTc2LzIpKSAvIDE3NjsKCX0gZWxzZSB7CgkJQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT5jdXJyZW50X3NwZWVkICA9CgkJCShudG9ocyhjYXAtPmN1cnNwZWVkKSArICgxNzYvMikpIC8gMTc2OwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPm1heF9zcGVlZCA9CgkJCShudG9ocyhjYXAtPm1heHNwZWVkKSArICgxNzYvMikpIC8gMTc2OwoJfQp9CgpzdGF0aWMKaW50IGlkZV9jZHJvbV9zZWxlY3Rfc3BlZWQgKHN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpLCBpbnQgc3BlZWQpCnsKCWlkZV9kcml2ZV90ICpkcml2ZSA9IGNkaS0+aGFuZGxlOwoJc3RydWN0IHJlcXVlc3Rfc2Vuc2Ugc2Vuc2U7CglzdHJ1Y3QgYXRhcGlfY2FwYWJpbGl0aWVzX3BhZ2UgY2FwOwoJaW50IHN0YXQ7CgoJaWYgKChzdGF0ID0gY2Ryb21fc2VsZWN0X3NwZWVkKGRyaXZlLCBzcGVlZCwgJnNlbnNlKSkgPCAwKQoJCXJldHVybiBzdGF0OwoKCWlmICghaWRlX2Nkcm9tX2dldF9jYXBhYmlsaXRpZXMoZHJpdmUsICZjYXApKSB7CgkJaWRlX2Nkcm9tX3VwZGF0ZV9zcGVlZChkcml2ZSwgJmNhcCk7CgkJY2RpLT5zcGVlZCA9IENEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+Y3VycmVudF9zcGVlZDsKCX0KICAgICAgICByZXR1cm4gMDsKfQoKLyoKICogYWRkIGxvZ2ljIHRvIHRyeSBHRVRfRVZFTlQgY29tbWFuZCBmaXJzdCB0byBjaGVjayBmb3IgbWVkaWEgYW5kIHRyYXkKICogc3RhdHVzLiB0aGlzIHNob3VsZCBiZSBzdXBwb3J0ZWQgYnkgbmV3ZXIgY2Qtci93IGFuZCBhbGwgRFZEIGV0YwogKiBkcml2ZXMKICovCnN0YXRpYwppbnQgaWRlX2Nkcm9tX2RyaXZlX3N0YXR1cyAoc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGksIGludCBzbG90X25yKQp7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSBjZGktPmhhbmRsZTsKCXN0cnVjdCBtZWRpYV9ldmVudF9kZXNjIG1lZDsKCXN0cnVjdCByZXF1ZXN0X3NlbnNlIHNlbnNlOwoJaW50IHN0YXQ7CgoJaWYgKHNsb3RfbnIgIT0gQ0RTTF9DVVJSRU5UKQoJCXJldHVybiAtRUlOVkFMOwoKCXN0YXQgPSBjZHJvbV9jaGVja19zdGF0dXMoZHJpdmUsICZzZW5zZSk7CglpZiAoIXN0YXQgfHwgc2Vuc2Uuc2Vuc2Vfa2V5ID09IFVOSVRfQVRURU5USU9OKQoJCXJldHVybiBDRFNfRElTQ19PSzsKCglpZiAoIWNkcm9tX2dldF9tZWRpYV9ldmVudChjZGksICZtZWQpKSB7CgkJaWYgKG1lZC5tZWRpYV9wcmVzZW50KQoJCQlyZXR1cm4gQ0RTX0RJU0NfT0s7CgkJZWxzZSBpZiAobWVkLmRvb3Jfb3BlbikKCQkJcmV0dXJuIENEU19UUkFZX09QRU47CgkJZWxzZQoJCQlyZXR1cm4gQ0RTX05PX0RJU0M7Cgl9CgoJaWYgKHNlbnNlLnNlbnNlX2tleSA9PSBOT1RfUkVBRFkgJiYgc2Vuc2UuYXNjID09IDB4MDQgJiYgc2Vuc2UuYXNjcSA9PSAweDA0KQoJCXJldHVybiBDRFNfRElTQ19PSzsKCgkvKgoJICogSWYgbm90IHVzaW5nIE10IEZ1amkgZXh0ZW5kZWQgbWVkaWEgdHJheSByZXBvcnRzLAoJICoganVzdCByZXR1cm4gVFJBWV9PUEVOIHNpbmNlIEFUQVBJIGRvZXNuJ3QgcHJvdmlkZQoJICogYW55IG90aGVyIHdheSB0byBkZXRlY3QgdGhpcy4uLgoJICovCglpZiAoc2Vuc2Uuc2Vuc2Vfa2V5ID09IE5PVF9SRUFEWSkgewoJCWlmIChzZW5zZS5hc2MgPT0gMHgzYSkgewoJCQlpZiAoc2Vuc2UuYXNjcSA9PSAxKQoJCQkJcmV0dXJuIENEU19OT19ESVNDOwoJCQllbHNlIGlmIChzZW5zZS5hc2NxID09IDAgfHwgc2Vuc2UuYXNjcSA9PSAyKQoJCQkJcmV0dXJuIENEU19UUkFZX09QRU47CgkJfQoJfQoKCXJldHVybiBDRFNfRFJJVkVfTk9UX1JFQURZOwp9CgpzdGF0aWMKaW50IGlkZV9jZHJvbV9nZXRfbGFzdF9zZXNzaW9uIChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSwKCQkJCXN0cnVjdCBjZHJvbV9tdWx0aXNlc3Npb24gKm1zX2luZm8pCnsKCXN0cnVjdCBhdGFwaV90b2MgKnRvYzsKCWlkZV9kcml2ZV90ICpkcml2ZSA9IGNkaS0+aGFuZGxlOwoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglzdHJ1Y3QgcmVxdWVzdF9zZW5zZSBzZW5zZTsKCWludCByZXQ7CgoJaWYgKCFDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPnRvY192YWxpZCB8fCBpbmZvLT50b2MgPT0gTlVMTCkKCQlpZiAoKHJldCA9IGNkcm9tX3JlYWRfdG9jKGRyaXZlLCAmc2Vuc2UpKSkKCQkJcmV0dXJuIHJldDsKCgl0b2MgPSBpbmZvLT50b2M7Cgltc19pbmZvLT5hZGRyLmxiYSA9IHRvYy0+bGFzdF9zZXNzaW9uX2xiYTsKCW1zX2luZm8tPnhhX2ZsYWcgPSB0b2MtPnhhX2ZsYWc7CgoJcmV0dXJuIDA7Cn0KCnN0YXRpYwppbnQgaWRlX2Nkcm9tX2dldF9tY24gKHN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpLAoJCSAgICAgICBzdHJ1Y3QgY2Ryb21fbWNuICptY25faW5mbykKewoJaW50IHN0YXQ7CgljaGFyIG1jbmJ1ZlsyNF07CglpZGVfZHJpdmVfdCAqZHJpdmUgPSBjZGktPmhhbmRsZTsKCi8qIGdldCBNQ04gKi8KCWlmICgoc3RhdCA9IGNkcm9tX3JlYWRfc3ViY2hhbm5lbChkcml2ZSwgMiwgbWNuYnVmLCBzaXplb2YgKG1jbmJ1ZiksIE5VTEwpKSkKCQlyZXR1cm4gc3RhdDsKCgltZW1jcHkgKG1jbl9pbmZvLT5tZWRpdW1fY2F0YWxvZ19udW1iZXIsIG1jbmJ1Zis5LAoJCXNpemVvZiAobWNuX2luZm8tPm1lZGl1bV9jYXRhbG9nX251bWJlciktMSk7CgltY25faW5mby0+bWVkaXVtX2NhdGFsb2dfbnVtYmVyW3NpemVvZiAobWNuX2luZm8tPm1lZGl1bV9jYXRhbG9nX251bWJlciktMV0KCQk9ICdcMCc7CgoJcmV0dXJuIDA7Cn0KCgoKLyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogT3RoZXIgZHJpdmVyIHJlcXVlc3RzIChvcGVuLCBjbG9zZSwgY2hlY2sgbWVkaWEgY2hhbmdlKS4KICovCgpzdGF0aWMKaW50IGlkZV9jZHJvbV9jaGVja19tZWRpYV9jaGFuZ2VfcmVhbCAoc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGksCgkJCQkgICAgICAgaW50IHNsb3RfbnIpCnsKCWlkZV9kcml2ZV90ICpkcml2ZSA9IGNkaS0+aGFuZGxlOwoJaW50IHJldHZhbDsKCQoJaWYgKHNsb3RfbnIgPT0gQ0RTTF9DVVJSRU5UKSB7CgkJKHZvaWQpIGNkcm9tX2NoZWNrX3N0YXR1cyhkcml2ZSwgTlVMTCk7CgkJcmV0dmFsID0gQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT5tZWRpYV9jaGFuZ2VkOwoJCUNEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+bWVkaWFfY2hhbmdlZCA9IDA7CgkJcmV0dXJuIHJldHZhbDsKCX0gZWxzZSB7CgkJcmV0dXJuIC1FSU5WQUw7Cgl9Cn0KCgpzdGF0aWMKaW50IGlkZV9jZHJvbV9vcGVuX3JlYWwgKHN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpLCBpbnQgcHVycG9zZSkKewoJcmV0dXJuIDA7Cn0KCi8qCiAqIENsb3NlIGRvd24gdGhlIGRldmljZS4gIEludmFsaWRhdGUgYWxsIGNhY2hlZCBibG9ja3MuCiAqLwoKc3RhdGljCnZvaWQgaWRlX2Nkcm9tX3JlbGVhc2VfcmVhbCAoc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGkpCnsKCWlkZV9kcml2ZV90ICpkcml2ZSA9IGNkaS0+aGFuZGxlOwoKCWlmICghY2RpLT51c2VfY291bnQpCgkJQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT50b2NfdmFsaWQgPSAwOwp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIERldmljZSBpbml0aWFsaXphdGlvbi4KICovCnN0YXRpYyBzdHJ1Y3QgY2Ryb21fZGV2aWNlX29wcyBpZGVfY2Ryb21fZG9wcyA9IHsKCS5vcGVuCQkJPSBpZGVfY2Ryb21fb3Blbl9yZWFsLAoJLnJlbGVhc2UJCT0gaWRlX2Nkcm9tX3JlbGVhc2VfcmVhbCwKCS5kcml2ZV9zdGF0dXMJCT0gaWRlX2Nkcm9tX2RyaXZlX3N0YXR1cywKCS5tZWRpYV9jaGFuZ2VkCQk9IGlkZV9jZHJvbV9jaGVja19tZWRpYV9jaGFuZ2VfcmVhbCwKCS50cmF5X21vdmUJCT0gaWRlX2Nkcm9tX3RyYXlfbW92ZSwKCS5sb2NrX2Rvb3IJCT0gaWRlX2Nkcm9tX2xvY2tfZG9vciwKCS5zZWxlY3Rfc3BlZWQJCT0gaWRlX2Nkcm9tX3NlbGVjdF9zcGVlZCwKCS5nZXRfbGFzdF9zZXNzaW9uCT0gaWRlX2Nkcm9tX2dldF9sYXN0X3Nlc3Npb24sCgkuZ2V0X21jbgkJPSBpZGVfY2Ryb21fZ2V0X21jbiwKCS5yZXNldAkJCT0gaWRlX2Nkcm9tX3Jlc2V0LAoJLmF1ZGlvX2lvY3RsCQk9IGlkZV9jZHJvbV9hdWRpb19pb2N0bCwKCS5kZXZfaW9jdGwJCT0gaWRlX2Nkcm9tX2Rldl9pb2N0bCwKCS5jYXBhYmlsaXR5CQk9IENEQ19DTE9TRV9UUkFZIHwgQ0RDX09QRU5fVFJBWSB8IENEQ19MT0NLIHwKCQkJCUNEQ19TRUxFQ1RfU1BFRUQgfCBDRENfU0VMRUNUX0RJU0MgfAoJCQkJQ0RDX01VTFRJX1NFU1NJT04gfCBDRENfTUNOIHwKCQkJCUNEQ19NRURJQV9DSEFOR0VEIHwgQ0RDX1BMQVlfQVVESU8gfCBDRENfUkVTRVQgfAoJCQkJQ0RDX0lPQ1RMUyB8IENEQ19EUklWRV9TVEFUVVMgfCBDRENfQ0RfUiB8CgkJCQlDRENfQ0RfUlcgfCBDRENfRFZEIHwgQ0RDX0RWRF9SfCBDRENfRFZEX1JBTSB8CgkJCQlDRENfR0VORVJJQ19QQUNLRVQgfCBDRENfTU9fRFJJVkUgfCBDRENfTVJXIHwKCQkJCUNEQ19NUldfVyB8IENEQ19SQU0sCgkuZ2VuZXJpY19wYWNrZXQJCT0gaWRlX2Nkcm9tX3BhY2tldCwKfTsKCnN0YXRpYyBpbnQgaWRlX2Nkcm9tX3JlZ2lzdGVyIChpZGVfZHJpdmVfdCAqZHJpdmUsIGludCBuc2xvdHMpCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpkZXZpbmZvID0gJmluZm8tPmRldmluZm87CgoJZGV2aW5mby0+b3BzID0gJmlkZV9jZHJvbV9kb3BzOwoJZGV2aW5mby0+bWFzayA9IDA7CglkZXZpbmZvLT5zcGVlZCA9IENEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+Y3VycmVudF9zcGVlZDsKCWRldmluZm8tPmNhcGFjaXR5ID0gbnNsb3RzOwoJZGV2aW5mby0+aGFuZGxlID0gZHJpdmU7CglzdHJjcHkoZGV2aW5mby0+bmFtZSwgZHJpdmUtPm5hbWUpOwoJCgkvKiBzZXQgY2FwYWJpbGl0eSBtYXNrIHRvIG1hdGNoIHRoZSBwcm9iZS4gKi8KCWlmICghQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2RfcikKCQlkZXZpbmZvLT5tYXNrIHw9IENEQ19DRF9SOwoJaWYgKCFDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5jZF9ydykKCQlkZXZpbmZvLT5tYXNrIHw9IENEQ19DRF9SVzsKCWlmICghQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkKQoJCWRldmluZm8tPm1hc2sgfD0gQ0RDX0RWRDsKCWlmICghQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkX3IpCgkJZGV2aW5mby0+bWFzayB8PSBDRENfRFZEX1I7CglpZiAoIUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZF9yYW0pCgkJZGV2aW5mby0+bWFzayB8PSBDRENfRFZEX1JBTTsKCWlmICghQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+aXNfY2hhbmdlcikKCQlkZXZpbmZvLT5tYXNrIHw9IENEQ19TRUxFQ1RfRElTQzsKCWlmICghQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+YXVkaW9fcGxheSkKCQlkZXZpbmZvLT5tYXNrIHw9IENEQ19QTEFZX0FVRElPOwoJaWYgKCFDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5jbG9zZV90cmF5KQoJCWRldmluZm8tPm1hc2sgfD0gQ0RDX0NMT1NFX1RSQVk7CglpZiAoIUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPm1vX2RyaXZlKQoJCWRldmluZm8tPm1hc2sgfD0gQ0RDX01PX0RSSVZFOwoKCWRldmluZm8tPmRpc2sgPSBpbmZvLT5kaXNrOwoJcmV0dXJuIHJlZ2lzdGVyX2Nkcm9tKGRldmluZm8pOwp9CgpzdGF0aWMKaW50IGlkZV9jZHJvbV9wcm9iZV9jYXBhYmlsaXRpZXMgKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSA9ICZpbmZvLT5kZXZpbmZvOwoJc3RydWN0IGF0YXBpX2NhcGFiaWxpdGllc19wYWdlIGNhcDsKCWludCBuc2xvdHMgPSAxOwoKCWlmIChkcml2ZS0+bWVkaWEgPT0gaWRlX29wdGljYWwpIHsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5tb19kcml2ZSA9IDE7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+cmFtID0gMTsKCQlwcmludGsoS0VSTl9FUlIgIiVzOiBBVEFQSSBtYWduZXRvLW9wdGljYWwgZHJpdmVcbiIsIGRyaXZlLT5uYW1lKTsKCQlyZXR1cm4gbnNsb3RzOwoJfQoKCWlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5uZWMyNjAgfHwKCSAgICAhc3RyY21wKGRyaXZlLT5pZC0+bW9kZWwsIlNUSU5HUkFZIDg0MjIgSURFIDhYIENELVJPTSA3LTI3LTk1IikpIHsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5ub19lamVjdCA9IDA7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+YXVkaW9fcGxheSA9IDE7CgkJcmV0dXJuIG5zbG90czsKCX0KCgkvKgoJICogd2UgaGF2ZSB0byBjaGVhdCBhIGxpdHRsZSBoZXJlLiB0aGUgcGFja2V0IHdpbGwgZXZlbnR1YWxseQoJICogYmUgcXVldWVkIHdpdGggaWRlX2Nkcm9tX3BhY2tldCgpLCB3aGljaCBleHRyYWN0cyB0aGUKCSAqIGRyaXZlIGZyb20gY2RpLT5oYW5kbGUuIFNpbmNlIHRoaXMgZGV2aWNlIGhhc24ndCBiZWVuCgkgKiByZWdpc3RlcmVkIHdpdGggdGhlIFVuaWZvcm0gbGF5ZXIgeWV0LCBpdCBjYW4ndCBkbyB0aGlzLgoJICogU2FtZSBnb2VzIGZvciBjZGktPm9wcy4KCSAqLwoJY2RpLT5oYW5kbGUgPSBkcml2ZTsKCWNkaS0+b3BzID0gJmlkZV9jZHJvbV9kb3BzOwoKCWlmIChpZGVfY2Ryb21fZ2V0X2NhcGFiaWxpdGllcyhkcml2ZSwgJmNhcCkpCgkJcmV0dXJuIDA7CgoJaWYgKGNhcC5sb2NrID09IDApCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bm9fZG9vcmxvY2sgPSAxOwoJaWYgKGNhcC5lamVjdCkKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5ub19lamVjdCA9IDA7CglpZiAoY2FwLmNkX3Jfd3JpdGUpCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2RfciA9IDE7CglpZiAoY2FwLmNkX3J3X3dyaXRlKSB7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2RfcncgPSAxOwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnJhbSA9IDE7Cgl9CglpZiAoY2FwLnRlc3Rfd3JpdGUpCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dGVzdF93cml0ZSA9IDE7CglpZiAoY2FwLmR2ZF9yYW1fcmVhZCB8fCBjYXAuZHZkX3JfcmVhZCB8fCBjYXAuZHZkX3JvbSkKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5kdmQgPSAxOwoJaWYgKGNhcC5kdmRfcmFtX3dyaXRlKSB7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkX3JhbSA9IDE7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+cmFtID0gMTsKCX0KCWlmIChjYXAuZHZkX3Jfd3JpdGUpCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkX3IgPSAxOwoJaWYgKGNhcC5hdWRpb19wbGF5KQoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmF1ZGlvX3BsYXkgPSAxOwoJaWYgKGNhcC5tZWNodHlwZSA9PSBtZWNodHlwZV9jYWRkeSB8fCBjYXAubWVjaHR5cGUgPT0gbWVjaHR5cGVfcG9wdXApCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2xvc2VfdHJheSA9IDA7CgoJLyogU29tZSBkcml2ZXMgdXNlZCBieSBBcHBsZSBkb24ndCBhZHZlcnRpc2UgYXVkaW8gcGxheQoJICogYnV0IHRoZXkgZG8gc3VwcG9ydCByZWFkaW5nIFRPQyAmIGF1ZGlvIGRhdGFzCgkgKi8KCWlmIChzdHJjbXAoZHJpdmUtPmlkLT5tb2RlbCwgIk1BVFNISVRBRFZELVJPTSBTUi04MTg3IikgPT0gMCB8fAoJICAgIHN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiTUFUU0hJVEFEVkQtUk9NIFNSLTgxODYiKSA9PSAwIHx8CgkgICAgc3RyY21wKGRyaXZlLT5pZC0+bW9kZWwsICJNQVRTSElUQURWRC1ST00gU1ItODE3NiIpID09IDAgfHwKCSAgICBzdHJjbXAoZHJpdmUtPmlkLT5tb2RlbCwgIk1BVFNISVRBRFZELVJPTSBTUi04MTc0IikgPT0gMCkKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5hdWRpb19wbGF5ID0gMTsKCiNpZiAhIFNUQU5EQVJEX0FUQVBJCglpZiAoY2RpLT5zYW55b19zbG90ID4gMCkgewoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmlzX2NoYW5nZXIgPSAxOwoJCW5zbG90cyA9IDM7Cgl9CgoJZWxzZQojZW5kaWYgLyogbm90IFNUQU5EQVJEX0FUQVBJICovCglpZiAoY2FwLm1lY2h0eXBlID09IG1lY2h0eXBlX2luZGl2aWR1YWxfY2hhbmdlciB8fAoJICAgIGNhcC5tZWNodHlwZSA9PSBtZWNodHlwZV9jYXJ0cmlkZ2VfY2hhbmdlcikgewoJCWlmICgobnNsb3RzID0gY2Ryb21fbnVtYmVyX29mX3Nsb3RzKGNkaSkpID4gMSkgewoJCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5pc19jaGFuZ2VyID0gMTsKCQkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+c3VwcF9kaXNjX3ByZXNlbnQgPSAxOwoJCX0KCX0KCglpZGVfY2Ryb21fdXBkYXRlX3NwZWVkKGRyaXZlLCAmY2FwKTsKCS8qIGRvbid0IHByaW50IHNwZWVkIGlmIHRoZSBkcml2ZSByZXBvcnRlZCAwLgoJICovCglwcmludGsoS0VSTl9JTkZPICIlczogQVRBUEkiLCBkcml2ZS0+bmFtZSk7CglpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bWF4X3NwZWVkKQoJCXByaW50aygiICVkWCIsIENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPm1heF9zcGVlZCk7CglwcmludGsoIiAlcyIsIENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZCA/ICJEVkQtUk9NIiA6ICJDRC1ST00iKTsKCglpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkX3J8Q0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkX3JhbSkKICAgICAgICAJcHJpbnRrKCIgRFZEJXMlcyIsIAogICAgICAgIAkoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkX3IpPyAiLVIiIDogIiIsIAogICAgICAgIAkoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkX3JhbSk/ICItUkFNIiA6ICIiKTsKCiAgICAgICAgaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNkX3J8Q0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2RfcncpIAogICAgICAgIAlwcmludGsoIiBDRCVzJXMiLCAKICAgICAgICAJKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNkX3IpPyAiLVIiIDogIiIsIAogICAgICAgIAkoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2RfcncpPyAiL1JXIiA6ICIiKTsKCiAgICAgICAgaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmlzX2NoYW5nZXIpIAogICAgICAgIAlwcmludGsoIiBjaGFuZ2VyIHcvJWQgc2xvdHMiLCBuc2xvdHMpOwogICAgICAgIGVsc2UgCQogICAgICAgIAlwcmludGsoIiBkcml2ZSIpOwoKCXByaW50aygiLCAlZGtCIENhY2hlIiwgYmUxNl90b19jcHUoY2FwLmJ1ZmZlcl9zaXplKSk7CgoJaWYgKGRyaXZlLT51c2luZ19kbWEpCgkJaWRlX2RtYV92ZXJib3NlKGRyaXZlKTsKCglwcmludGsoIlxuIik7CgoJcmV0dXJuIG5zbG90czsKfQoKc3RhdGljIHZvaWQgaWRlX2Nkcm9tX2FkZF9zZXR0aW5ncyhpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCWlkZV9hZGRfc2V0dGluZyhkcml2ZSwJImRzY19vdmVybGFwIiwJCVNFVFRJTkdfUlcsIC0xLCAtMSwgVFlQRV9CWVRFLCAwLCAxLCAxLAkxLCAmZHJpdmUtPmRzY19vdmVybGFwLCBOVUxMKTsKfQoKLyoKICogc3RhbmRhcmQgcHJlcF9ycV9mbiB0aGF0IGJ1aWxkcyAxMCBieXRlIGNtZHMKICovCnN0YXRpYyBpbnQgaWRlX2Nkcm9tX3ByZXBfZnMocmVxdWVzdF9xdWV1ZV90ICpxLCBzdHJ1Y3QgcmVxdWVzdCAqcnEpCnsKCWludCBoYXJkX3NlY3QgPSBxdWV1ZV9oYXJkc2VjdF9zaXplKHEpOwoJbG9uZyBibG9jayA9IChsb25nKXJxLT5oYXJkX3NlY3RvciAvIChoYXJkX3NlY3QgPj4gOSk7Cgl1bnNpZ25lZCBsb25nIGJsb2NrcyA9IHJxLT5oYXJkX25yX3NlY3RvcnMgLyAoaGFyZF9zZWN0ID4+IDkpOwoKCW1lbXNldChycS0+Y21kLCAwLCBzaXplb2YocnEtPmNtZCkpOwoKCWlmIChycV9kYXRhX2RpcihycSkgPT0gUkVBRCkKCQlycS0+Y21kWzBdID0gR1BDTURfUkVBRF8xMDsKCWVsc2UKCQlycS0+Y21kWzBdID0gR1BDTURfV1JJVEVfMTA7CgoJLyoKCSAqIGZpbGwgaW4gbGJhCgkgKi8KCXJxLT5jbWRbMl0gPSAoYmxvY2sgPj4gMjQpICYgMHhmZjsKCXJxLT5jbWRbM10gPSAoYmxvY2sgPj4gMTYpICYgMHhmZjsKCXJxLT5jbWRbNF0gPSAoYmxvY2sgPj4gIDgpICYgMHhmZjsKCXJxLT5jbWRbNV0gPSBibG9jayAmIDB4ZmY7CgoJLyoKCSAqIGFuZCB0cmFuc2ZlciBsZW5ndGgKCSAqLwoJcnEtPmNtZFs3XSA9IChibG9ja3MgPj4gOCkgJiAweGZmOwoJcnEtPmNtZFs4XSA9IGJsb2NrcyAmIDB4ZmY7CglycS0+Y21kX2xlbiA9IDEwOwoJcmV0dXJuIEJMS1BSRVBfT0s7Cn0KCi8qCiAqIE1vc3Qgb2YgdGhlIFNDU0kgY29tbWFuZHMgYXJlIHN1cHBvcnRlZCBkaXJlY3RseSBieSBBVEFQSSBkZXZpY2VzLgogKiBUaGlzIHRyYW5zZm9ybSBoYW5kbGVzIHRoZSBmZXcgZXhjZXB0aW9ucy4KICovCnN0YXRpYyBpbnQgaWRlX2Nkcm9tX3ByZXBfcGMoc3RydWN0IHJlcXVlc3QgKnJxKQp7Cgl1OCAqYyA9IHJxLT5jbWQ7CgoJLyoKCSAqIFRyYW5zZm9ybSA2LWJ5dGUgcmVhZC93cml0ZSBjb21tYW5kcyB0byB0aGUgMTAtYnl0ZSB2ZXJzaW9uCgkgKi8KCWlmIChjWzBdID09IFJFQURfNiB8fCBjWzBdID09IFdSSVRFXzYpIHsKCQljWzhdID0gY1s0XTsKCQljWzVdID0gY1szXTsKCQljWzRdID0gY1syXTsKCQljWzNdID0gY1sxXSAmIDB4MWY7CgkJY1syXSA9IDA7CgkJY1sxXSAmPSAweGUwOwoJCWNbMF0gKz0gKFJFQURfMTAgLSBSRUFEXzYpOwoJCXJxLT5jbWRfbGVuID0gMTA7CgkJcmV0dXJuIEJMS1BSRVBfT0s7Cgl9CgoJLyoKCSAqIGl0J3Mgc2lsbHkgdG8gcHJldGVuZCB3ZSB1bmRlcnN0YW5kIDYtYnl0ZSBzZW5zZSBjb21tYW5kcywganVzdAoJICogcmVqZWN0IHdpdGggSUxMRUdBTF9SRVFVRVNUIGFuZCB0aGUgY2FsbGVyIHNob3VsZCB0YWtlIHRoZQoJICogYXBwcm9wcmlhdGUgYWN0aW9uCgkgKi8KCWlmIChjWzBdID09IE1PREVfU0VOU0UgfHwgY1swXSA9PSBNT0RFX1NFTEVDVCkgewoJCXJxLT5lcnJvcnMgPSBJTExFR0FMX1JFUVVFU1Q7CgkJcmV0dXJuIEJMS1BSRVBfS0lMTDsKCX0KCQoJcmV0dXJuIEJMS1BSRVBfT0s7Cn0KCnN0YXRpYyBpbnQgaWRlX2Nkcm9tX3ByZXBfZm4ocmVxdWVzdF9xdWV1ZV90ICpxLCBzdHJ1Y3QgcmVxdWVzdCAqcnEpCnsKCWlmIChycS0+ZmxhZ3MgJiBSRVFfQ01EKQoJCXJldHVybiBpZGVfY2Ryb21fcHJlcF9mcyhxLCBycSk7CgllbHNlIGlmIChycS0+ZmxhZ3MgJiBSRVFfQkxPQ0tfUEMpCgkJcmV0dXJuIGlkZV9jZHJvbV9wcmVwX3BjKHJxKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljCmludCBpZGVfY2Ryb21fc2V0dXAgKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSA9ICZpbmZvLT5kZXZpbmZvOwoJaW50IG5zbG90czsKCglibGtfcXVldWVfcHJlcF9ycShkcml2ZS0+cXVldWUsIGlkZV9jZHJvbV9wcmVwX2ZuKTsKCWJsa19xdWV1ZV9kbWFfYWxpZ25tZW50KGRyaXZlLT5xdWV1ZSwgMzEpOwoJZHJpdmUtPnF1ZXVlLT51bnBsdWdfZGVsYXkgPSAoMSAqIEhaKSAvIDEwMDA7CglpZiAoIWRyaXZlLT5xdWV1ZS0+dW5wbHVnX2RlbGF5KQoJCWRyaXZlLT5xdWV1ZS0+dW5wbHVnX2RlbGF5ID0gMTsKCglkcml2ZS0+c3BlY2lhbC5hbGwJPSAwOwoKCUNEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+bWVkaWFfY2hhbmdlZCA9IDE7CglDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPnRvY192YWxpZCAgICAgPSAwOwoJQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT5kb29yX2xvY2tlZCAgID0gMDsKCiNpZiBOT19ET09SX0xPQ0tJTkcKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPm5vX2Rvb3Jsb2NrID0gMTsKI2Vsc2UKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPm5vX2Rvb3Jsb2NrID0gMDsKI2VuZGlmCgoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHJxX2ludGVycnVwdCA9ICgoZHJpdmUtPmlkLT5jb25maWcgJiAweDAwNjApID09IDB4MjApOwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+aXNfY2hhbmdlciA9IDA7CglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5jZF9yID0gMDsKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNkX3J3ID0gMDsKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnRlc3Rfd3JpdGUgPSAwOwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkID0gMDsKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZF9yID0gMDsKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZF9yYW0gPSAwOwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bm9fZWplY3QgPSAxOwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+c3VwcF9kaXNjX3ByZXNlbnQgPSAwOwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+YXVkaW9fcGxheSA9IDA7CglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5jbG9zZV90cmF5ID0gMTsKCQoJLyogbGltaXQgdHJhbnNmZXIgc2l6ZSBwZXIgaW50ZXJydXB0LiAqLwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bGltaXRfbmZyYW1lcyA9IDA7CgkvKiBhIHRlc3RhbWVudCB0byB0aGUgbmljZSBxdWFsaXR5IG9mIFNhbXN1bmcgZHJpdmVzLi4uICovCglpZiAoIXN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiU0FNU1VORyBDRC1ST00gU0NSLTI0MzAiKSkKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5saW1pdF9uZnJhbWVzID0gMTsKCWVsc2UgaWYgKCFzdHJjbXAoZHJpdmUtPmlkLT5tb2RlbCwgIlNBTVNVTkcgQ0QtUk9NIFNDUi0yNDMyIikpCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bGltaXRfbmZyYW1lcyA9IDE7CgkvKiB0aGUgMzIzMSBtb2RlbCBkb2VzIG5vdCBzdXBwb3J0IHRoZSBTRVRfQ0RfU1BFRUQgY29tbWFuZCAqLwoJZWxzZSBpZiAoIXN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiU0FNU1VORyBDRC1ST00gU0NSLTMyMzEiKSkKCQljZGktPm1hc2sgfD0gQ0RDX1NFTEVDVF9TUEVFRDsKCiNpZiAhIFNUQU5EQVJEX0FUQVBJCgkvKiBieSBkZWZhdWx0IFNhbnlvIDMgQ0QgY2hhbmdlciBzdXBwb3J0IGlzIHR1cm5lZCBvZmYgYW5kCiAgICAgICAgICAgQVRBUEkgUmV2IDIuMisgc3RhbmRhcmQgc3VwcG9ydCBmb3IgQ0QgY2hhbmdlcnMgaXMgdXNlZCAqLwoJY2RpLT5zYW55b19zbG90ID0gMDsKCglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5uZWMyNjAgPSAwOwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dG9jdHJhY2tzX2FzX2JjZCA9IDA7CglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT50b2NhZGRyX2FzX2JjZCA9IDA7CglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5wbGF5bXNmX2FzX2JjZCA9IDA7CglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5zdWJjaGFuX2FzX2JjZCA9IDA7CgoJaWYgKHN0cmNtcCAoZHJpdmUtPmlkLT5tb2RlbCwgIlYwMDNTMERTIikgPT0gMCAmJgoJICAgIGRyaXZlLT5pZC0+ZndfcmV2WzRdID09ICcxJyAmJgoJICAgIGRyaXZlLT5pZC0+ZndfcmV2WzZdIDw9ICcyJykgewoJCS8qIFZlcnRvcyAzMDAuCgkJICAgU29tZSB2ZXJzaW9ucyBvZiB0aGlzIGRyaXZlIGxpa2UgdG8gdGFsayBCQ0QuICovCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dG9jdHJhY2tzX2FzX2JjZCA9IDE7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dG9jYWRkcl9hc19iY2QgPSAxOwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnBsYXltc2ZfYXNfYmNkID0gMTsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5zdWJjaGFuX2FzX2JjZCA9IDE7Cgl9CgoJZWxzZSBpZiAoc3RyY21wIChkcml2ZS0+aWQtPm1vZGVsLCAiVjAwNkUwRFMiKSA9PSAwICYmCgkgICAgZHJpdmUtPmlkLT5md19yZXZbNF0gPT0gJzEnICYmCgkgICAgZHJpdmUtPmlkLT5md19yZXZbNl0gPD0gJzInKSB7CgkJLyogVmVydG9zIDYwMCBFU0QuICovCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dG9jdHJhY2tzX2FzX2JjZCA9IDE7Cgl9CgllbHNlIGlmIChzdHJjbXAoZHJpdmUtPmlkLT5tb2RlbCwgIk5FQyBDRC1ST00gRFJJVkU6MjYwIikgPT0gMCAmJgoJCSBzdHJuY21wKGRyaXZlLT5pZC0+ZndfcmV2LCAiMS4wMSIsIDQpID09IDApIHsgLyogRklYTUUgKi8KCQkvKiBPbGQgTkVDMjYwIChub3QgUikuCgkJICAgVGhpcyBkcml2ZSB3YXMgcmVsZWFzZWQgYmVmb3JlIHRoZSAxLjIgdmVyc2lvbgoJCSAgIG9mIHRoZSBzcGVjLiAqLwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnRvY2FkZHJfYXNfYmNkID0gMTsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5wbGF5bXNmX2FzX2JjZCA9IDE7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+c3ViY2hhbl9hc19iY2QgPSAxOwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPm5lYzI2MCAgICAgICAgID0gMTsKCX0KCWVsc2UgaWYgKHN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiV0VBUk5FUyBDREQtMTIwIikgPT0gMCAmJgoJCSBzdHJuY21wKGRyaXZlLT5pZC0+ZndfcmV2LCAiQTEuMSIsIDQpID09IDApIHsgLyogRklYTUUgKi8KCQkvKiBXZWFybmVzICovCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+cGxheW1zZl9hc19iY2QgPSAxOwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnN1YmNoYW5fYXNfYmNkID0gMTsKCX0KICAgICAgICAvKiBTYW55byAzIENEIGNoYW5nZXIgdXNlcyBhIG5vbi1zdGFuZGFyZCBjb21tYW5kCiAgICAgICAgICAgZm9yIENEIGNoYW5naW5nICovCiAgICAgICAgZWxzZSBpZiAoKHN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiQ0QtUk9NIENEUi1DMyBHIikgPT0gMCkgfHwKICAgICAgICAgICAgICAgICAoc3RyY21wKGRyaXZlLT5pZC0+bW9kZWwsICJDRC1ST00gQ0RSLUMzRyIpID09IDApIHx8CiAgICAgICAgICAgICAgICAgKHN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiQ0QtUk9NIENEUl9DMzYiKSA9PSAwKSkgewogICAgICAgICAgICAgICAgIC8qIHVzZXMgQ0QgaW4gc2xvdCAwIHdoZW4gdmFsdWUgaXMgc2V0IHRvIDMgKi8KICAgICAgICAgICAgICAgICBjZGktPnNhbnlvX3Nsb3QgPSAzOwogICAgICAgIH0KI2VuZGlmIC8qIG5vdCBTVEFOREFSRF9BVEFQSSAqLwoKCWluZm8tPnRvYwkJPSBOVUxMOwoJaW5mby0+YnVmZmVyCQk9IE5VTEw7CglpbmZvLT5zZWN0b3JfYnVmZmVyZWQJPSAwOwoJaW5mby0+bnNlY3RvcnNfYnVmZmVyZWQJPSAwOwoJaW5mby0+Y2hhbmdlcl9pbmZvICAgICAgPSBOVUxMOwoJaW5mby0+bGFzdF9ibG9jawk9IDA7CglpbmZvLT5zdGFydF9zZWVrCT0gMDsKCgluc2xvdHMgPSBpZGVfY2Ryb21fcHJvYmVfY2FwYWJpbGl0aWVzIChkcml2ZSk7CgoJLyoKCSAqIHNldCBjb3JyZWN0IGJsb2NrIHNpemUKCSAqLwoJYmxrX3F1ZXVlX2hhcmRzZWN0X3NpemUoZHJpdmUtPnF1ZXVlLCBDRF9GUkFNRVNJWkUpOwoKCWlmIChkcml2ZS0+YXV0b3R1bmUgPT0gSURFX1RVTkVfREVGQVVMVCB8fAoJICAgIGRyaXZlLT5hdXRvdHVuZSA9PSBJREVfVFVORV9BVVRPKQoJCWRyaXZlLT5kc2Nfb3ZlcmxhcCA9IChkcml2ZS0+bmV4dCAhPSBkcml2ZSk7CiNpZiAwCglkcml2ZS0+ZHNjX292ZXJsYXAgPSAoSFdJRihkcml2ZSktPm5vX2RzYykgPyAwIDogMTsKCWlmIChIV0lGKGRyaXZlKS0+bm9fZHNjKSB7CgkJcHJpbnRrKEtFUk5fSU5GTyAiaWRlLWNkOiAlczogZGlzYWJsaW5nIERTQyBvdmVybGFwXG4iLAoJCQlkcml2ZS0+bmFtZSk7CgkJZHJpdmUtPmRzY19vdmVybGFwID0gMDsKCX0KI2VuZGlmCgoJaWYgKGlkZV9jZHJvbV9yZWdpc3Rlcihkcml2ZSwgbnNsb3RzKSkgewoJCXByaW50ayAoS0VSTl9FUlIgIiVzOiBpZGVfY2Ryb21fc2V0dXAgZmFpbGVkIHRvIHJlZ2lzdGVyIGRldmljZSB3aXRoIHRoZSBjZHJvbSBkcml2ZXIuXG4iLCBkcml2ZS0+bmFtZSk7CgkJaW5mby0+ZGV2aW5mby5oYW5kbGUgPSBOVUxMOwoJCXJldHVybiAxOwoJfQoJaWRlX2Nkcm9tX2FkZF9zZXR0aW5ncyhkcml2ZSk7CglyZXR1cm4gMDsKfQoKI2lmZGVmIENPTkZJR19QUk9DX0ZTCnN0YXRpYwpzZWN0b3JfdCBpZGVfY2Ryb21fY2FwYWNpdHkgKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJdW5zaWduZWQgbG9uZyBjYXBhY2l0eSwgc2VjdG9yc19wZXJfZnJhbWU7CgoJaWYgKGNkcm9tX3JlYWRfY2FwYWNpdHkoZHJpdmUsICZjYXBhY2l0eSwgJnNlY3RvcnNfcGVyX2ZyYW1lLCBOVUxMKSkKCQlyZXR1cm4gMDsKCglyZXR1cm4gY2FwYWNpdHkgKiBzZWN0b3JzX3Blcl9mcmFtZTsKfQojZW5kaWYKCnN0YXRpYyBpbnQgaWRlX2NkX3JlbW92ZShzdHJ1Y3QgZGV2aWNlICpkZXYpCnsKCWlkZV9kcml2ZV90ICpkcml2ZSA9IHRvX2lkZV9kZXZpY2UoZGV2KTsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoKCWlkZV91bnJlZ2lzdGVyX3N1YmRyaXZlcihkcml2ZSwgaW5mby0+ZHJpdmVyKTsKCglkZWxfZ2VuZGlzayhpbmZvLT5kaXNrKTsKCglpZGVfY2RfcHV0KGluZm8pOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBpZGVfY2RfcmVsZWFzZShzdHJ1Y3Qga3JlZiAqa3JlZikKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSB0b19pZGVfY2Qoa3JlZik7CglzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmRldmluZm8gPSAmaW5mby0+ZGV2aW5mbzsKCWlkZV9kcml2ZV90ICpkcml2ZSA9IGluZm8tPmRyaXZlOwoJc3RydWN0IGdlbmRpc2sgKmcgPSBpbmZvLT5kaXNrOwoKCWlmIChpbmZvLT5idWZmZXIgIT0gTlVMTCkKCQlrZnJlZShpbmZvLT5idWZmZXIpOwoJaWYgKGluZm8tPnRvYyAhPSBOVUxMKQoJCWtmcmVlKGluZm8tPnRvYyk7CglpZiAoaW5mby0+Y2hhbmdlcl9pbmZvICE9IE5VTEwpCgkJa2ZyZWUoaW5mby0+Y2hhbmdlcl9pbmZvKTsKCWlmIChkZXZpbmZvLT5oYW5kbGUgPT0gZHJpdmUgJiYgdW5yZWdpc3Rlcl9jZHJvbShkZXZpbmZvKSkKCQlwcmludGsoS0VSTl9FUlIgIiVzOiAlcyBmYWlsZWQgdG8gdW5yZWdpc3RlciBkZXZpY2UgZnJvbSB0aGUgY2Ryb20gIgoJCQkJImRyaXZlci5cbiIsIF9fRlVOQ1RJT05fXywgZHJpdmUtPm5hbWUpOwoJZHJpdmUtPmRzY19vdmVybGFwID0gMDsKCWRyaXZlLT5kcml2ZXJfZGF0YSA9IE5VTEw7CglibGtfcXVldWVfcHJlcF9ycShkcml2ZS0+cXVldWUsIE5VTEwpOwoJZy0+cHJpdmF0ZV9kYXRhID0gTlVMTDsKCXB1dF9kaXNrKGcpOwoJa2ZyZWUoaW5mbyk7Cn0KCnN0YXRpYyBpbnQgaWRlX2NkX3Byb2JlKHN0cnVjdCBkZXZpY2UgKik7CgojaWZkZWYgQ09ORklHX1BST0NfRlMKc3RhdGljIGludCBwcm9jX2lkZWNkX3JlYWRfY2FwYWNpdHkKCShjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZiwgaW50IGNvdW50LCBpbnQgKmVvZiwgdm9pZCAqZGF0YSkKewoJaWRlX2RyaXZlX3QgKmRyaXZlID0gZGF0YTsKCWludCBsZW47CgoJbGVuID0gc3ByaW50ZihwYWdlLCIlbGx1XG4iLCAobG9uZyBsb25nKWlkZV9jZHJvbV9jYXBhY2l0eShkcml2ZSkpOwoJUFJPQ19JREVfUkVBRF9SRVRVUk4ocGFnZSxzdGFydCxvZmYsY291bnQsZW9mLGxlbik7Cn0KCnN0YXRpYyBpZGVfcHJvY19lbnRyeV90IGlkZWNkX3Byb2NbXSA9IHsKCXsgImNhcGFjaXR5IiwgU19JRlJFR3xTX0lSVUdPLCBwcm9jX2lkZWNkX3JlYWRfY2FwYWNpdHksIE5VTEwgfSwKCXsgTlVMTCwgMCwgTlVMTCwgTlVMTCB9Cn07CiNlbHNlCiMgZGVmaW5lIGlkZWNkX3Byb2MJTlVMTAojZW5kaWYKCnN0YXRpYyBpZGVfZHJpdmVyX3QgaWRlX2Nkcm9tX2RyaXZlciA9IHsKCS5vd25lcgkJCT0gVEhJU19NT0RVTEUsCgkuZ2VuX2RyaXZlciA9IHsKCQkubmFtZQkJPSAiaWRlLWNkcm9tIiwKCQkuYnVzCQk9ICZpZGVfYnVzX3R5cGUsCgkJLnByb2JlCQk9IGlkZV9jZF9wcm9iZSwKCQkucmVtb3ZlCQk9IGlkZV9jZF9yZW1vdmUsCgl9LAoJLnZlcnNpb24JCT0gSURFQ0RfVkVSU0lPTiwKCS5tZWRpYQkJCT0gaWRlX2Nkcm9tLAoJLnN1cHBvcnRzX2RzY19vdmVybGFwCT0gMSwKCS5kb19yZXF1ZXN0CQk9IGlkZV9kb19yd19jZHJvbSwKCS5lbmRfcmVxdWVzdAkJPSBpZGVfZW5kX3JlcXVlc3QsCgkuZXJyb3IJCQk9IF9faWRlX2Vycm9yLAoJLmFib3J0CQkJPSBfX2lkZV9hYm9ydCwKCS5wcm9jCQkJPSBpZGVjZF9wcm9jLAp9OwoKc3RhdGljIGludCBpZGVjZF9vcGVuKHN0cnVjdCBpbm9kZSAqIGlub2RlLCBzdHJ1Y3QgZmlsZSAqIGZpbGUpCnsKCXN0cnVjdCBnZW5kaXNrICpkaXNrID0gaW5vZGUtPmlfYmRldi0+YmRfZGlzazsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvOwoJaWRlX2RyaXZlX3QgKmRyaXZlOwoJaW50IHJjID0gLUVOT01FTTsKCglpZiAoIShpbmZvID0gaWRlX2NkX2dldChkaXNrKSkpCgkJcmV0dXJuIC1FTlhJTzsKCglkcml2ZSA9IGluZm8tPmRyaXZlOwoKCWRyaXZlLT51c2FnZSsrOwoKCWlmICghaW5mby0+YnVmZmVyKQoJCWluZm8tPmJ1ZmZlciA9IGttYWxsb2MoU0VDVE9SX0JVRkZFUl9TSVpFLAoJCQkJCUdGUF9LRVJORUx8X19HRlBfUkVQRUFUKTsKICAgICAgICBpZiAoIWluZm8tPmJ1ZmZlciB8fCAocmMgPSBjZHJvbV9vcGVuKCZpbmZvLT5kZXZpbmZvLCBpbm9kZSwgZmlsZSkpKQoJCWRyaXZlLT51c2FnZS0tOwoKCWlmIChyYyA8IDApCgkJaWRlX2NkX3B1dChpbmZvKTsKCglyZXR1cm4gcmM7Cn0KCnN0YXRpYyBpbnQgaWRlY2RfcmVsZWFzZShzdHJ1Y3QgaW5vZGUgKiBpbm9kZSwgc3RydWN0IGZpbGUgKiBmaWxlKQp7CglzdHJ1Y3QgZ2VuZGlzayAqZGlzayA9IGlub2RlLT5pX2JkZXYtPmJkX2Rpc2s7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGlkZV9jZF9nKGRpc2spOwoJaWRlX2RyaXZlX3QgKmRyaXZlID0gaW5mby0+ZHJpdmU7CgoJY2Ryb21fcmVsZWFzZSAoJmluZm8tPmRldmluZm8sIGZpbGUpOwoJZHJpdmUtPnVzYWdlLS07CgoJaWRlX2NkX3B1dChpbmZvKTsKCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBpZGVjZF9pb2N0bCAoc3RydWN0IGlub2RlICppbm9kZSwgc3RydWN0IGZpbGUgKmZpbGUsCgkJCXVuc2lnbmVkIGludCBjbWQsIHVuc2lnbmVkIGxvbmcgYXJnKQp7CglzdHJ1Y3QgYmxvY2tfZGV2aWNlICpiZGV2ID0gaW5vZGUtPmlfYmRldjsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gaWRlX2NkX2coYmRldi0+YmRfZGlzayk7CglpbnQgZXJyOwoKCWVyciAgPSBnZW5lcmljX2lkZV9pb2N0bChpbmZvLT5kcml2ZSwgZmlsZSwgYmRldiwgY21kLCBhcmcpOwoJaWYgKGVyciA9PSAtRUlOVkFMKQoJCWVyciA9IGNkcm9tX2lvY3RsKGZpbGUsICZpbmZvLT5kZXZpbmZvLCBpbm9kZSwgY21kLCBhcmcpOwoKCXJldHVybiBlcnI7Cn0KCnN0YXRpYyBpbnQgaWRlY2RfbWVkaWFfY2hhbmdlZChzdHJ1Y3QgZ2VuZGlzayAqZGlzaykKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBpZGVfY2RfZyhkaXNrKTsKCXJldHVybiBjZHJvbV9tZWRpYV9jaGFuZ2VkKCZpbmZvLT5kZXZpbmZvKTsKfQoKc3RhdGljIGludCBpZGVjZF9yZXZhbGlkYXRlX2Rpc2soc3RydWN0IGdlbmRpc2sgKmRpc2spCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gaWRlX2NkX2coZGlzayk7CglzdHJ1Y3QgcmVxdWVzdF9zZW5zZSBzZW5zZTsKCWNkcm9tX3JlYWRfdG9jKGluZm8tPmRyaXZlLCAmc2Vuc2UpOwoJcmV0dXJuICAwOwp9CgpzdGF0aWMgc3RydWN0IGJsb2NrX2RldmljZV9vcGVyYXRpb25zIGlkZWNkX29wcyA9IHsKCS5vd25lcgkJPSBUSElTX01PRFVMRSwKCS5vcGVuCQk9IGlkZWNkX29wZW4sCgkucmVsZWFzZQk9IGlkZWNkX3JlbGVhc2UsCgkuaW9jdGwJCT0gaWRlY2RfaW9jdGwsCgkubWVkaWFfY2hhbmdlZAk9IGlkZWNkX21lZGlhX2NoYW5nZWQsCgkucmV2YWxpZGF0ZV9kaXNrPSBpZGVjZF9yZXZhbGlkYXRlX2Rpc2sKfTsKCi8qIG9wdGlvbnMgKi8Kc3RhdGljIGNoYXIgKmlnbm9yZSA9IE5VTEw7Cgptb2R1bGVfcGFyYW0oaWdub3JlLCBjaGFycCwgMDQwMCk7Ck1PRFVMRV9ERVNDUklQVElPTigiQVRBUEkgQ0QtUk9NIERyaXZlciIpOwoKc3RhdGljIGludCBpZGVfY2RfcHJvYmUoc3RydWN0IGRldmljZSAqZGV2KQp7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSB0b19pZGVfZGV2aWNlKGRldik7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbzsKCXN0cnVjdCBnZW5kaXNrICpnOwoJc3RydWN0IHJlcXVlc3Rfc2Vuc2Ugc2Vuc2U7CgoJaWYgKCFzdHJzdHIoImlkZS1jZHJvbSIsIGRyaXZlLT5kcml2ZXJfcmVxKSkKCQlnb3RvIGZhaWxlZDsKCWlmICghZHJpdmUtPnByZXNlbnQpCgkJZ290byBmYWlsZWQ7CglpZiAoZHJpdmUtPm1lZGlhICE9IGlkZV9jZHJvbSAmJiBkcml2ZS0+bWVkaWEgIT0gaWRlX29wdGljYWwpCgkJZ290byBmYWlsZWQ7CgkvKiBza2lwIGRyaXZlcyB0aGF0IHdlIHdlcmUgdG9sZCB0byBpZ25vcmUgKi8KCWlmIChpZ25vcmUgIT0gTlVMTCkgewoJCWlmIChzdHJzdHIoaWdub3JlLCBkcml2ZS0+bmFtZSkpIHsKCQkJcHJpbnRrKEtFUk5fSU5GTyAiaWRlLWNkOiBpZ25vcmluZyBkcml2ZSAlc1xuIiwgZHJpdmUtPm5hbWUpOwoJCQlnb3RvIGZhaWxlZDsKCQl9Cgl9CglpZiAoZHJpdmUtPnNjc2kpIHsKCQlwcmludGsoS0VSTl9JTkZPICJpZGUtY2Q6IHBhc3NpbmcgZHJpdmUgJXMgdG8gaWRlLXNjc2kgZW11bGF0aW9uLlxuIiwgZHJpdmUtPm5hbWUpOwoJCWdvdG8gZmFpbGVkOwoJfQoJaW5mbyA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBjZHJvbV9pbmZvKSwgR0ZQX0tFUk5FTCk7CglpZiAoaW5mbyA9PSBOVUxMKSB7CgkJcHJpbnRrKEtFUk5fRVJSICIlczogQ2FuJ3QgYWxsb2NhdGUgYSBjZHJvbSBzdHJ1Y3R1cmVcbiIsIGRyaXZlLT5uYW1lKTsKCQlnb3RvIGZhaWxlZDsKCX0KCglnID0gYWxsb2NfZGlzaygxIDw8IFBBUlROX0JJVFMpOwoJaWYgKCFnKQoJCWdvdG8gb3V0X2ZyZWVfY2Q7CgoJaWRlX2luaXRfZGlzayhnLCBkcml2ZSk7CgoJaWRlX3JlZ2lzdGVyX3N1YmRyaXZlcihkcml2ZSwgJmlkZV9jZHJvbV9kcml2ZXIpOwoKCW1lbXNldChpbmZvLCAwLCBzaXplb2YgKHN0cnVjdCBjZHJvbV9pbmZvKSk7CgoJa3JlZl9pbml0KCZpbmZvLT5rcmVmKTsKCglpbmZvLT5kcml2ZSA9IGRyaXZlOwoJaW5mby0+ZHJpdmVyID0gJmlkZV9jZHJvbV9kcml2ZXI7CglpbmZvLT5kaXNrID0gZzsKCglnLT5wcml2YXRlX2RhdGEgPSAmaW5mby0+ZHJpdmVyOwoKCWRyaXZlLT5kcml2ZXJfZGF0YSA9IGluZm87CgoJZy0+bWlub3JzID0gMTsKCXNucHJpbnRmKGctPmRldmZzX25hbWUsIHNpemVvZihnLT5kZXZmc19uYW1lKSwKCQkJIiVzL2NkIiwgZHJpdmUtPmRldmZzX25hbWUpOwoJZy0+ZHJpdmVyZnNfZGV2ID0gJmRyaXZlLT5nZW5kZXY7CglnLT5mbGFncyA9IEdFTkhEX0ZMX0NEIHwgR0VOSERfRkxfUkVNT1ZBQkxFOwoJaWYgKGlkZV9jZHJvbV9zZXR1cChkcml2ZSkpIHsKCQlzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmRldmluZm8gPSAmaW5mby0+ZGV2aW5mbzsKCQlpZGVfdW5yZWdpc3Rlcl9zdWJkcml2ZXIoZHJpdmUsICZpZGVfY2Ryb21fZHJpdmVyKTsKCQlpZiAoaW5mby0+YnVmZmVyICE9IE5VTEwpCgkJCWtmcmVlKGluZm8tPmJ1ZmZlcik7CgkJaWYgKGluZm8tPnRvYyAhPSBOVUxMKQoJCQlrZnJlZShpbmZvLT50b2MpOwoJCWlmIChpbmZvLT5jaGFuZ2VyX2luZm8gIT0gTlVMTCkKCQkJa2ZyZWUoaW5mby0+Y2hhbmdlcl9pbmZvKTsKCQlpZiAoZGV2aW5mby0+aGFuZGxlID09IGRyaXZlICYmIHVucmVnaXN0ZXJfY2Ryb20oZGV2aW5mbykpCgkJCXByaW50ayAoS0VSTl9FUlIgIiVzOiBpZGVfY2Ryb21fY2xlYW51cCBmYWlsZWQgdG8gdW5yZWdpc3RlciBkZXZpY2UgZnJvbSB0aGUgY2Ryb20gZHJpdmVyLlxuIiwgZHJpdmUtPm5hbWUpOwoJCWtmcmVlKGluZm8pOwoJCWRyaXZlLT5kcml2ZXJfZGF0YSA9IE5VTEw7CgkJZ290byBmYWlsZWQ7Cgl9CgoJY2Ryb21fcmVhZF90b2MoZHJpdmUsICZzZW5zZSk7CglnLT5mb3BzID0gJmlkZWNkX29wczsKCWctPmZsYWdzIHw9IEdFTkhEX0ZMX1JFTU9WQUJMRTsKCWFkZF9kaXNrKGcpOwoJcmV0dXJuIDA7CgpvdXRfZnJlZV9jZDoKCWtmcmVlKGluZm8pOwpmYWlsZWQ6CglyZXR1cm4gLUVOT0RFVjsKfQoKc3RhdGljIHZvaWQgX19leGl0IGlkZV9jZHJvbV9leGl0KHZvaWQpCnsKCWRyaXZlcl91bnJlZ2lzdGVyKCZpZGVfY2Ryb21fZHJpdmVyLmdlbl9kcml2ZXIpOwp9CiAKc3RhdGljIGludCBpZGVfY2Ryb21faW5pdCh2b2lkKQp7CglyZXR1cm4gZHJpdmVyX3JlZ2lzdGVyKCZpZGVfY2Ryb21fZHJpdmVyLmdlbl9kcml2ZXIpOwp9Cgptb2R1bGVfaW5pdChpZGVfY2Ryb21faW5pdCk7Cm1vZHVsZV9leGl0KGlkZV9jZHJvbV9leGl0KTsKTU9EVUxFX0xJQ0VOU0UoIkdQTCIpOwo=