LyoKICogbGludXgvZHJpdmVycy9pZGUvaWRlLWNkLmMKICoKICogQ29weXJpZ2h0IChDKSAxOTk0LCAxOTk1LCAxOTk2ICBzY290dCBzbnlkZXIgIDxzbnlkZXJAZm5hbGQwLmZuYWwuZ292PgogKiBDb3B5cmlnaHQgKEMpIDE5OTYtMTk5OCAgRXJpayBBbmRlcnNlbiA8YW5kZXJzZWVAZGViaWFuLm9yZz4KICogQ29weXJpZ2h0IChDKSAxOTk4LTIwMDAgIEplbnMgQXhib2UgPGF4Ym9lQHN1c2UuZGU+CiAqCiAqIE1heSBiZSBjb3BpZWQgb3IgbW9kaWZpZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMKICogTGljZW5zZS4gIFNlZSBsaW51eC9DT1BZSU5HIGZvciBtb3JlIGluZm9ybWF0aW9uLgogKgogKiBBVEFQSSBDRC1ST00gZHJpdmVyLiAgVG8gYmUgdXNlZCB3aXRoIGlkZS5jLgogKiBTZWUgRG9jdW1lbnRhdGlvbi9jZHJvbS9pZGUtY2QgZm9yIHVzYWdlIGluZm9ybWF0aW9uLgogKgogKiBTdWdnZXN0aW9ucyBhcmUgd2VsY29tZS4gUGF0Y2hlcyB0aGF0IHdvcmsgYXJlIG1vcmUgd2VsY29tZSB0aG91Z2guIDstKQogKiBGb3IgdGhvc2Ugd2lzaGluZyB0byB3b3JrIG9uIHRoaXMgZHJpdmVyLCBwbGVhc2UgYmUgc3VyZSB5b3UgZG93bmxvYWQKICogYW5kIGNvbXBseSB3aXRoIHRoZSBsYXRlc3QgTXQuIEZ1amkgKFNGRjgwOTAgdmVyc2lvbiA0KSBhbmQgQVRBUEkgCiAqIChTRkYtODAyMGkgcmV2IDIuNikgc3RhbmRhcmRzLiBUaGVzZSBkb2N1bWVudHMgY2FuIGJlIG9idGFpbmVkIGJ5IAogKiBhbm9ueW1vdXMgZnRwIGZyb206CiAqIGZ0cDovL2Zpc3Npb24uZHQud2RjLmNvbS9wdWIvc3RhbmRhcmRzL1NGRl9hdGFwaS9zcGVjL1NGRjgwMjAtcjIuNi9QUy84MDIwcjI2LnBzCiAqIGZ0cDovL2Z0cC5hdmMtcGlvbmVlci5jb20vTXRmdWppNC9TcGVjL0Z1amk0cjEwLnBkZgogKgogKiBEcml2ZXMgdGhhdCBkZXZpYXRlIGZyb20gdGhlc2Ugc3RhbmRhcmRzIHdpbGwgYmUgYWNjb21tb2RhdGVkIGFzIG11Y2gKICogYXMgcG9zc2libGUgdmlhIGNvbXBpbGUgdGltZSBvciBjb21tYW5kLWxpbmUgb3B0aW9ucy4gIFNpbmNlIEkgb25seSBoYXZlCiAqIGEgZmV3IGRyaXZlcywgeW91IGdlbmVyYWxseSBuZWVkIHRvIHNlbmQgbWUgcGF0Y2hlcy4uLgogKgogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIFRPIERPIExJU1Q6CiAqIC1NYWtlIGl0IHNvIHRoYXQgUGlvbmVlciBDRCBEUi1BMjRYIGFuZCBmcmllbmRzIGRvbid0IGdldCBzY3Jld2VkIHVwIG9uCiAqICAgYm9vdAogKgogKiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tCiAqIDEuMDAgIE9jdCAzMSwgMTk5NCAtLSBJbml0aWFsIHZlcnNpb24uCiAqIDEuMDEgIE5vdiAgMiwgMTk5NCAtLSBGaXhlZCBwcm9ibGVtIHdpdGggc3RhcnRpbmcgcmVxdWVzdCBpbgogKiAgICAgICAgICAgICAgICAgICAgICAgY2Ryb21fY2hlY2tfc3RhdHVzLgogKiAxLjAzICBOb3YgMjUsIDE5OTQgLS0gbGVhdmluZyB1bm1hc2tfaW50cltdIGFzIGEgdXNlci1zZXR0aW5nIChhcyBmb3IgZGlza3MpCiAqIChmcm9tIG1sb3JkKSAgICAgICAtLSBtaW5vciBjaGFuZ2VzIHRvIGNkcm9tX3NldHVwKCkKICogICAgICAgICAgICAgICAgICAgIC0tIHJlbmFtZWQgaWRlX2Rldl9zIHRvIGlkZV9kcml2ZV90LCBlbmFibGUgaXJxIG9uIGNvbW1hbmQKICogMi4wMCAgTm92IDI3LCAxOTk0IC0tIEdlbmVyYWxpemUgcGFja2V0IGNvbW1hbmQgaW50ZXJmYWNlOwogKiAgICAgICAgICAgICAgICAgICAgICAgYWRkIGF1ZGlvIGlvY3Rscy4KICogMi4wMSAgRGVjICAzLCAxOTk0IC0tIFJld29yayBwYWNrZXQgY29tbWFuZCBpbnRlcmZhY2UgdG8gaGFuZGxlIGRldmljZXMKICogICAgICAgICAgICAgICAgICAgICAgIHdoaWNoIHNlbmQgYW4gaW50ZXJydXB0IHdoZW4gcmVhZHkgZm9yIGEgY29tbWFuZC4KICogMi4wMiAgRGVjIDExLCAxOTk0IC0tIENhY2hlIHRoZSBUT0MgaW4gdGhlIGRyaXZlci4KICogICAgICAgICAgICAgICAgICAgICAgIERvbid0IHVzZSBTQ01EX1BMQVlBVURJT19USTsgaXQncyBub3QgaW5jbHVkZWQKICogICAgICAgICAgICAgICAgICAgICAgIGluIHRoZSBjdXJyZW50IHZlcnNpb24gb2YgQVRBUEkuCiAqICAgICAgICAgICAgICAgICAgICAgICBUcnkgdG8gdXNlIExCQSBpbnN0ZWFkIG9mIHRyYWNrIG9yIE1TRiBhZGRyZXNzaW5nCiAqICAgICAgICAgICAgICAgICAgICAgICB3aGVuIHBvc3NpYmxlLgogKiAgICAgICAgICAgICAgICAgICAgICAgRG9uJ3Qgd2FpdCBmb3IgUkVBRFlfU1RBVC4KICogMi4wMyAgSmFuIDEwLCAxOTk1IC0tIFJld3JpdGUgYmxvY2sgcmVhZCByb3V0aW5lcyB0byBoYW5kbGUgYmxvY2sgc2l6ZXMKICogICAgICAgICAgICAgICAgICAgICAgIG90aGVyIHRoYW4gMmsgYW5kIHRvIG1vdmUgbXVsdGlwbGUgc2VjdG9ycyBpbiBhCiAqICAgICAgICAgICAgICAgICAgICAgICBzaW5nbGUgdHJhbnNhY3Rpb24uCiAqIDIuMDQgIEFwciAyMSwgMTk5NSAtLSBBZGQgd29yay1hcm91bmQgZm9yIENyZWF0aXZlIExhYnMgQ0QyMjBFIGRyaXZlcy4KICogICAgICAgICAgICAgICAgICAgICAgIFRoYW5rcyB0byBOaWNrIFNhdyA8Y3dzYXdAcHRzNy5wdHMubW90LmNvbT4gZm9yCiAqICAgICAgICAgICAgICAgICAgICAgICBoZWxwIGluIGZpZ3VyaW5nIHRoaXMgb3V0LiAgRGl0dG8gZm9yIEFjZXIgYW5kCiAqICAgICAgICAgICAgICAgICAgICAgICBBenRlY2ggZHJpdmVzLCB3aGljaCBzZWVtIHRvIGhhdmUgdGhlIHNhbWUgcHJvYmxlbS4KICogMi4wNGIgTWF5IDMwLCAxOTk1IC0tIEZpeCB0byBtYXRjaCBjaGFuZ2VzIGluIGlkZS5jIHZlcnNpb24gMy4xNiAtbWwKICogMi4wNSAgSnVuICA4LCAxOTk1IC0tIERvbid0IGF0dGVtcHQgdG8gcmV0cnkgYWZ0ZXIgYW4gaWxsZWdhbCByZXF1ZXN0CiAqICAgICAgICAgICAgICAgICAgICAgICAgb3IgZGF0YSBwcm90ZWN0IGVycm9yLgogKiAgICAgICAgICAgICAgICAgICAgICAgVXNlIEhXSUYgYW5kIERFVl9IV0lGIG1hY3JvcyBhcyBpbiBpZGUuYy4KICogICAgICAgICAgICAgICAgICAgICAgIEFsd2F5cyB0cnkgdG8gZG8gYSByZXF1ZXN0X3NlbnNlIGFmdGVyCiAqICAgICAgICAgICAgICAgICAgICAgICAgYSBmYWlsZWQgY29tbWFuZC4KICogICAgICAgICAgICAgICAgICAgICAgIEluY2x1ZGUgYW4gb3B0aW9uIHRvIGdpdmUgdGV4dHVhbCBkZXNjcmlwdGlvbnMKICogICAgICAgICAgICAgICAgICAgICAgICBvZiBBVEFQSSBlcnJvcnMuCiAqICAgICAgICAgICAgICAgICAgICAgICBGaXggYSBidWcgaW4gaGFuZGxpbmcgdGhlIHNlY3RvciBjYWNoZSB3aGljaAogKiAgICAgICAgICAgICAgICAgICAgICAgIHNob3dlZCB1cCBpZiB0aGUgZHJpdmUgcmV0dXJuZWQgZGF0YSBpbiA1MTIgYnl0ZQogKiAgICAgICAgICAgICAgICAgICAgICAgIGJsb2NrcyAobGlrZSBQaW9uZWVyIGRyaXZlcykuICBUaGFua3MgdG8KICogICAgICAgICAgICAgICAgICAgICAgICBSaWNoYXJkIEhpcnN0IDxzcmhAZ3B0LmNvLnVrPiBmb3IgZGlhZ25vc2luZyB0aGlzLgogKiAgICAgICAgICAgICAgICAgICAgICAgUHJvcGVybHkgc3VwcGx5IHRoZSBwYWdlIG51bWJlciBmaWVsZCBpbiB0aGUKICogICAgICAgICAgICAgICAgICAgICAgICBNT0RFX1NFTEVDVCBjb21tYW5kLgogKiAgICAgICAgICAgICAgICAgICAgICAgUExBWUFVRElPMTIgaXMgYnJva2VuIG9uIHRoZSBBenRlY2g7IHdvcmsgYXJvdW5kIGl0LgogKiAyLjA1eCBBdWcgMTEsIDE5OTUgLS0gbG90cyBvZiBkYXRhIHN0cnVjdHVyZSByZW5hbWluZy9yZXN0cnVjdHVyaW5nIGluIGlkZS5jCiAqICAgICAgICAgICAgICAgICAgICAgICAobXkgYXBvbG9naWVzIHRvIFNjb3R0LCBidXQgbm93IGlkZS1jZC5jIGlzIGluZGVwZW5kZW50KQogKiAzLjAwICBBdWcgMjIsIDE5OTUgLS0gSW1wbGVtZW50IENEUk9NTVVMVElTRVNTSU9OIGlvY3RsLgogKiAgICAgICAgICAgICAgICAgICAgICAgSW1wbGVtZW50IENEUk9NUkVBREFVRElPIGlvY3RsIChVTlRFU1RFRCkuCiAqICAgICAgICAgICAgICAgICAgICAgICBVc2UgaW5wdXRfaWRlX2RhdGEoKSBhbmQgb3V0cHV0X2lkZV9kYXRhKCkuCiAqICAgICAgICAgICAgICAgICAgICAgICBBZGQgZG9vciBsb2NraW5nLgogKiAgICAgICAgICAgICAgICAgICAgICAgRml4IHVzYWdlIGNvdW50IGxlYWsgaW4gY2Ryb21fb3Blbiwgd2hpY2ggaGFwcGVuZWQKICogICAgICAgICAgICAgICAgICAgICAgICB3aGVuIGEgcmVhZC13cml0ZSBtb3VudCB3YXMgYXR0ZW1wdGVkLgogKiAgICAgICAgICAgICAgICAgICAgICAgVHJ5IHRvIGxvYWQgdGhlIGRpc2sgb24gb3Blbi4KICogICAgICAgICAgICAgICAgICAgICAgIEltcGxlbWVudCBDRFJPTUVKRUNUX1NXIGlvY3RsIChvZmYgYnkgZGVmYXVsdCkuCiAqICAgICAgICAgICAgICAgICAgICAgICBSZWFkIHRvdGFsIGNkcm9tIGNhcGFjaXR5IGR1cmluZyBvcGVuLgogKiAgICAgICAgICAgICAgICAgICAgICAgUmVhcnJhbmdlIGxvZ2ljIGluIGNkcm9tX2RlY29kZV9zdGF0dXMuICBJc3N1ZQogKiAgICAgICAgICAgICAgICAgICAgICAgIHJlcXVlc3Qgc2Vuc2UgY29tbWFuZHMgZm9yIGZhaWxlZCBwYWNrZXQgY29tbWFuZHMKICogICAgICAgICAgICAgICAgICAgICAgICBmcm9tIGhlcmUgaW5zdGVhZCBvZiBmcm9tIGNkcm9tX3F1ZXVlX3BhY2tldF9jb21tYW5kLgogKiAgICAgICAgICAgICAgICAgICAgICAgIEZpeCBhIHJhY2UgY29uZGl0aW9uIGluIHJldHJpZXZpbmcgZXJyb3IgaW5mb3JtYXRpb24uCiAqICAgICAgICAgICAgICAgICAgICAgICBTdXBwcmVzcyBwcmludGluZyBub3JtYWwgdW5pdCBhdHRlbnRpb24gZXJyb3JzIGFuZAogKiAgICAgICAgICAgICAgICAgICAgICAgIHNvbWUgZHJpdmUgbm90IHJlYWR5IGVycm9ycy4KICogICAgICAgICAgICAgICAgICAgICAgIEltcGxlbWVudCBDRFJPTVZPTFJFQUQgaW9jdGwuCiAqICAgICAgICAgICAgICAgICAgICAgICBJbXBsZW1lbnQgQ0RST01SRUFETU9ERTEvMiBpb2N0bHMuCiAqICAgICAgICAgICAgICAgICAgICAgICBGaXggcmFjZSBjb25kaXRpb24gaW4gc2V0dGluZyB1cCBpbnRlcnJ1cHQgaGFuZGxlcnMKICogICAgICAgICAgICAgICAgICAgICAgICB3aGVuIHRoZSBgc2VyaWFsaXplJyBvcHRpb24gaXMgdXNlZC4KICogMy4wMSAgU2VwICAyLCAxOTk1IC0tIEZpeCBvcmRlcmluZyBvZiByZWVuYWJsaW5nIGludGVycnVwdHMgaW4KICogICAgICAgICAgICAgICAgICAgICAgICBjZHJvbV9xdWV1ZV9yZXF1ZXN0LgogKiAgICAgICAgICAgICAgICAgICAgICAgQW5vdGhlciB0cnkgYXQgdXNpbmcgaWRlX1tpbnB1dCxvdXRwdXRdX2RhdGEuCiAqIDMuMDIgIFNlcCAxNiwgMTk5NSAtLSBTdGljayB0b3RhbCBkaXNrIGNhcGFjaXR5IGluIHBhcnRpdGlvbiB0YWJsZSBhcyB3ZWxsLgogKiAgICAgICAgICAgICAgICAgICAgICAgTWFrZSBWRVJCT1NFX0lERV9DRF9FUlJPUlMgZHVtcCBmYWlsZWQgY29tbWFuZCBhZ2Fpbi4KICogICAgICAgICAgICAgICAgICAgICAgIER1bXAgb3V0IG1vcmUgaW5mb3JtYXRpb24gZm9yIElMTEVHQUwgUkVRVUVTVCBlcnJzLgogKiAgICAgICAgICAgICAgICAgICAgICAgRml4IGhhbmRsaW5nIG9mIGVycm9ycyBvY2N1cnJpbmcgYmVmb3JlIHRoZQogKiAgICAgICAgICAgICAgICAgICAgICAgIHBhY2tldCBjb21tYW5kIGlzIHRyYW5zZmVycmVkLgogKiAgICAgICAgICAgICAgICAgICAgICAgRml4IHRyYW5zZmVycyB3aXRoIG9kZCBieXRlbGVuZ3Rocy4KICogMy4wMyAgT2N0IDI3LCAxOTk1IC0tIFNvbWUgQ3JlYXRpdmUgZHJpdmVzIGhhdmUgYW4gaWQgb2YganVzdCBgQ0QnLgogKiAgICAgICAgICAgICAgICAgICAgICAgYERDSS0yUzEwJyBkcml2ZXMgYXJlIGJyb2tlbiB0b28uCiAqIDMuMDQgIE5vdiAyMCwgMTk5NSAtLSBTbyBhcmUgVmVydG9zIGRyaXZlcy4KICogMy4wNSAgRGVjICAxLCAxOTk1IC0tIENoYW5nZXMgdG8gZ28gd2l0aCBvdmVyaGF1bCBvZiBpZGUuYyBhbmQgaWRlLXRhcGUuYwogKiAzLjA2ICBEZWMgMTYsIDE5OTUgLS0gQWRkIHN1cHBvcnQgbmVlZGVkIGZvciBwYXJ0aXRpb25zLgogKiAgICAgICAgICAgICAgICAgICAgICAgTW9yZSB3b3JrYXJvdW5kcyBmb3IgVmVydG9zIGJ1Z3MgKGJhc2VkIG9uIHBhdGNoZXMKICogICAgICAgICAgICAgICAgICAgICAgICBmcm9tIEhvbGdlciBEaWV0emUgPGRpZXR6ZUBhaXg1MjAuaW5mb3JtYXRpay51bmktbGVpcHppZy5kZT4pLgogKiAgICAgICAgICAgICAgICAgICAgICAgVHJ5IHRvIGVsaW1pbmF0ZSBieXRlb3JkZXIgYXNzdW1wdGlvbnMuCiAqICAgICAgICAgICAgICAgICAgICAgICBVc2UgYXRhcGlfY2Ryb21fc3ViY2hubCBzdHJ1Y3QgZGVmaW5pdGlvbi4KICogICAgICAgICAgICAgICAgICAgICAgIEFkZCBTVEFOREFSRF9BVEFQSSBjb21waWxhdGlvbiBvcHRpb24uCiAqIDMuMDcgIEphbiAyOSwgMTk5NiAtLSBNb3JlIHR3aWRkbGluZyBmb3IgYnJva2VuIGRyaXZlczogU29ueSA1NUQsCiAqICAgICAgICAgICAgICAgICAgICAgICAgVmVydG9zIDMwMC4KICogICAgICAgICAgICAgICAgICAgICAgIEFkZCBOT19ET09SX0xPQ0tJTkcgY29uZmlndXJhdGlvbiBvcHRpb24uCiAqICAgICAgICAgICAgICAgICAgICAgICBIYW5kbGUgZHJpdmVfY21kIHJlcXVlc3RzIHcvTlVMTCBhcmdzIChmb3IgaGRwYXJtIC10KS4KICogICAgICAgICAgICAgICAgICAgICAgIFdvcmsgYXJvdW5kIHNwb3JhZGljIFNvbnk1NWUgYXVkaW8gcGxheSBwcm9ibGVtLgogKiAzLjA3YSBGZWIgMTEsIDE5OTYgLS0gY2hlY2sgZHJpdmUtPmlkIGZvciBOVUxMIGJlZm9yZSBkZXJlZmVyZW5jaW5nLCB0byBmaXgKICogICAgICAgICAgICAgICAgICAgICAgICBwcm9ibGVtIHdpdGggImhkZT1jZHJvbSIgd2l0aCBubyBkcml2ZSBwcmVzZW50LiAgLW1sCiAqIDMuMDggIE1hciAgNiwgMTk5NiAtLSBNb3JlIFZlcnRvcyB3b3JrYXJvdW5kcy4KICogMy4wOSAgQXByICA1LCAxOTk2IC0tIEFkZCBDRFJPTUNMT1NFVFJBWSBpb2N0bC4KICogICAgICAgICAgICAgICAgICAgICAgIFN3aXRjaCB0byB1c2luZyBNU0YgYWRkcmVzc2luZyBmb3IgYXVkaW8gY29tbWFuZHMuCiAqICAgICAgICAgICAgICAgICAgICAgICBSZWZvcm1hdCB0byBtYXRjaCBrZXJuZWwgdGFiYmluZyBzdHlsZS4KICogICAgICAgICAgICAgICAgICAgICAgIEFkZCBDRFJPTV9HRVRfVVBDIGlvY3RsLgogKiAzLjEwICBBcHIgMTAsIDE5OTYgLS0gRml4IGNvbXBpbGF0aW9uIGVycm9yIHdpdGggU1RBTkRBUkRfQVRBUEkuCiAqIDMuMTEgIEFwciAyOSwgMTk5NiAtLSBQYXRjaCBmcm9tIEhlaWtvIEVpc3NmZWxkdCA8aGVpa29AY29sb3NzdXMuZXNjYXBlLmRlPgogKiAgICAgICAgICAgICAgICAgICAgICAgdG8gcmVtb3ZlIHJlZHVuZGFudCB2ZXJpZnlfYXJlYSBjYWxscy4KICogMy4xMiAgTWF5ICA3LCAxOTk2IC0tIFJ1ZGltZW50YXJ5IGNoYW5nZXIgc3VwcG9ydC4gIEJhc2VkIG9uIHBhdGNoZXMKICogICAgICAgICAgICAgICAgICAgICAgICBmcm9tIEdlcmhhcmQgWnViZXIgPHp1YmVyQGJlcmxpbi5zbmFmdS5kZT4uCiAqICAgICAgICAgICAgICAgICAgICAgICBMZXQgb3BlbiBzdWNjZWVkIGV2ZW4gaWYgdGhlcmUncyBubyBsb2FkZWQgZGlzYy4KICogMy4xMyAgTWF5IDE5LCAxOTk2IC0tIEZpeGVzIGZvciBjaGFuZ2VyIGNvZGUuCiAqIDMuMTQgIE1heSAyOSwgMTk5NiAtLSBBZGQgd29yay1hcm91bmQgZm9yIFZlcnRvcyA2MDAuCiAqICAgICAgICAgICAgICAgICAgICAgICAgKEZyb20gSGVubnVzIEJlcmdtYW4gPGhlbm51c0Bza3kub3cubmw+LikKICogMy4xNSAgSnVseSAyLCAxOTk2IC0tIEFkZGVkIHN1cHBvcnQgZm9yIFNhbnlvIDMgQ0QgY2hhbmdlcnMKICogICAgICAgICAgICAgICAgICAgICAgICBmcm9tIEJlbiBHYWxsaWFydCA8YmdhbGxpYUBsdWMuZWR1PiB3aXRoIAogKiAgICAgICAgICAgICAgICAgICAgICAgIHNwZWNpYWwgaGVscCBmcm9tIEplZmYgTGlnaHRmb290IAogKiAgICAgICAgICAgICAgICAgICAgICAgIDxqZWZmbWxAcG9ib3guY29tPgogKiAzLjE1YSBKdWx5IDksIDE5OTYgLS0gSW1wcm92ZWQgU2FueW8gMyBDRCBjaGFuZ2VyIGlkZW50aWZpY2F0aW9uCiAqIDMuMTYgIEp1bCAyOCwgMTk5NiAtLSBGaXggZnJvbSBHYWRpIHRvIHJlZHVjZSBrZXJuZWwgc3RhY2sgdXNhZ2UgZm9yIGlvY3RsLgogKiAzLjE3ICBTZXAgMTcsIDE5OTYgLS0gVHdlYWsgYXVkaW8gcmVhZHMgZm9yIHNvbWUgZHJpdmVzLgogKiAgICAgICAgICAgICAgICAgICAgICAgU3RhcnQgY2hhbmdpbmcgQ0RST01MT0FERlJPTVNMT1QgdG8gQ0RST01fU0VMRUNUX0RJU0MuCiAqIDMuMTggIE9jdCAzMSwgMTk5NiAtLSBBZGRlZCBtb2R1bGUgYW5kIERNQSBzdXBwb3J0LgogKiAgICAgICAgICAgICAgICAgICAgICAgCiAqICAgICAgICAgICAgICAgICAgICAgICAKICogNC4wMCAgTm92IDUsIDE5OTYgICAtLSBOZXcgaWRlLWNkIG1haW50YWluZXIsCiAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgRXJpayBCLiBBbmRlcnNlbiA8YW5kZXJzZWVAZGViaWFuLm9yZz4KICogICAgICAgICAgICAgICAgICAgICAtLSBOZXdlciBDcmVhdGl2ZSBkcml2ZXMgZG9uJ3QgYWx3YXlzIHNldCB0aGUgZXJyb3IKICogICAgICAgICAgICAgICAgICAgICAgICAgIHJlZ2lzdGVyIGNvcnJlY3RseS4gIE1ha2Ugc3VyZSB3ZSBzZWUgbWVkaWEgY2hhbmdlcwogKiAgICAgICAgICAgICAgICAgICAgICAgICAgcmVnYXJkbGVzcy4KICogICAgICAgICAgICAgICAgICAgICAtLSBJbnRlZ3JhdGUgd2l0aCBnZW5lcmljIGNkcm9tIGRyaXZlci4KICogICAgICAgICAgICAgICAgICAgICAtLSBDRFJPTUdFVFNQSU5ET1dOIGFuZCBDRFJPTVNFVFNQSU5ET1dOIGlvY3RscywgYmFzZWQgb24KICogICAgICAgICAgICAgICAgICAgICAgICAgIGEgcGF0Y2ggZnJvbSBDaXJvIENhdHR1dG8gPD4uCiAqICAgICAgICAgICAgICAgICAgICAgLS0gQ2FsbCBzZXRfZGV2aWNlX3JvLgogKiAgICAgICAgICAgICAgICAgICAgIC0tIEltcGxlbWVudCBDRFJPTU1FQ0hBTklTTVNUQVRVUyBhbmQgQ0RST01TTE9UVEFCTEUKICogICAgICAgICAgICAgICAgICAgICAgICAgIGlvY3RscywgYmFzZWQgb24gcGF0Y2ggYnkgRXJpayBBbmRlcnNlbgogKiAgICAgICAgICAgICAgICAgICAgIC0tIEFkZCBzb21lIHByb2JlcyBvZiBkcml2ZSBjYXBhYmlsaXR5IGR1cmluZyBzZXR1cC4KICoKICogNC4wMSAgTm92IDExLCAxOTk2ICAtLSBTcGxpdCBpbnRvIGlkZS1jZC5jIGFuZCBpZGUtY2QuaAogKiAgICAgICAgICAgICAgICAgICAgIC0tIFJlbW92ZWQgQ0RST01NRUNIQU5JU01TVEFUVVMgYW5kIENEUk9NU0xPVFRBQkxFIAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgaW9jdGxzIGluIGZhdm9yIG9mIGEgZ2VuZXJhbGl6ZWQgYXBwcm9hY2ggCiAqICAgICAgICAgICAgICAgICAgICAgICAgICB1c2luZyB0aGUgZ2VuZXJpYyBjZHJvbSBkcml2ZXIuCiAqICAgICAgICAgICAgICAgICAgICAgLS0gRnVsbHkgaW50ZWdyYXRlZCB3aXRoIHRoZSAyLjEuWCBrZXJuZWwuCiAqICAgICAgICAgICAgICAgICAgICAgLS0gT3RoZXIgc3R1ZmYgdGhhdCBJIGZvcmdvdCAobG90cyBvZiBjaGFuZ2VzKQogKgogKiA0LjAyICBEZWMgMDEsIDE5OTYgIC0tIEFwcGxpZWQgcGF0Y2ggZnJvbSBHYWRpIE94bWFuIDxnYWRpb0BuZXR2aXNpb24ubmV0LmlsPgogKiAgICAgICAgICAgICAgICAgICAgICAgICAgdG8gZml4IHRoZSBkcml2ZSBkb29yIGxvY2tpbmcgcHJvYmxlbXMuCiAqCiAqIDQuMDMgIERlYyAwNCwgMTk5NiAgLS0gQWRkZWQgRFNDIG92ZXJsYXAgc3VwcG9ydC4KICogNC4wNCAgRGVjIDI5LCAxOTk2ICAtLSBBZGRlZCBDRFJPTVJFQURSQVcgaW9jbHQgYmFzZWQgb24gcGF0Y2ggCiAqICAgICAgICAgICAgICAgICAgICAgICAgICBieSBBbGVzIE1ha2Fyb3YgKHhtYWthcm92QHN1bi5mZWxrLmN2dXQuY3opCiAqCiAqIDQuMDUgIE5vdiAyMCwgMTk5NyAgLS0gTW9kaWZpZWQgdG8gcHJpbnQgbW9yZSBkcml2ZSBpbmZvIG9uIGluaXQKICogICAgICAgICAgICAgICAgICAgICAgICBNaW5vciBvdGhlciBjaGFuZ2VzCiAqICAgICAgICAgICAgICAgICAgICAgICAgRml4IGVycm9ycyBvbiBDRFJPTVNUT1AgKElmIHlvdSBoYXZlIGEgIkRvbHBoaW4iLAogKiAgICAgICAgICAgICAgICAgICAgICAgICAgeW91IG11c3QgZGVmaW5lIElIQVZFQURPTFBISU4pCiAqICAgICAgICAgICAgICAgICAgICAgICAgQWRkZWQgaWRlbnRpZmllciBzbyBuZXcgU2FueW8gQ0QtY2hhbmdlciB3b3JrcwogKiAgICAgICAgICAgICAgICAgICAgICAgIEJldHRlciBkZXRlY3Rpb24gaWYgZG9vciBsb2NraW5nIGlzbid0IHN1cHBvcnRlZAogKgogKiA0LjA2ICBEZWMgMTcsIDE5OTcgIC0tIGZpeGVkIGVuZGxlc3MgInRyYXkgb3BlbiIgbWVzc2FnZXMgIC1tbAogKiA0LjA3ICBEZWMgMTcsIDE5OTcgIC0tIGZhbGxiYWNrIHRvIHNldCBwYy0+c3RhdCBvbiAidHJheSBvcGVuIgogKiA0LjA4ICBEZWMgMTgsIDE5OTcgIC0tIHNwZXcgbGVzcyBub2lzZSB3aGVuIHRyYXkgaXMgZW1wdHkKICogICAgICAgICAgICAgICAgICAgICAtLSBmaXggc3BlZWQgZGlzcGxheSBmb3IgQUNFUiAyNFgsIDE4WAogKiA0LjA5ICBKYW4gMDQsIDE5OTggIC0tIGZpeCBoYW5kbGluZyBvZiB0aGUgbGFzdCBibG9jayBzbyB3ZSByZXR1cm4KICogICAgICAgICAgICAgICAgICAgICAgICAgYW4gZW5kIG9mIGZpbGUgaW5zdGVhZCBvZiBhbiBJL08gZXJyb3IgKEdhZGkpCiAqIDQuMTAgIEphbiAyNCwgMTk5OCAgLS0gZml4ZWQgYSBidWcgc28gbm93IGNoYW5nZXJzIGNhbiBjaGFuZ2UgdG8gYSBuZXcKICogICAgICAgICAgICAgICAgICAgICAgICAgc2xvdCB3aGVuIHRoZXJlIGlzIG5vIGRpc2MgaW4gdGhlIGN1cnJlbnQgc2xvdC4KICogICAgICAgICAgICAgICAgICAgICAtLSBGaXhlZCBhIG1lbW9yeSBsZWFrIHdoZXJlIGluZm8tPmNoYW5nZXJfaW5mbyB3YXMKICogICAgICAgICAgICAgICAgICAgICAgICAgbWFsbG9jJ2VkIGJ1dCBuZXZlciBmcmVlJ2Qgd2hlbiBjbG9zaW5nIHRoZSBkZXZpY2UuCiAqICAgICAgICAgICAgICAgICAgICAgLS0gQ2xlYW5lZCB1cCB0aGUgZ2xvYmFsIG5hbWVzcGFjZSBhIGJpdCBieSBtYWtpbmcgbW9yZQogKiAgICAgICAgICAgICAgICAgICAgICAgICBmdW5jdGlvbnMgc3RhdGljIHRoYXQgc2hvdWxkIGFscmVhZHkgaGF2ZSBiZWVuLgogKiA0LjExICBNYXIgMTIsIDE5OTggIC0tIEFkZGVkIHN1cHBvcnQgZm9yIHRoZSBDRFJPTV9TRUxFQ1RfU1BFRUQgaW9jdGwKICogICAgICAgICAgICAgICAgICAgICAgICAgYmFzZWQgb24gYSBwYXRjaCBmb3IgMi4wLjMzIGJ5IEplbGxlIEZva3MgCiAqICAgICAgICAgICAgICAgICAgICAgICAgIDxqZWxsZUBzY2ludGlsbGEudXR3ZW50ZS5ubD4sIGEgcGF0Y2ggZm9yIDIuMC4zMwogKiAgICAgICAgICAgICAgICAgICAgICAgICBieSBUb25pIEdpb3JnaW5vIDx0b25pQHBjYXBlMi5waS5pbmZuLml0PiwgdGhlIFNDU0kKICogICAgICAgICAgICAgICAgICAgICAgICAgdmVyc2lvbiwgYW5kIG15IG93biBlZmZvcnRzLiAgLWVyaWsKICogICAgICAgICAgICAgICAgICAgICAtLSBGaXhlZCBhIHN0dXBpZCBidWcgd2hpY2ggZWdjcyB3YXMga2luZCBlbm91Z2ggdG8KICogICAgICAgICAgICAgICAgICAgICAgICAgaW5mb3JtIG1lIG9mIHdoZXJlICJJbGxlZ2FsIG1vZGUgZm9yIHRoaXMgdHJhY2siCiAqICAgICAgICAgICAgICAgICAgICAgICAgIHdhcyBuZXZlciByZXR1cm5lZCBkdWUgdG8gYSBjb21wYXJpc29uIG9uIGRhdGEKICogICAgICAgICAgICAgICAgICAgICAgICAgdHlwZXMgb2YgbGltaXRlZCByYW5nZS4KICogNC4xMiAgTWFyIDI5LCAxOTk4ICAtLSBGaXhlZCBidWcgaW4gQ0RST01fU0VMRUNUX1NQRUVEIHNvIHdyaXRlIHNwZWVkIGlzIAogKiAgICAgICAgICAgICAgICAgICAgICAgICBub3cgc2V0IGlvbmx5IGZvciBDRC1SIGFuZCBDRC1SVyBkcml2ZXMuICBJIGhhZCAKICogICAgICAgICAgICAgICAgICAgICAgICAgcmVtb3ZlZCB0aGlzIHN1cHBvcnQgYmVjYXVzZSBpdCBwcm9kdWNlZCBlcnJvcnMuCiAqICAgICAgICAgICAgICAgICAgICAgICAgIEl0IHByb2R1Y2VkIGVycm9ycyBfb25seV8gZm9yIG5vbi13cml0ZXJzLiBkdWguCiAqIDQuMTMgIE1heSAwNSwgMTk5OCAgLS0gU3VwcHJlc3MgdXNlbGVzcyAiaW4gcHJvZ3Jlc3Mgb2YgYmVjb21pbmcgcmVhZHkiCiAqICAgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VzLCBzaW5jZSB0aGlzIGlzIG5vdCBhbiBlcnJvci4KICogICAgICAgICAgICAgICAgICAgICAtLSBDaGFuZ2UgZXJyb3IgbWVzc2FnZXMgdG8gYmUgY29uc3QKICogICAgICAgICAgICAgICAgICAgICAtLSBSZW1vdmUgYSAiXHQiIHdoaWNoIGxvb2tzIHVnbHkgaW4gdGhlIHN5c2xvZ3MKICogNC4xNCAgSnVseSAxNywgMTk5OCAtLSBDaGFuZ2UgdG8gcG9pbnRpbmcgdG8gLnBzIHZlcnNpb24gb2YgQVRBUEkgc3BlYwogKiAgICAgICAgICAgICAgICAgICAgICAgICBzaW5jZSB0aGUgLnBkZiB2ZXJzaW9uIGRvZXNuJ3Qgc2VlbSB0byB3b3JrLi4uCiAqICAgICAgICAgICAgICAgICAgICAgLS0gVXBkYXRlZCB0aGUgVE9ETyBsaXN0IHRvIHNvbWV0aGluZyBtb3JlIGN1cnJlbnQuCiAqCiAqIDQuMTUgIEF1ZyAyNSwgMTk5OCAgLS0gVXBkYXRlZCBpZGUtY2QuaCB0byByZXNwZWN0IG1lY2hpbmUgZW5kaWFuZXNzLCAKICogICAgICAgICAgICAgICAgICAgICAgICAgcGF0Y2ggdGhhbmtzIHRvICJFZGRpZSBDLiBEb3N0IiA8ZWNkQHNreW5ldC5iZT4KICoKICogNC41MCAgT2N0IDE5LCAxOTk4ICAtLSBOZXcgbWFpbnRhaW5lcnMhCiAqICAgICAgICAgICAgICAgICAgICAgICAgIEplbnMgQXhib2UgPGF4Ym9lQGltYWdlLmRrPgogKiAgICAgICAgICAgICAgICAgICAgICAgICBDaHJpcyBad2lsbGluZyA8Y2hyaXNAY2xvdWRuZXQuY29tPgogKgogKiA0LjUxICBEZWMgMjMsIDE5OTggIC0tIEplbnMgQXhib2UgPGF4Ym9lQGltYWdlLmRrPgogKiAgICAgICAgICAgICAgICAgICAgICAtIGlkZV9jZHJvbV9yZXNldCBlbmFibGVkIHNpbmNlIHRoZSBpZGUgc3Vic3lzdGVtCiAqICAgICAgICAgICAgICAgICAgICAgICAgIGhhbmRsZXMgcmVzZXRzIGZpbmUgbm93LiA8YXhib2VAaW1hZ2UuZGs+CiAqICAgICAgICAgICAgICAgICAgICAgIC0gVHJhbnNmZXIgc2l6ZSBmaXggZm9yIFNhbXN1bmcgQ0QtUk9NcywgdGhhbmtzIHRvCiAqICAgICAgICAgICAgICAgICAgICAgICAgIlZpbGxlIEhhbGxpayIgPHZpbGxlLmhhbGxpa0BtYWlsLmVlPi4KICogICAgICAgICAgICAgICAgICAgICAgLSBvdGhlciBtaW5vciBzdHVmZi4KICoKICogNC41MiAgSmFuIDE5LCAxOTk5ICAtLSBKZW5zIEF4Ym9lIDxheGJvZUBpbWFnZS5kaz4KICogICAgICAgICAgICAgICAgICAgICAgLSBEZXRlY3QgRFZELVJPTS9SQU0gZHJpdmVzCiAqCiAqIDQuNTMgIEZlYiAyMiwgMTk5OSAgIC0gSW5jbHVkZSBvdGhlciBtb2RlbCBTYW1zdW5nIGFuZCBvbmUgR29sZHN0YXIKICogICAgICAgICAgICAgICAgICAgICAgICAgZHJpdmUgaW4gdHJhbnNmZXIgc2l6ZSBsaW1pdC4KICogICAgICAgICAgICAgICAgICAgICAgLSBGaXggdGhlIEkvTyBlcnJvciB3aGVuIGRvaW5nIGVqZWN0IHdpdGhvdXQgYSBtZWRpdW0KICogICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVkIG9uIHNvbWUgZHJpdmVzLgogKiAgICAgICAgICAgICAgICAgICAgICAtIENEUk9NUkVBRE1PREUyIGlzIG5vdyBpbXBsZW1lbnRlZCB0aHJvdWdoCiAqICAgICAgICAgICAgICAgICAgICAgICAgIENEUk9NUkVBRFJBVywgc2luY2UgbWFueSBkcml2ZXMgZG9uJ3Qgc3VwcG9ydAogKiAgICAgICAgICAgICAgICAgICAgICAgICBNT0RFMiAoZXZlbiB0aG91Z2ggQVRBUEkgMi42IHNheXMgdGhleSBtdXN0KS4KICogICAgICAgICAgICAgICAgICAgICAgLSBBZGRlZCBpZ25vcmUgcGFyYW1ldGVyIHRvIGlkZS1jZCAoYXMgYSBtb2R1bGUpLCBlZwogKiAgICAgICAgICAgICAgICAgICAgICAgICAJaW5zbW9kIGlkZS1jZCBpZ25vcmU9J2hkYSBoZGInCiAqICAgICAgICAgICAgICAgICAgICAgICAgIFVzZWZ1bCB3aGVuIHVzaW5nIGlkZS1jZCBpbiBjb25qdW5jdGlvbiB3aXRoCiAqICAgICAgICAgICAgICAgICAgICAgICAgIGlkZS1zY3NpLiBUT0RPOiBub24tbW9kdWxhciB3YXkgb2YgZG9pbmcgdGhlCiAqICAgICAgICAgICAgICAgICAgICAgICAgIHNhbWUuCiAqCiAqIDQuNTQgIEF1ZyA1LCAxOTk5CS0gU3VwcG9ydCBmb3IgTU1DMiBjbGFzcyBjb21tYW5kcyB0aHJvdWdoIHRoZSBnZW5lcmljCiAqCQkJICBwYWNrZXQgaW50ZXJmYWNlIHRvIGNkcm9tLmMuCiAqCQkJLSBVbmlmaWVkIGF1ZGlvIGlvY3RsIHN1cHBvcnQsIG1vc3Qgb2YgaXQuCiAqCQkJLSBjbGVhbmVkIHVwIHZhcmlvdXMgZGVwcmVjYXRlZCB2ZXJpZnlfYXJlYSgpLgogKgkJCS0gQWRkZWQgaWRlX2Nkcm9tX3BhY2tldCgpIGFzIHRoZSBpbnRlcmZhY2UgZm9yCiAqCQkJICB0aGUgVW5pZm9ybSBnZW5lcmljX3BhY2tldCgpLgogKgkJCS0gYnVuY2ggb2Ygb3RoZXIgc3R1ZmYsIHdpbGwgZmlsbCBpbiBsb2dzIGxhdGVyLgogKgkJCS0gcmVwb3J0IDEgc2xvdCBmb3Igbm9uLWNoYW5nZXJzLCBsaWtlIHRoZSBvdGhlcgogKgkJCSAgY2Qtcm9tIGRyaXZlcnMuIGRvbid0IHJlcG9ydCBzZWxlY3QgZGlzYyBmb3IKICoJCQkgIG5vbi1jaGFuZ2VycyBhcyB3ZWxsLgogKgkJCS0gbWFzayBvdXQgYXVkaW8gcGxheWluZywgaWYgdGhlIGRldmljZSBjYW4ndCBkbyBpdC4KICoKICogNC41NSAgU2VwIDEsIDE5OTkJLSBFbGltaW5hdGVkIHRoZSByZXN0IG9mIHRoZSBhdWRpbyBpb2N0bHMsIGV4Y2VwdAogKgkJCSAgZm9yIENEUk9NUkVBRFRPQ1tFTlRSWXxIRUFERVJdLiBTb21lIG9mIHRoZSBkcml2ZXJzCiAqCQkJICB1c2UgdGhpcyBpbmRlcGVuZGVudGx5IG9mIHRoZSBhY3R1YWwgYXVkaW8gaGFuZGxpbmcuCiAqCQkJICBUaGV5IHdpbGwgZGlzYXBwZWFyIGxhdGVyIHdoZW4gSSBnZXQgdGhlIHRpbWUgdG8KICoJCQkgIGRvIGl0IGNsZWFubHkuCiAqCQkJLSBNaW5pbWl6ZSB0aGUgVE9DIHJlYWRpbmcgLSBvbmx5IGRvIGl0IHdoZW4gd2UKICoJCQkgIGtub3cgYSBtZWRpYSBjaGFuZ2UgaGFzIG9jY3VycmVkLgogKgkJCS0gTW92ZWQgYWxsIHRoZSBDRFJPTVJFQUR4IGlvY3RscyB0byB0aGUgVW5pZm9ybSBsYXllci4KICoJCQktIEhlaWtvIEVpc3NmZWxkdCA8aGVpa29AY29sb3NzdXMuZXNjYXBlLmRlPiBzdXBwbGllZAogKgkJCSAgc29tZSBmaXhlcyBmb3IgQ0RJLgogKgkJCS0gQ0QtUk9NIGxlYXZpbmcgZG9vciBsb2NrZWQgZml4IGZyb20gQW5kcmllcwogKgkJCSAgQnJvdXdlciA8QW5kcmllcy5Ccm91d2VyQGN3aS5ubD4KICoJCQktIEVyaWsgQW5kZXJzZW4gPGFuZGVyc2VuQHhtaXNzaW9uLmNvbT4gdW5pZmllZAogKgkJCSAgY29tbWFuZHMgYWNyb3NzIHRoZSB2YXJpb3VzIGRyaXZlcnMgYW5kIGhvdwogKgkJCSAgc2Vuc2UgZXJyb3JzIGFyZSBoYW5kbGVkLgogKgogKiA0LjU2ICBTZXAgMTIsIDE5OTkJLSBSZW1vdmVkIGNoYW5nZXIgc3VwcG9ydCAtIGl0IGlzIG5vdyBpbiB0aGUKICoJCQkgIFVuaWZvcm0gbGF5ZXIuCiAqCQkJLSBBZGRlZCBwYXJ0aXRpb24gYmFzZWQgbXVsdGlzZXNzaW9uIGhhbmRsaW5nLgogKgkJCS0gTW9kZSBzZW5zZSBhbmQgbW9kZSBzZWxlY3QgbW92ZWQgdG8gdGhlCiAqCQkJICBVbmlmb3JtIGxheWVyLgogKgkJCS0gRml4ZWQgYSBwcm9ibGVtIHdpdGggV1BJIENEUy0zMlggZHJpdmUgLSBpdAogKgkJCSAgZmFpbGVkIHRoZSBjYXBhYmlsaXRpZXMgCiAqCiAqIDQuNTcgIEFwciA3LCAyMDAwCS0gRml4ZWQgc2Vuc2UgcmVwb3J0aW5nLgogKgkJCS0gRml4ZWQgcG9zc2libGUgb29wcyBpbiBpZGVfY2Ryb21fZ2V0X2xhc3Rfc2Vzc2lvbigpCiAqCQkJLSBGaXggbG9ja2luZyBtYW5pYSBhbmQgbWFrZSBpZGVfY2Ryb21fcmVzZXQgcmVsb2NrCiAqCQkJLSBTdG9wIHNwZXdpbmcgZXJyb3JzIHRvIGxvZyB3aGVuIG1hZ2ljZGV2IHBvbGxzIHdpdGgKICoJCQkgIFRFU1RfVU5JVF9SRUFEWSBvbiBzb21lIGRyaXZlcy4KICoJCQktIFZhcmlvdXMgZml4ZXMgZnJvbSBUb2JpYXMgUmluZ3N0cm9tOgogKgkJCSAgdHJheSBpZiBpdCB3YXMgbG9ja2VkIHByaW9yIHRvIHRoZSByZXNldC4KICoJCQkgIC0gY2Ryb21fcmVhZF9jYXBhY2l0eSByZXR1cm5zIG9uZSBmcmFtZSB0b28gbGl0dGxlLgogKgkJCSAgLSBGaXggcmVhbCBjYXBhY2l0eSByZXBvcnRpbmcuCiAqCiAqIDQuNTggIE1heSAxLCAyMDAwCS0gQ2xlYW4gdXAgQUNFUjUwIHN0dWZmLgogKgkJCS0gRml4IHNtYWxsIHByb2JsZW0gd2l0aCBpZGVfY2Ryb21fY2FwYWNpdHkKICoKICogNC41OSAgQXVnIDExLCAyMDAwCS0gRml4IGNoYW5nZXIgcHJvYmxlbSBpbiBjZHJvbV9yZWFkX3RvYywgd2Ugd2VyZW4ndAogKgkJCSAgY29ycmVjdGx5IHNlbnNpbmcgYSBkaXNjIGNoYW5nZS4KICoJCQktIFJlYXJyYW5nZWQgc29tZSBjb2RlCiAqCQkJLSBVc2UgZXh0ZW5kZWQgc2Vuc2Ugb24gZHJpdmVzIHRoYXQgc3VwcG9ydCBpdCBmb3IKICoJCQkgIGNvcnJlY3RseSByZXBvcnRpbmcgdHJheSBzdGF0dXMgLS0gZnJvbQogKgkJCSAgTWljaGFlbCBEIEpvaG5zb24gPGpvaG5zb21Ab3JzdC5lZHU+CiAqIDQuNjAgIERlYyAxNywgMjAwMwktIEFkZCBtdCByYWluaWVyIHN1cHBvcnQKICoJCQktIEJ1bXAgdGltZW91dCBmb3IgcGFja2V0IGNvbW1hbmRzLCBtYXRjaGVzIHNyCiAqCQkJLSBPZGQgc3R1ZmYKICogNC42MSAgSmFuIDIyLCAyMDA0CS0gc3VwcG9ydCBoYXJkd2FyZSBzZWN0b3Igc2l6ZXMgb3RoZXIgdGhhbiAya0IsCiAqCQkJICBQYXNjYWwgU2NobWlkdCA8ZGVyLmVyZW1pdEBlbWFpbC5kZT4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKiovCiAKI2RlZmluZSBJREVDRF9WRVJTSU9OICI0LjYxIgoKI2luY2x1ZGUgPGxpbnV4L2NvbmZpZy5oPgojaW5jbHVkZSA8bGludXgvbW9kdWxlLmg+CiNpbmNsdWRlIDxsaW51eC90eXBlcy5oPgojaW5jbHVkZSA8bGludXgva2VybmVsLmg+CiNpbmNsdWRlIDxsaW51eC9kZWxheS5oPgojaW5jbHVkZSA8bGludXgvdGltZXIuaD4KI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KI2luY2x1ZGUgPGxpbnV4L2ludGVycnVwdC5oPgojaW5jbHVkZSA8bGludXgvZXJybm8uaD4KI2luY2x1ZGUgPGxpbnV4L2Nkcm9tLmg+CiNpbmNsdWRlIDxsaW51eC9pZGUuaD4KI2luY2x1ZGUgPGxpbnV4L2NvbXBsZXRpb24uaD4KCiNpbmNsdWRlIDxzY3NpL3Njc2kuaD4JLyogRm9yIFNDU0kgLT4gQVRBUEkgY29tbWFuZCBjb252ZXJzaW9uICovCgojaW5jbHVkZSA8YXNtL2lycS5oPgojaW5jbHVkZSA8YXNtL2lvLmg+CiNpbmNsdWRlIDxhc20vYnl0ZW9yZGVyLmg+CiNpbmNsdWRlIDxhc20vdWFjY2Vzcy5oPgojaW5jbHVkZSA8YXNtL3VuYWxpZ25lZC5oPgoKI2luY2x1ZGUgImlkZS1jZC5oIgoKc3RhdGljIERFQ0xBUkVfTVVURVgoaWRlY2RfcmVmX3NlbSk7CgojZGVmaW5lIHRvX2lkZV9jZChvYmopIGNvbnRhaW5lcl9vZihvYmosIHN0cnVjdCBjZHJvbV9pbmZvLCBrcmVmKSAKCiNkZWZpbmUgaWRlX2NkX2coZGlzaykgXAoJY29udGFpbmVyX29mKChkaXNrKS0+cHJpdmF0ZV9kYXRhLCBzdHJ1Y3QgY2Ryb21faW5mbywgZHJpdmVyKQoKc3RhdGljIHN0cnVjdCBjZHJvbV9pbmZvICppZGVfY2RfZ2V0KHN0cnVjdCBnZW5kaXNrICpkaXNrKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqY2QgPSBOVUxMOwoKCWRvd24oJmlkZWNkX3JlZl9zZW0pOwoJY2QgPSBpZGVfY2RfZyhkaXNrKTsKCWlmIChjZCkKCQlrcmVmX2dldCgmY2QtPmtyZWYpOwoJdXAoJmlkZWNkX3JlZl9zZW0pOwoJcmV0dXJuIGNkOwp9CgpzdGF0aWMgdm9pZCBpZGVfY2RfcmVsZWFzZShzdHJ1Y3Qga3JlZiAqKTsKCnN0YXRpYyB2b2lkIGlkZV9jZF9wdXQoc3RydWN0IGNkcm9tX2luZm8gKmNkKQp7Cglkb3duKCZpZGVjZF9yZWZfc2VtKTsKCWtyZWZfcHV0KCZjZC0+a3JlZiwgaWRlX2NkX3JlbGVhc2UpOwoJdXAoJmlkZWNkX3JlZl9zZW0pOwp9CgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBHZW5lcmljIHBhY2tldCBjb21tYW5kIHN1cHBvcnQgYW5kIGVycm9yIGhhbmRsaW5nIHJvdXRpbmVzLgogKi8KCi8qIE1hcmsgdGhhdCB3ZSd2ZSBzZWVuIGEgbWVkaWEgY2hhbmdlLCBhbmQgaW52YWxpZGF0ZSBvdXIgaW50ZXJuYWwKICAgYnVmZmVycy4gKi8Kc3RhdGljIHZvaWQgY2Ryb21fc2F3X21lZGlhX2NoYW5nZSAoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCQoJQ0RST01fU1RBVEVfRkxBR1MgKGRyaXZlKS0+bWVkaWFfY2hhbmdlZCA9IDE7CglDRFJPTV9TVEFURV9GTEFHUyAoZHJpdmUpLT50b2NfdmFsaWQgPSAwOwoJaW5mby0+bnNlY3RvcnNfYnVmZmVyZWQgPSAwOwp9CgpzdGF0aWMgaW50IGNkcm9tX2xvZ19zZW5zZShpZGVfZHJpdmVfdCAqZHJpdmUsIHN0cnVjdCByZXF1ZXN0ICpycSwKCQkJICAgc3RydWN0IHJlcXVlc3Rfc2Vuc2UgKnNlbnNlKQp7CglpbnQgbG9nID0gMDsKCglpZiAoIXNlbnNlIHx8ICFycSB8fCAocnEtPmZsYWdzICYgUkVRX1FVSUVUKSkKCQlyZXR1cm4gMDsKCglzd2l0Y2ggKHNlbnNlLT5zZW5zZV9rZXkpIHsKCQljYXNlIE5PX1NFTlNFOiBjYXNlIFJFQ09WRVJFRF9FUlJPUjoKCQkJYnJlYWs7CgkJY2FzZSBOT1RfUkVBRFk6CgkJCS8qCgkJCSAqIGRvbid0IGNhcmUgYWJvdXQgdHJheSBzdGF0ZSBtZXNzYWdlcyBmb3IKCQkJICogZS5nLiBjYXBhY2l0eSBjb21tYW5kcyBvciBpbi1wcm9ncmVzcyBvcgoJCQkgKiBiZWNvbWluZyByZWFkeQoJCQkgKi8KCQkJaWYgKHNlbnNlLT5hc2MgPT0gMHgzYSB8fCBzZW5zZS0+YXNjID09IDB4MDQpCgkJCQlicmVhazsKCQkJbG9nID0gMTsKCQkJYnJlYWs7CgkJY2FzZSBJTExFR0FMX1JFUVVFU1Q6CgkJCS8qCgkJCSAqIGRvbid0IGxvZyBTVEFSVF9TVE9QIHVuaXQgd2l0aCBMb0VqIHNldCwgc2luY2UKCQkJICogd2UgY2Fubm90IHJlbGlhYmx5IGNoZWNrIGlmIGRyaXZlIGNhbiBhdXRvLWNsb3NlCgkJCSAqLwoJCQlpZiAocnEtPmNtZFswXSA9PSBHUENNRF9TVEFSVF9TVE9QX1VOSVQgJiYgc2Vuc2UtPmFzYyA9PSAweDI0KQoJCQkJbG9nID0gMDsKCQkJYnJlYWs7CgkJY2FzZSBVTklUX0FUVEVOVElPTjoKCQkJLyoKCQkJICogTWFrZSBnb29kIGFuZCBzdXJlIHdlJ3ZlIHNlZW4gdGhpcyBwb3RlbnRpYWwgbWVkaWEKCQkJICogY2hhbmdlLiBTb21lIGRyaXZlcyAoaS5lLiBDcmVhdGl2ZSkgZmFpbCB0byBwcmVzZW50CgkJCSAqIHRoZSBjb3JyZWN0IHNlbnNlIGtleSBpbiB0aGUgZXJyb3IgcmVnaXN0ZXIuCgkJCSAqLwoJCQljZHJvbV9zYXdfbWVkaWFfY2hhbmdlKGRyaXZlKTsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJbG9nID0gMTsKCQkJYnJlYWs7Cgl9CglyZXR1cm4gbG9nOwp9CgpzdGF0aWMKdm9pZCBjZHJvbV9hbmFseXplX3NlbnNlX2RhdGEoaWRlX2RyaXZlX3QgKmRyaXZlLAoJCQkgICAgICBzdHJ1Y3QgcmVxdWVzdCAqZmFpbGVkX2NvbW1hbmQsCgkJCSAgICAgIHN0cnVjdCByZXF1ZXN0X3NlbnNlICpzZW5zZSkKewoJaWYgKCFjZHJvbV9sb2dfc2Vuc2UoZHJpdmUsIGZhaWxlZF9jb21tYW5kLCBzZW5zZSkpCgkJcmV0dXJuOwoKCS8qCgkgKiBJZiBhIHJlYWQgdG9jIGlzIGV4ZWN1dGVkIGZvciBhIENELVIgb3IgQ0QtUlcgbWVkaXVtIHdoZXJlCgkgKiB0aGUgZmlyc3QgdG9jIGhhcyBub3QgYmVlbiByZWNvcmRlZCB5ZXQsIGl0IHdpbGwgZmFpbCB3aXRoCgkgKiAwNS8yNC8wMCAod2hpY2ggaXMgYSBjb25mdXNpbmcgZXJyb3IpCgkgKi8KCWlmIChmYWlsZWRfY29tbWFuZCAmJiBmYWlsZWRfY29tbWFuZC0+Y21kWzBdID09IEdQQ01EX1JFQURfVE9DX1BNQV9BVElQKQoJCWlmIChzZW5zZS0+c2Vuc2Vfa2V5ID09IDB4MDUgJiYgc2Vuc2UtPmFzYyA9PSAweDI0KQoJCQlyZXR1cm47CgojaWYgVkVSQk9TRV9JREVfQ0RfRVJST1JTCgl7CgkJaW50IGk7CgkJY29uc3QgY2hhciAqczsKCQljaGFyIGJ1Zls4MF07CgoJCXByaW50ayAoIkFUQVBJIGRldmljZSAlczpcbiIsIGRyaXZlLT5uYW1lKTsKCQlpZiAoc2Vuc2UtPmVycm9yX2NvZGU9PTB4NzApCgkJCXByaW50aygiICBFcnJvcjogIik7CgkJZWxzZSBpZiAoc2Vuc2UtPmVycm9yX2NvZGU9PTB4NzEpCgkJCXByaW50aygiICBEZWZlcnJlZCBFcnJvcjogIik7CgkJZWxzZSBpZiAoc2Vuc2UtPmVycm9yX2NvZGUgPT0gMHg3ZikKCQkJcHJpbnRrKCIgIFZlbmRvci1zcGVjaWZpYyBFcnJvcjogIik7CgkJZWxzZQoJCQlwcmludGsoIiAgVW5rbm93biBFcnJvciBUeXBlOiAiKTsKCgkJaWYgKHNlbnNlLT5zZW5zZV9rZXkgPCBBUllfTEVOKHNlbnNlX2tleV90ZXh0cykpCgkJCXMgPSBzZW5zZV9rZXlfdGV4dHNbc2Vuc2UtPnNlbnNlX2tleV07CgkJZWxzZQoJCQlzID0gImJhZCBzZW5zZSBrZXkhIjsKCgkJcHJpbnRrKCIlcyAtLSAoU2Vuc2Uga2V5PTB4JTAyeClcbiIsIHMsIHNlbnNlLT5zZW5zZV9rZXkpOwoKCQlpZiAoc2Vuc2UtPmFzYyA9PSAweDQwKSB7CgkJCXNwcmludGYoYnVmLCAiRGlhZ25vc3RpYyBmYWlsdXJlIG9uIGNvbXBvbmVudCAweCUwMngiLAoJCQkJIHNlbnNlLT5hc2NxKTsKCQkJcyA9IGJ1ZjsKCQl9IGVsc2UgewoJCQlpbnQgbG8gPSAwLCBtaWQsIGhpID0gQVJZX0xFTihzZW5zZV9kYXRhX3RleHRzKTsKCQkJdW5zaWduZWQgbG9uZyBrZXkgPSAoc2Vuc2UtPnNlbnNlX2tleSA8PCAxNik7CgkJCWtleSB8PSAoc2Vuc2UtPmFzYyA8PCA4KTsKCQkJaWYgKCEoc2Vuc2UtPmFzY3EgPj0gMHg4MCAmJiBzZW5zZS0+YXNjcSA8PSAweGRkKSkKCQkJCWtleSB8PSBzZW5zZS0+YXNjcTsKCQkJcyA9IE5VTEw7CgoJCQl3aGlsZSAoaGkgPiBsbykgewoJCQkJbWlkID0gKGxvICsgaGkpIC8gMjsKCQkJCWlmIChzZW5zZV9kYXRhX3RleHRzW21pZF0uYXNjX2FzY3EgPT0ga2V5IHx8CgkJCQkgICAgc2Vuc2VfZGF0YV90ZXh0c1ttaWRdLmFzY19hc2NxID09ICgweGZmMDAwMHxrZXkpKSB7CgkJCQkJcyA9IHNlbnNlX2RhdGFfdGV4dHNbbWlkXS50ZXh0OwoJCQkJCWJyZWFrOwoJCQkJfQoJCQkJZWxzZSBpZiAoc2Vuc2VfZGF0YV90ZXh0c1ttaWRdLmFzY19hc2NxID4ga2V5KQoJCQkJCWhpID0gbWlkOwoJCQkJZWxzZQoJCQkJCWxvID0gbWlkKzE7CgkJCX0KCQl9CgoJCWlmIChzID09IE5VTEwpIHsKCQkJaWYgKHNlbnNlLT5hc2MgPiAweDgwKQoJCQkJcyA9ICIodmVuZG9yLXNwZWNpZmljIGVycm9yKSI7CgkJCWVsc2UKCQkJCXMgPSAiKHJlc2VydmVkIGVycm9yIGNvZGUpIjsKCQl9CgoJCXByaW50ayhLRVJOX0VSUiAiICAlcyAtLSAoYXNjPTB4JTAyeCwgYXNjcT0weCUwMngpXG4iLAoJCQlzLCBzZW5zZS0+YXNjLCBzZW5zZS0+YXNjcSk7CgoJCWlmIChmYWlsZWRfY29tbWFuZCAhPSBOVUxMKSB7CgoJCQlpbnQgbG89MCwgbWlkLCBoaT0gQVJZX0xFTiAocGFja2V0X2NvbW1hbmRfdGV4dHMpOwoJCQlzID0gTlVMTDsKCgkJCXdoaWxlIChoaSA+IGxvKSB7CgkJCQltaWQgPSAobG8gKyBoaSkgLyAyOwoJCQkJaWYgKHBhY2tldF9jb21tYW5kX3RleHRzW21pZF0ucGFja2V0X2NvbW1hbmQgPT0KCQkJCSAgICBmYWlsZWRfY29tbWFuZC0+Y21kWzBdKSB7CgkJCQkJcyA9IHBhY2tldF9jb21tYW5kX3RleHRzW21pZF0udGV4dDsKCQkJCQlicmVhazsKCQkJCX0KCQkJCWlmIChwYWNrZXRfY29tbWFuZF90ZXh0c1ttaWRdLnBhY2tldF9jb21tYW5kID4KCQkJCSAgICBmYWlsZWRfY29tbWFuZC0+Y21kWzBdKQoJCQkJCWhpID0gbWlkOwoJCQkJZWxzZQoJCQkJCWxvID0gbWlkKzE7CgkJCX0KCgkJCXByaW50ayAoS0VSTl9FUlIgIiAgVGhlIGZhaWxlZCBcIiVzXCIgcGFja2V0IGNvbW1hbmQgd2FzOiBcbiAgXCIiLCBzKTsKCQkJZm9yIChpPTA7IGk8c2l6ZW9mIChmYWlsZWRfY29tbWFuZC0+Y21kKTsgaSsrKQoJCQkJcHJpbnRrICgiJTAyeCAiLCBmYWlsZWRfY29tbWFuZC0+Y21kW2ldKTsKCQkJcHJpbnRrICgiXCJcbiIpOwoJCX0KCgkJLyogVGhlIFNLU1YgYml0IHNwZWNpZmllcyB2YWxpZGl0eSBvZiB0aGUgc2Vuc2Vfa2V5X3NwZWNpZmljCgkJICogaW4gdGhlIG5leHQgdHdvIGNvbW1hbmRzLiBJdCBpcyBiaXQgNyBvZiB0aGUgZmlyc3QgYnl0ZS4KCQkgKiBJbiB0aGUgY2FzZSBvZiBOT1RfUkVBRFksIGlmIFNLU1YgaXMgc2V0IHRoZSBkcml2ZSBjYW4KCQkgKiBnaXZlIHVzIG5pY2UgRVRBIHJlYWRpbmdzLgoJCSAqLwoJCWlmIChzZW5zZS0+c2Vuc2Vfa2V5ID09IE5PVF9SRUFEWSAmJiAoc2Vuc2UtPnNrc1swXSAmIDB4ODApKSB7CgkJCWludCBwcm9ncmVzcyA9IChzZW5zZS0+c2tzWzFdIDw8IDggfCBzZW5zZS0+c2tzWzJdKSAqIDEwMDsKCQkJcHJpbnRrKEtFUk5fRVJSICIgIENvbW1hbmQgaXMgJTAyZCUlIGNvbXBsZXRlXG4iLCBwcm9ncmVzcyAvIDB4ZmZmZik7CgoJCX0KCgkJaWYgKHNlbnNlLT5zZW5zZV9rZXkgPT0gSUxMRUdBTF9SRVFVRVNUICYmCgkJICAgIChzZW5zZS0+c2tzWzBdICYgMHg4MCkgIT0gMCkgewoJCQlwcmludGsoS0VSTl9FUlIgIiAgRXJyb3IgaW4gJXMgYnl0ZSAlZCIsCgkJCQkoc2Vuc2UtPnNrc1swXSAmIDB4NDApICE9IDAgPwoJCQkJImNvbW1hbmQgcGFja2V0IiA6ICJjb21tYW5kIGRhdGEiLAoJCQkJKHNlbnNlLT5za3NbMV0gPDwgOCkgKyBzZW5zZS0+c2tzWzJdKTsKCgkJCWlmICgoc2Vuc2UtPnNrc1swXSAmIDB4NDApICE9IDApCgkJCQlwcmludGsgKCIgYml0ICVkIiwgc2Vuc2UtPnNrc1swXSAmIDB4MDcpOwoKCQkJcHJpbnRrICgiXG4iKTsKCQl9Cgl9CgojZWxzZSAvKiBub3QgVkVSQk9TRV9JREVfQ0RfRVJST1JTICovCgoJLyogU3VwcHJlc3MgcHJpbnRpbmcgdW5pdCBhdHRlbnRpb24gYW5kIGBpbiBwcm9ncmVzcyBvZiBiZWNvbWluZyByZWFkeScKCSAgIGVycm9ycyB3aGVuIHdlJ3JlIG5vdCBiZWluZyB2ZXJib3NlLiAqLwoKCWlmIChzZW5zZS0+c2Vuc2Vfa2V5ID09IFVOSVRfQVRURU5USU9OIHx8CgkgICAgKHNlbnNlLT5zZW5zZV9rZXkgPT0gTk9UX1JFQURZICYmIChzZW5zZS0+YXNjID09IDQgfHwKCQkJCQkJc2Vuc2UtPmFzYyA9PSAweDNhKSkpCgkJcmV0dXJuOwoKCXByaW50ayhLRVJOX0VSUiAiJXM6IGVycm9yIGNvZGU6IDB4JTAyeCAgc2Vuc2Vfa2V5OiAweCUwMnggIGFzYzogMHglMDJ4ICBhc2NxOiAweCUwMnhcbiIsCgkJZHJpdmUtPm5hbWUsCgkJc2Vuc2UtPmVycm9yX2NvZGUsIHNlbnNlLT5zZW5zZV9rZXksCgkJc2Vuc2UtPmFzYywgc2Vuc2UtPmFzY3EpOwojZW5kaWYgLyogbm90IFZFUkJPU0VfSURFX0NEX0VSUk9SUyAqLwp9CgovKgogKiBJbml0aWFsaXplIGEgaWRlLWNkIHBhY2tldCBjb21tYW5kIHJlcXVlc3QKICovCnN0YXRpYyB2b2lkIGNkcm9tX3ByZXBhcmVfcmVxdWVzdChpZGVfZHJpdmVfdCAqZHJpdmUsIHN0cnVjdCByZXF1ZXN0ICpycSkKewoJc3RydWN0IGNkcm9tX2luZm8gKmNkID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoKCWlkZV9pbml0X2RyaXZlX2NtZChycSk7CglycS0+ZmxhZ3MgPSBSRVFfUEM7CglycS0+cnFfZGlzayA9IGNkLT5kaXNrOwp9CgpzdGF0aWMgdm9pZCBjZHJvbV9xdWV1ZV9yZXF1ZXN0X3NlbnNlKGlkZV9kcml2ZV90ICpkcml2ZSwgdm9pZCAqc2Vuc2UsCgkJCQkgICAgICBzdHJ1Y3QgcmVxdWVzdCAqZmFpbGVkX2NvbW1hbmQpCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvCQk9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXN0cnVjdCByZXF1ZXN0ICpycQkJPSAmaW5mby0+cmVxdWVzdF9zZW5zZV9yZXF1ZXN0OwoKCWlmIChzZW5zZSA9PSBOVUxMKQoJCXNlbnNlID0gJmluZm8tPnNlbnNlX2RhdGE7CgoJLyogc3R1ZmYgdGhlIHNlbnNlIHJlcXVlc3QgaW4gZnJvbnQgb2Ygb3VyIGN1cnJlbnQgcmVxdWVzdCAqLwoJY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGRyaXZlLCBycSk7CgoJcnEtPmRhdGEgPSBzZW5zZTsKCXJxLT5jbWRbMF0gPSBHUENNRF9SRVFVRVNUX1NFTlNFOwoJcnEtPmNtZFs0XSA9IHJxLT5kYXRhX2xlbiA9IDE4OwoKCXJxLT5mbGFncyA9IFJFUV9TRU5TRTsKCgkvKiBOT1RFISBTYXZlIHRoZSBmYWlsZWQgY29tbWFuZCBpbiAicnEtPmJ1ZmZlciIgKi8KCXJxLT5idWZmZXIgPSAodm9pZCAqKSBmYWlsZWRfY29tbWFuZDsKCgkodm9pZCkgaWRlX2RvX2RyaXZlX2NtZChkcml2ZSwgcnEsIGlkZV9wcmVlbXB0KTsKfQoKc3RhdGljIHZvaWQgY2Ryb21fZW5kX3JlcXVlc3QgKGlkZV9kcml2ZV90ICpkcml2ZSwgaW50IHVwdG9kYXRlKQp7CglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7CglpbnQgbnNlY3RvcnMgPSBycS0+aGFyZF9jdXJfc2VjdG9yczsKCglpZiAoKHJxLT5mbGFncyAmIFJFUV9TRU5TRSkgJiYgdXB0b2RhdGUpIHsKCQkvKgoJCSAqIEZvciBSRVFfU0VOU0UsICJycS0+YnVmZmVyIiBwb2ludHMgdG8gdGhlIG9yaWdpbmFsIGZhaWxlZAoJCSAqIHJlcXVlc3QKCQkgKi8KCQlzdHJ1Y3QgcmVxdWVzdCAqZmFpbGVkID0gKHN0cnVjdCByZXF1ZXN0ICopIHJxLT5idWZmZXI7CgkJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CgkJdm9pZCAqc2Vuc2UgPSAmaW5mby0+c2Vuc2VfZGF0YTsKCQl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCQlpZiAoZmFpbGVkKSB7CgkJCWlmIChmYWlsZWQtPnNlbnNlKSB7CgkJCQlzZW5zZSA9IGZhaWxlZC0+c2Vuc2U7CgkJCQlmYWlsZWQtPnNlbnNlX2xlbiA9IHJxLT5zZW5zZV9sZW47CgkJCX0KCgkJCS8qCgkJCSAqIG5vdyBlbmQgZmFpbGVkIHJlcXVlc3QKCQkJICovCgkJCXNwaW5fbG9ja19pcnFzYXZlKCZpZGVfbG9jaywgZmxhZ3MpOwoJCQllbmRfdGhhdF9yZXF1ZXN0X2NodW5rKGZhaWxlZCwgMCwgZmFpbGVkLT5kYXRhX2xlbik7CgkJCWVuZF90aGF0X3JlcXVlc3RfbGFzdChmYWlsZWQpOwoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZpZGVfbG9jaywgZmxhZ3MpOwoJCX0KCgkJY2Ryb21fYW5hbHl6ZV9zZW5zZV9kYXRhKGRyaXZlLCBmYWlsZWQsIHNlbnNlKTsKCX0KCglpZiAoIXJxLT5jdXJyZW50X25yX3NlY3RvcnMgJiYgYmxrX2ZzX3JlcXVlc3QocnEpKQoJCXVwdG9kYXRlID0gMTsKCS8qIG1ha2Ugc3VyZSBpdCdzIGZ1bGx5IGVuZGVkICovCglpZiAoYmxrX3BjX3JlcXVlc3QocnEpKQoJCW5zZWN0b3JzID0gKHJxLT5kYXRhX2xlbiArIDUxMSkgPj4gOTsKCWlmICghbnNlY3RvcnMpCgkJbnNlY3RvcnMgPSAxOwoKCWlkZV9lbmRfcmVxdWVzdChkcml2ZSwgdXB0b2RhdGUsIG5zZWN0b3JzKTsKfQoKLyogUmV0dXJucyAwIGlmIHRoZSByZXF1ZXN0IHNob3VsZCBiZSBjb250aW51ZWQuCiAgIFJldHVybnMgMSBpZiB0aGUgcmVxdWVzdCB3YXMgZW5kZWQuICovCnN0YXRpYyBpbnQgY2Ryb21fZGVjb2RlX3N0YXR1cyhpZGVfZHJpdmVfdCAqZHJpdmUsIGludCBnb29kX3N0YXQsIGludCAqc3RhdF9yZXQpCnsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCWludCBzdGF0LCBlcnIsIHNlbnNlX2tleTsKCQoJLyogQ2hlY2sgZm9yIGVycm9ycy4gKi8KCXN0YXQgPSBIV0lGKGRyaXZlKS0+SU5CKElERV9TVEFUVVNfUkVHKTsKCWlmIChzdGF0X3JldCkKCQkqc3RhdF9yZXQgPSBzdGF0OwoKCWlmIChPS19TVEFUKHN0YXQsIGdvb2Rfc3RhdCwgQkFEX1JfU1RBVCkpCgkJcmV0dXJuIDA7CgoJLyogR2V0IHRoZSBJREUgZXJyb3IgcmVnaXN0ZXIuICovCgllcnIgPSBIV0lGKGRyaXZlKS0+SU5CKElERV9FUlJPUl9SRUcpOwoJc2Vuc2Vfa2V5ID0gZXJyID4+IDQ7CgoJaWYgKHJxID09IE5VTEwpIHsKCQlwcmludGsoIiVzOiBtaXNzaW5nIHJxIGluIGNkcm9tX2RlY29kZV9zdGF0dXNcbiIsIGRyaXZlLT5uYW1lKTsKCQlyZXR1cm4gMTsKCX0KCglpZiAocnEtPmZsYWdzICYgUkVRX1NFTlNFKSB7CgkJLyogV2UgZ290IGFuIGVycm9yIHRyeWluZyB0byBnZXQgc2Vuc2UgaW5mbwoJCSAgIGZyb20gdGhlIGRyaXZlIChwcm9iYWJseSB3aGlsZSB0cnlpbmcKCQkgICB0byByZWNvdmVyIGZyb20gYSBmb3JtZXIgZXJyb3IpLiAgSnVzdCBnaXZlIHVwLiAqLwoKCQlycS0+ZmxhZ3MgfD0gUkVRX0ZBSUxFRDsKCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7CgkJaWRlX2Vycm9yKGRyaXZlLCAicmVxdWVzdCBzZW5zZSBmYWlsdXJlIiwgc3RhdCk7CgkJcmV0dXJuIDE7CgoJfSBlbHNlIGlmIChycS0+ZmxhZ3MgJiAoUkVRX1BDIHwgUkVRX0JMT0NLX1BDKSkgewoJCS8qIEFsbCBvdGhlciBmdW5jdGlvbnMsIGV4Y2VwdCBmb3IgUkVBRC4gKi8KCQl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCQkvKgoJCSAqIGlmIHdlIGhhdmUgYW4gZXJyb3IsIHBhc3MgYmFjayBDSEVDS19DT05ESVRJT04gYXMgdGhlCgkJICogc2NzaSBzdGF0dXMgYnl0ZQoJCSAqLwoJCWlmICgocnEtPmZsYWdzICYgUkVRX0JMT0NLX1BDKSAmJiAhcnEtPmVycm9ycykKCQkJcnEtPmVycm9ycyA9IFNBTV9TVEFUX0NIRUNLX0NPTkRJVElPTjsKCgkJLyogQ2hlY2sgZm9yIHRyYXkgb3Blbi4gKi8KCQlpZiAoc2Vuc2Vfa2V5ID09IE5PVF9SRUFEWSkgewoJCQljZHJvbV9zYXdfbWVkaWFfY2hhbmdlIChkcml2ZSk7CgkJfSBlbHNlIGlmIChzZW5zZV9rZXkgPT0gVU5JVF9BVFRFTlRJT04pIHsKCQkJLyogQ2hlY2sgZm9yIG1lZGlhIGNoYW5nZS4gKi8KCQkJY2Ryb21fc2F3X21lZGlhX2NoYW5nZSAoZHJpdmUpOwoJCQkvKnByaW50aygiJXM6IG1lZGlhIGNoYW5nZWRcbiIsZHJpdmUtPm5hbWUpOyovCgkJCXJldHVybiAwOwoJCX0gZWxzZSBpZiAoIShycS0+ZmxhZ3MgJiBSRVFfUVVJRVQpKSB7CgkJCS8qIE90aGVyd2lzZSwgcHJpbnQgYW4gZXJyb3IuICovCgkJCWlkZV9kdW1wX3N0YXR1cyhkcml2ZSwgInBhY2tldCBjb21tYW5kIGVycm9yIiwgc3RhdCk7CgkJfQoJCQoJCXJxLT5mbGFncyB8PSBSRVFfRkFJTEVEOwoKCQkvKgoJCSAqIGluc3RlYWQgb2YgcGxheWluZyBnYW1lcyB3aXRoIG1vdmluZyBjb21wbGV0aW9ucyBhcm91bmQsCgkJICogcmVtb3ZlIGZhaWxlZCByZXF1ZXN0IGNvbXBsZXRlbHkgYW5kIGVuZCBpdCB3aGVuIHRoZQoJCSAqIHJlcXVlc3Qgc2Vuc2UgaGFzIGNvbXBsZXRlZAoJCSAqLwoJCWlmIChzdGF0ICYgRVJSX1NUQVQpIHsKCQkJc3Bpbl9sb2NrX2lycXNhdmUoJmlkZV9sb2NrLCBmbGFncyk7CgkJCWJsa2Rldl9kZXF1ZXVlX3JlcXVlc3QocnEpOwoJCQlIV0dST1VQKGRyaXZlKS0+cnEgPSBOVUxMOwoJCQlzcGluX3VubG9ja19pcnFyZXN0b3JlKCZpZGVfbG9jaywgZmxhZ3MpOwoKCQkJY2Ryb21fcXVldWVfcmVxdWVzdF9zZW5zZShkcml2ZSwgcnEtPnNlbnNlLCBycSk7CgkJfSBlbHNlCgkJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAwKTsKCgl9IGVsc2UgaWYgKGJsa19mc19yZXF1ZXN0KHJxKSkgewoJCWludCBkb19lbmRfcmVxdWVzdCA9IDA7CgoJCS8qIEhhbmRsZSBlcnJvcnMgZnJvbSBSRUFEIGFuZCBXUklURSByZXF1ZXN0cy4gKi8KCgkJaWYgKGJsa19ub3JldHJ5X3JlcXVlc3QocnEpKQoJCQlkb19lbmRfcmVxdWVzdCA9IDE7CgoJCWlmIChzZW5zZV9rZXkgPT0gTk9UX1JFQURZKSB7CgkJCS8qIFRyYXkgb3Blbi4gKi8KCQkJaWYgKHJxX2RhdGFfZGlyKHJxKSA9PSBSRUFEKSB7CgkJCQljZHJvbV9zYXdfbWVkaWFfY2hhbmdlIChkcml2ZSk7CgoJCQkJLyogRmFpbCB0aGUgcmVxdWVzdC4gKi8KCQkJCXByaW50ayAoIiVzOiB0cmF5IG9wZW5cbiIsIGRyaXZlLT5uYW1lKTsKCQkJCWRvX2VuZF9yZXF1ZXN0ID0gMTsKCQkJfSBlbHNlIHsKCQkJCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoKCQkJCS8qIGFsbG93IHRoZSBkcml2ZSA1IHNlY29uZHMgdG8gcmVjb3Zlciwgc29tZQoJCQkJICogZGV2aWNlcyB3aWxsIHJldHVybiB0aGlzIGVycm9yIHdoaWxlIGZsdXNoaW5nCgkJCQkgKiBkYXRhIGZyb20gY2FjaGUgKi8KCQkJCWlmICghcnEtPmVycm9ycykKCQkJCQlpbmZvLT53cml0ZV90aW1lb3V0ID0gamlmZmllcyArIEFUQVBJX1dBSVRfV1JJVEVfQlVTWTsKCQkJCXJxLT5lcnJvcnMgPSAxOwoJCQkJaWYgKHRpbWVfYWZ0ZXIoamlmZmllcywgaW5mby0+d3JpdGVfdGltZW91dCkpCgkJCQkJZG9fZW5kX3JlcXVlc3QgPSAxOwoJCQkJZWxzZSB7CgkJCQkJdW5zaWduZWQgbG9uZyBmbGFnczsKCgkJCQkJLyoKCQkJCQkgKiB0YWtlIGEgYnJlYXRoZXIgcmVseWluZyBvbiB0aGUKCQkJCQkgKiB1bnBsdWcgdGltZXIgdG8ga2ljayB1cyBhZ2FpbgoJCQkJCSAqLwoJCQkJCXNwaW5fbG9ja19pcnFzYXZlKCZpZGVfbG9jaywgZmxhZ3MpOwoJCQkJCWJsa19wbHVnX2RldmljZShkcml2ZS0+cXVldWUpOwoJCQkJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmlkZV9sb2NrLGZsYWdzKTsKCQkJCQlyZXR1cm4gMTsKCQkJCX0KCQkJfQoJCX0gZWxzZSBpZiAoc2Vuc2Vfa2V5ID09IFVOSVRfQVRURU5USU9OKSB7CgkJCS8qIE1lZGlhIGNoYW5nZS4gKi8KCQkJY2Ryb21fc2F3X21lZGlhX2NoYW5nZSAoZHJpdmUpOwoKCQkJLyogQXJyYW5nZSB0byByZXRyeSB0aGUgcmVxdWVzdC4KCQkJICAgQnV0IGJlIHN1cmUgdG8gZ2l2ZSB1cCBpZiB3ZSd2ZSByZXRyaWVkCgkJCSAgIHRvbyBtYW55IHRpbWVzLiAqLwoJCQlpZiAoKytycS0+ZXJyb3JzID4gRVJST1JfTUFYKQoJCQkJZG9fZW5kX3JlcXVlc3QgPSAxOwoJCX0gZWxzZSBpZiAoc2Vuc2Vfa2V5ID09IElMTEVHQUxfUkVRVUVTVCB8fAoJCQkgICBzZW5zZV9rZXkgPT0gREFUQV9QUk9URUNUKSB7CgkJCS8qIE5vIHBvaW50IGluIHJldHJ5aW5nIGFmdGVyIGFuIGlsbGVnYWwKCQkJICAgcmVxdWVzdCBvciBkYXRhIHByb3RlY3QgZXJyb3IuKi8KCQkJaWRlX2R1bXBfc3RhdHVzIChkcml2ZSwgImNvbW1hbmQgZXJyb3IiLCBzdGF0KTsKCQkJZG9fZW5kX3JlcXVlc3QgPSAxOwoJCX0gZWxzZSBpZiAoc2Vuc2Vfa2V5ID09IE1FRElVTV9FUlJPUikgewoJCQkvKiBObyBwb2ludCBpbiByZS10cnlpbmcgYSB6aWxsaW9uIHRpbWVzIG9uIGEgYmFkIAoJCQkgKiBzZWN0b3IuLi4gIElmIHdlIGdvdCBoZXJlIHRoZSBlcnJvciBpcyBub3QgY29ycmVjdGFibGUgKi8KCQkJaWRlX2R1bXBfc3RhdHVzIChkcml2ZSwgIm1lZGlhIGVycm9yIChiYWQgc2VjdG9yKSIsIHN0YXQpOwoJCQlkb19lbmRfcmVxdWVzdCA9IDE7CgkJfSBlbHNlIGlmIChzZW5zZV9rZXkgPT0gQkxBTktfQ0hFQ0spIHsKCQkJLyogRGlzayBhcHBlYXJzIGJsYW5rID8/ICovCgkJCWlkZV9kdW1wX3N0YXR1cyAoZHJpdmUsICJtZWRpYSBlcnJvciAoYmxhbmspIiwgc3RhdCk7CgkJCWRvX2VuZF9yZXF1ZXN0ID0gMTsKCQl9IGVsc2UgaWYgKChlcnIgJiB+QUJSVF9FUlIpICE9IDApIHsKCQkJLyogR28gdG8gdGhlIGRlZmF1bHQgaGFuZGxlcgoJCQkgICBmb3Igb3RoZXIgZXJyb3JzLiAqLwoJCQlpZGVfZXJyb3IoZHJpdmUsICJjZHJvbV9kZWNvZGVfc3RhdHVzIiwgc3RhdCk7CgkJCXJldHVybiAxOwoJCX0gZWxzZSBpZiAoKCsrcnEtPmVycm9ycyA+IEVSUk9SX01BWCkpIHsKCQkJLyogV2UndmUgcmFja2VkIHVwIHRvbyBtYW55IHJldHJpZXMuICBBYm9ydC4gKi8KCQkJZG9fZW5kX3JlcXVlc3QgPSAxOwoJCX0KCgkJaWYgKGRvX2VuZF9yZXF1ZXN0KQoJCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7CgoJCS8qIElmIHdlIGdvdCBhIENIRUNLX0NPTkRJVElPTiBzdGF0dXMsCgkJICAgcXVldWUgYSByZXF1ZXN0IHNlbnNlIGNvbW1hbmQuICovCgkJaWYgKChzdGF0ICYgRVJSX1NUQVQpICE9IDApCgkJCWNkcm9tX3F1ZXVlX3JlcXVlc3Rfc2Vuc2UoZHJpdmUsIE5VTEwsIE5VTEwpOwoJfSBlbHNlIHsKCQlibGtfZHVtcF9ycV9mbGFncyhycSwgImlkZS1jZDogYmFkIHJxIik7CgkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDApOwoJfQoKCS8qIFJldHJ5LCBvciBoYW5kbGUgdGhlIG5leHQgcmVxdWVzdC4gKi8KCXJldHVybiAxOwp9CgpzdGF0aWMgaW50IGNkcm9tX3RpbWVyX2V4cGlyeShpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCXVuc2lnbmVkIGxvbmcgd2FpdCA9IDA7CgoJLyoKCSAqIFNvbWUgY29tbWFuZHMgYXJlICpzbG93KiBhbmQgbm9ybWFsbHkgdGFrZSBhIGxvbmcgdGltZSB0bwoJICogY29tcGxldGUuIFVzdWFsbHkgd2UgY2FuIHVzZSB0aGUgQVRBUEkgImRpc2Nvbm5lY3QiIHRvIGJ5cGFzcwoJICogdGhpcywgYnV0IG5vdCBhbGwgY29tbWFuZHMvZHJpdmVzIHN1cHBvcnQgdGhhdC4gTGV0CgkgKiBpZGVfdGltZXJfZXhwaXJ5IGtlZXAgcG9sbGluZyB1cyBmb3IgdGhlc2UuCgkgKi8KCXN3aXRjaCAocnEtPmNtZFswXSkgewoJCWNhc2UgR1BDTURfQkxBTks6CgkJY2FzZSBHUENNRF9GT1JNQVRfVU5JVDoKCQljYXNlIEdQQ01EX1JFU0VSVkVfUlpPTkVfVFJBQ0s6CgkJY2FzZSBHUENNRF9DTE9TRV9UUkFDSzoKCQljYXNlIEdQQ01EX0ZMVVNIX0NBQ0hFOgoJCQl3YWl0ID0gQVRBUElfV0FJVF9QQzsKCQkJYnJlYWs7CgkJZGVmYXVsdDoKCQkJaWYgKCEocnEtPmZsYWdzICYgUkVRX1FVSUVUKSkKCQkJCXByaW50ayhLRVJOX0lORk8gImlkZS1jZDogY21kIDB4JXggdGltZWQgb3V0XG4iLCBycS0+Y21kWzBdKTsKCQkJd2FpdCA9IDA7CgkJCWJyZWFrOwoJfQoJcmV0dXJuIHdhaXQ7Cn0KCi8qIFNldCB1cCB0aGUgZGV2aWNlIHJlZ2lzdGVycyBmb3IgdHJhbnNmZXJyaW5nIGEgcGFja2V0IGNvbW1hbmQgb24gREVWLAogICBleHBlY3RpbmcgdG8gbGF0ZXIgdHJhbnNmZXIgWEZFUkxFTiBieXRlcy4gIEhBTkRMRVIgaXMgdGhlIHJvdXRpbmUKICAgd2hpY2ggYWN0dWFsbHkgdHJhbnNmZXJzIHRoZSBjb21tYW5kIHRvIHRoZSBkcml2ZS4gIElmIHRoaXMgaXMgYQogICBkcnFfaW50ZXJydXB0IGRldmljZSwgdGhpcyByb3V0aW5lIHdpbGwgYXJyYW5nZSBmb3IgSEFORExFUiB0byBiZQogICBjYWxsZWQgd2hlbiB0aGUgaW50ZXJydXB0IGZyb20gdGhlIGRyaXZlIGFycml2ZXMuICBPdGhlcndpc2UsIEhBTkRMRVIKICAgd2lsbCBiZSBjYWxsZWQgaW1tZWRpYXRlbHkgYWZ0ZXIgdGhlIGRyaXZlIGlzIHByZXBhcmVkIGZvciB0aGUgdHJhbnNmZXIuICovCgpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX3N0YXJ0X3BhY2tldF9jb21tYW5kKGlkZV9kcml2ZV90ICpkcml2ZSwKCQkJCQkJICBpbnQgeGZlcmxlbiwKCQkJCQkJICBpZGVfaGFuZGxlcl90ICpoYW5kbGVyKQp7CglpZGVfc3RhcnRzdG9wX3Qgc3RhcnRzdG9wOwoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglpZGVfaHdpZl90ICpod2lmID0gZHJpdmUtPmh3aWY7CgoJLyogV2FpdCBmb3IgdGhlIGNvbnRyb2xsZXIgdG8gYmUgaWRsZS4gKi8KCWlmIChpZGVfd2FpdF9zdGF0KCZzdGFydHN0b3AsIGRyaXZlLCAwLCBCVVNZX1NUQVQsIFdBSVRfUkVBRFkpKQoJCXJldHVybiBzdGFydHN0b3A7CgoJaWYgKGluZm8tPmRtYSkKCQlpbmZvLT5kbWEgPSAhaHdpZi0+ZG1hX3NldHVwKGRyaXZlKTsKCgkvKiBTZXQgdXAgdGhlIGNvbnRyb2xsZXIgcmVnaXN0ZXJzLiAqLwoJLyogRklYTUU6IGZvciBWaXJ0dWFsIERNQSB3ZSBtdXN0IGNoZWNrIGhhcmRlciAqLwoJSFdJRihkcml2ZSktPk9VVEIoaW5mby0+ZG1hLCBJREVfRkVBVFVSRV9SRUcpOwoJSFdJRihkcml2ZSktPk9VVEIoMCwgSURFX0lSRUFTT05fUkVHKTsKCUhXSUYoZHJpdmUpLT5PVVRCKDAsIElERV9TRUNUT1JfUkVHKTsKCglIV0lGKGRyaXZlKS0+T1VUQih4ZmVybGVuICYgMHhmZiwgSURFX0JDT1VOVExfUkVHKTsKCUhXSUYoZHJpdmUpLT5PVVRCKHhmZXJsZW4gPj4gOCAgLCBJREVfQkNPVU5USF9SRUcpOwoJaWYgKElERV9DT05UUk9MX1JFRykKCQlIV0lGKGRyaXZlKS0+T1VUQihkcml2ZS0+Y3RsLCBJREVfQ09OVFJPTF9SRUcpOwogCglpZiAoQ0RST01fQ09ORklHX0ZMQUdTIChkcml2ZSktPmRycV9pbnRlcnJ1cHQpIHsKCQkvKiBwYWNrZXQgY29tbWFuZCAqLwoJCWlkZV9leGVjdXRlX2NvbW1hbmQoZHJpdmUsIFdJTl9QQUNLRVRDTUQsIGhhbmRsZXIsIEFUQVBJX1dBSVRfUEMsIGNkcm9tX3RpbWVyX2V4cGlyeSk7CgkJcmV0dXJuIGlkZV9zdGFydGVkOwoJfSBlbHNlIHsKCQl1bnNpZ25lZCBsb25nIGZsYWdzOwoKCQkvKiBwYWNrZXQgY29tbWFuZCAqLwoJCXNwaW5fbG9ja19pcnFzYXZlKCZpZGVfbG9jaywgZmxhZ3MpOwoJCWh3aWYtPk9VVEJTWU5DKGRyaXZlLCBXSU5fUEFDS0VUQ01ELCBJREVfQ09NTUFORF9SRUcpOwoJCW5kZWxheSg0MDApOwoJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJmlkZV9sb2NrLCBmbGFncyk7CgoJCXJldHVybiAoKmhhbmRsZXIpIChkcml2ZSk7Cgl9Cn0KCi8qIFNlbmQgYSBwYWNrZXQgY29tbWFuZCB0byBEUklWRSBkZXNjcmliZWQgYnkgQ01EX0JVRiBhbmQgQ01EX0xFTi4KICAgVGhlIGRldmljZSByZWdpc3RlcnMgbXVzdCBoYXZlIGFscmVhZHkgYmVlbiBwcmVwYXJlZAogICBieSBjZHJvbV9zdGFydF9wYWNrZXRfY29tbWFuZC4KICAgSEFORExFUiBpcyB0aGUgaW50ZXJydXB0IGhhbmRsZXIgdG8gY2FsbCB3aGVuIHRoZSBjb21tYW5kIGNvbXBsZXRlcwogICBvciB0aGVyZSdzIGRhdGEgcmVhZHkuICovCi8qCiAqIGNoYW5nZWQgNSBwYXJhbWV0ZXJzIHRvIDMgZm9yIGR2ZC1yYW0KICogc3RydWN0IHBhY2tldF9jb21tYW5kICpwYzsgbm93IHBhY2tldF9jb21tYW5kX3QgKnBjOwogKi8KI2RlZmluZSBBVEFQSV9NSU5fQ0RCX0JZVEVTIDEyCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fdHJhbnNmZXJfcGFja2V0X2NvbW1hbmQgKGlkZV9kcml2ZV90ICpkcml2ZSwKCQkJCQkgIHN0cnVjdCByZXF1ZXN0ICpycSwKCQkJCQkgIGlkZV9oYW5kbGVyX3QgKmhhbmRsZXIpCnsKCWlkZV9od2lmX3QgKmh3aWYgPSBkcml2ZS0+aHdpZjsKCWludCBjbWRfbGVuOwoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglpZGVfc3RhcnRzdG9wX3Qgc3RhcnRzdG9wOwoKCWlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5kcnFfaW50ZXJydXB0KSB7CgkJLyogSGVyZSB3ZSBzaG91bGQgaGF2ZSBiZWVuIGNhbGxlZCBhZnRlciByZWNlaXZpbmcgYW4gaW50ZXJydXB0CgkJICAgZnJvbSB0aGUgZGV2aWNlLiAgRFJRIHNob3VsZCBob3cgYmUgc2V0LiAqLwoKCQkvKiBDaGVjayBmb3IgZXJyb3JzLiAqLwoJCWlmIChjZHJvbV9kZWNvZGVfc3RhdHVzKGRyaXZlLCBEUlFfU1RBVCwgTlVMTCkpCgkJCXJldHVybiBpZGVfc3RvcHBlZDsKCX0gZWxzZSB7CgkJLyogT3RoZXJ3aXNlLCB3ZSBtdXN0IHdhaXQgZm9yIERSUSB0byBnZXQgc2V0LiAqLwoJCWlmIChpZGVfd2FpdF9zdGF0KCZzdGFydHN0b3AsIGRyaXZlLCBEUlFfU1RBVCwKCQkJCUJVU1lfU1RBVCwgV0FJVF9SRUFEWSkpCgkJCXJldHVybiBzdGFydHN0b3A7Cgl9CgoJLyogQXJtIHRoZSBpbnRlcnJ1cHQgaGFuZGxlci4gKi8KCWlkZV9zZXRfaGFuZGxlcihkcml2ZSwgaGFuZGxlciwgcnEtPnRpbWVvdXQsIGNkcm9tX3RpbWVyX2V4cGlyeSk7CgoJLyogQVRBUEkgY29tbWFuZHMgZ2V0IHBhZGRlZCBvdXQgdG8gMTIgYnl0ZXMgbWluaW11bSAqLwoJY21kX2xlbiA9IENPTU1BTkRfU0laRShycS0+Y21kWzBdKTsKCWlmIChjbWRfbGVuIDwgQVRBUElfTUlOX0NEQl9CWVRFUykKCQljbWRfbGVuID0gQVRBUElfTUlOX0NEQl9CWVRFUzsKCgkvKiBTZW5kIHRoZSBjb21tYW5kIHRvIHRoZSBkZXZpY2UuICovCglIV0lGKGRyaXZlKS0+YXRhcGlfb3V0cHV0X2J5dGVzKGRyaXZlLCBycS0+Y21kLCBjbWRfbGVuKTsKCgkvKiBTdGFydCB0aGUgRE1BIGlmIG5lZWQgYmUgKi8KCWlmIChpbmZvLT5kbWEpCgkJaHdpZi0+ZG1hX3N0YXJ0KGRyaXZlKTsKCglyZXR1cm4gaWRlX3N0YXJ0ZWQ7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEJsb2NrIHJlYWQgZnVuY3Rpb25zLgogKi8KCi8qCiAqIEJ1ZmZlciB1cCB0byBTRUNUT1JTX1RPX1RSQU5TRkVSIHNlY3RvcnMgZnJvbSB0aGUgZHJpdmUgaW4gb3VyIHNlY3RvcgogKiBidWZmZXIuICBPbmNlIHRoZSBmaXJzdCBzZWN0b3IgaXMgYWRkZWQsIGFueSBzdWJzZXF1ZW50IHNlY3RvcnMgYXJlCiAqIGFzc3VtZWQgdG8gYmUgY29udGludW91cyAodW50aWwgdGhlIGJ1ZmZlciBpcyBjbGVhcmVkKS4gIEZvciB0aGUgZmlyc3QKICogc2VjdG9yIGFkZGVkLCBTRUNUT1IgaXMgaXRzIHNlY3RvciBudW1iZXIuICAoU0VDVE9SIGlzIHRoZW4gaWdub3JlZCB1bnRpbAogKiB0aGUgYnVmZmVyIGlzIGNsZWFyZWQuKQogKi8Kc3RhdGljIHZvaWQgY2Ryb21fYnVmZmVyX3NlY3RvcnMgKGlkZV9kcml2ZV90ICpkcml2ZSwgdW5zaWduZWQgbG9uZyBzZWN0b3IsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbnQgc2VjdG9yc190b190cmFuc2ZlcikKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CgoJLyogTnVtYmVyIG9mIHNlY3RvcnMgdG8gcmVhZCBpbnRvIHRoZSBidWZmZXIuICovCglpbnQgc2VjdG9yc190b19idWZmZXIgPSBtaW5fdChpbnQsIHNlY3RvcnNfdG9fdHJhbnNmZXIsCgkJCQkgICAgIChTRUNUT1JfQlVGRkVSX1NJWkUgPj4gU0VDVE9SX0JJVFMpIC0KCQkJCSAgICAgICBpbmZvLT5uc2VjdG9yc19idWZmZXJlZCk7CgoJY2hhciAqZGVzdDsKCgkvKiBJZiB3ZSBjb3VsZG4ndCBnZXQgYSBidWZmZXIsIGRvbid0IHRyeSB0byBidWZmZXIgYW55dGhpbmcuLi4gKi8KCWlmIChpbmZvLT5idWZmZXIgPT0gTlVMTCkKCQlzZWN0b3JzX3RvX2J1ZmZlciA9IDA7CgoJLyogSWYgdGhpcyBpcyB0aGUgZmlyc3Qgc2VjdG9yIGluIHRoZSBidWZmZXIsIHJlbWVtYmVyIGl0cyBudW1iZXIuICovCglpZiAoaW5mby0+bnNlY3RvcnNfYnVmZmVyZWQgPT0gMCkKCQlpbmZvLT5zZWN0b3JfYnVmZmVyZWQgPSBzZWN0b3I7CgoJLyogUmVhZCB0aGUgZGF0YSBpbnRvIHRoZSBidWZmZXIuICovCglkZXN0ID0gaW5mby0+YnVmZmVyICsgaW5mby0+bnNlY3RvcnNfYnVmZmVyZWQgKiBTRUNUT1JfU0laRTsKCXdoaWxlIChzZWN0b3JzX3RvX2J1ZmZlciA+IDApIHsKCQlIV0lGKGRyaXZlKS0+YXRhcGlfaW5wdXRfYnl0ZXMoZHJpdmUsIGRlc3QsIFNFQ1RPUl9TSVpFKTsKCQktLXNlY3RvcnNfdG9fYnVmZmVyOwoJCS0tc2VjdG9yc190b190cmFuc2ZlcjsKCQkrK2luZm8tPm5zZWN0b3JzX2J1ZmZlcmVkOwoJCWRlc3QgKz0gU0VDVE9SX1NJWkU7Cgl9CgoJLyogVGhyb3cgYXdheSBhbnkgcmVtYWluaW5nIGRhdGEuICovCgl3aGlsZSAoc2VjdG9yc190b190cmFuc2ZlciA+IDApIHsKCQlzdGF0aWMgY2hhciBkdW1bU0VDVE9SX1NJWkVdOwoJCUhXSUYoZHJpdmUpLT5hdGFwaV9pbnB1dF9ieXRlcyhkcml2ZSwgZHVtLCBzaXplb2YgKGR1bSkpOwoJCS0tc2VjdG9yc190b190cmFuc2ZlcjsKCX0KfQoKLyoKICogQ2hlY2sgdGhlIGNvbnRlbnRzIG9mIHRoZSBpbnRlcnJ1cHQgcmVhc29uIHJlZ2lzdGVyIGZyb20gdGhlIGNkcm9tCiAqIGFuZCBhdHRlbXB0IHRvIHJlY292ZXIgaWYgdGhlcmUgYXJlIHByb2JsZW1zLiAgUmV0dXJucyAgMCBpZiBldmVyeXRoaW5nJ3MKICogb2s7IG5vbnplcm8gaWYgdGhlIHJlcXVlc3QgaGFzIGJlZW4gdGVybWluYXRlZC4KICovCnN0YXRpYyBpbmxpbmUKaW50IGNkcm9tX3JlYWRfY2hlY2tfaXJlYXNvbiAoaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgbGVuLCBpbnQgaXJlYXNvbikKewoJaWYgKGlyZWFzb24gPT0gMikKCQlyZXR1cm4gMDsKCWVsc2UgaWYgKGlyZWFzb24gPT0gMCkgewoJCS8qIFdob29wcy4uLiBUaGUgZHJpdmUgaXMgZXhwZWN0aW5nIHRvIHJlY2VpdmUgZGF0YSBmcm9tIHVzISAqLwoJCXByaW50ayhLRVJOX0VSUiAiJXM6IHJlYWRfaW50cjogRHJpdmUgd2FudHMgdG8gdHJhbnNmZXIgZGF0YSB0aGUgIgoJCQkJCQkid3Jvbmcgd2F5IVxuIiwgZHJpdmUtPm5hbWUpOwoKCQkvKiBUaHJvdyBzb21lIGRhdGEgYXQgdGhlIGRyaXZlIHNvIGl0IGRvZXNuJ3QgaGFuZwoJCSAgIGFuZCBxdWl0IHRoaXMgcmVxdWVzdC4gKi8KCQl3aGlsZSAobGVuID4gMCkgewoJCQlpbnQgZHVtID0gMDsKCQkJSFdJRihkcml2ZSktPmF0YXBpX291dHB1dF9ieXRlcyhkcml2ZSwgJmR1bSwgc2l6ZW9mIChkdW0pKTsKCQkJbGVuIC09IHNpemVvZiAoZHVtKTsKCQl9Cgl9IGVsc2UgIGlmIChpcmVhc29uID09IDEpIHsKCQkvKiBTb21lIGRyaXZlcyAoQVNVUykgc2VlbSB0byB0ZWxsIHVzIHRoYXQgc3RhdHVzCgkJICogaW5mbyBpcyBhdmFpbGFibGUuIGp1c3QgZ2V0IGl0IGFuZCBpZ25vcmUuCgkJICovCgkJKHZvaWQpIEhXSUYoZHJpdmUpLT5JTkIoSURFX1NUQVRVU19SRUcpOwoJCXJldHVybiAwOwoJfSBlbHNlIHsKCQkvKiBEcml2ZSB3YW50cyBhIGNvbW1hbmQgcGFja2V0LCBvciBpbnZhbGlkIGlyZWFzb24uLi4gKi8KCQlwcmludGsoS0VSTl9FUlIgIiVzOiByZWFkX2ludHI6IGJhZCBpbnRlcnJ1cHQgcmVhc29uICV4XG4iLCBkcml2ZS0+bmFtZSwKCQkJCQkJCQlpcmVhc29uKTsKCX0KCgljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7CglyZXR1cm4gLTE7Cn0KCi8qCiAqIEludGVycnVwdCByb3V0aW5lLiAgQ2FsbGVkIHdoZW4gYSByZWFkIHJlcXVlc3QgaGFzIGNvbXBsZXRlZC4KICovCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fcmVhZF9pbnRyIChpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCWludCBzdGF0OwoJaW50IGlyZWFzb24sIGxlbiwgc2VjdG9yc190b190cmFuc2ZlciwgbnNraXA7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXU4IGxvd2N5bCA9IDAsIGhpZ2hjeWwgPSAwOwoJaW50IGRtYSA9IGluZm8tPmRtYSwgZG1hX2Vycm9yID0gMDsKCglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7CgoJLyoKCSAqIGhhbmRsZSBkbWEgY2FzZQoJICovCglpZiAoZG1hKSB7CgkJaW5mby0+ZG1hID0gMDsKCQlpZiAoKGRtYV9lcnJvciA9IEhXSUYoZHJpdmUpLT5pZGVfZG1hX2VuZChkcml2ZSkpKQoJCQlfX2lkZV9kbWFfb2ZmKGRyaXZlKTsKCX0KCglpZiAoY2Ryb21fZGVjb2RlX3N0YXR1cyhkcml2ZSwgMCwgJnN0YXQpKQoJCXJldHVybiBpZGVfc3RvcHBlZDsKCglpZiAoZG1hKSB7CgkJaWYgKCFkbWFfZXJyb3IpIHsKCQkJaWRlX2VuZF9yZXF1ZXN0KGRyaXZlLCAxLCBycS0+bnJfc2VjdG9ycyk7CgkJCXJldHVybiBpZGVfc3RvcHBlZDsKCQl9IGVsc2UKCQkJcmV0dXJuIGlkZV9lcnJvcihkcml2ZSwgImRtYSBlcnJvciIsIHN0YXQpOwoJfQoKCS8qIFJlYWQgdGhlIGludGVycnVwdCByZWFzb24gYW5kIHRoZSB0cmFuc2ZlciBsZW5ndGguICovCglpcmVhc29uID0gSFdJRihkcml2ZSktPklOQihJREVfSVJFQVNPTl9SRUcpICYgMHgzOwoJbG93Y3lsICA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX0JDT1VOVExfUkVHKTsKCWhpZ2hjeWwgPSBIV0lGKGRyaXZlKS0+SU5CKElERV9CQ09VTlRIX1JFRyk7CgoJbGVuID0gbG93Y3lsICsgKDI1NiAqIGhpZ2hjeWwpOwoKCS8qIElmIERSUSBpcyBjbGVhciwgdGhlIGNvbW1hbmQgaGFzIGNvbXBsZXRlZC4gKi8KCWlmICgoc3RhdCAmIERSUV9TVEFUKSA9PSAwKSB7CgkJLyogSWYgd2UncmUgbm90IGRvbmUgZmlsbGluZyB0aGUgY3VycmVudCBidWZmZXIsIGNvbXBsYWluLgoJCSAgIE90aGVyd2lzZSwgY29tcGxldGUgdGhlIGNvbW1hbmQgbm9ybWFsbHkuICovCgkJaWYgKHJxLT5jdXJyZW50X25yX3NlY3RvcnMgPiAwKSB7CgkJCXByaW50ayAoS0VSTl9FUlIgIiVzOiBjZHJvbV9yZWFkX2ludHI6IGRhdGEgdW5kZXJydW4gKCVkIGJsb2NrcylcbiIsCgkJCQlkcml2ZS0+bmFtZSwgcnEtPmN1cnJlbnRfbnJfc2VjdG9ycyk7CgkJCXJxLT5mbGFncyB8PSBSRVFfRkFJTEVEOwoJCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7CgkJfSBlbHNlCgkJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAxKTsKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7Cgl9CgoJLyogQ2hlY2sgdGhhdCB0aGUgZHJpdmUgaXMgZXhwZWN0aW5nIHRvIGRvIHRoZSBzYW1lIHRoaW5nIHdlIGFyZS4gKi8KCWlmIChjZHJvbV9yZWFkX2NoZWNrX2lyZWFzb24gKGRyaXZlLCBsZW4sIGlyZWFzb24pKQoJCXJldHVybiBpZGVfc3RvcHBlZDsKCgkvKiBBc3N1bWUgdGhhdCB0aGUgZHJpdmUgd2lsbCBhbHdheXMgcHJvdmlkZSBkYXRhIGluIG11bHRpcGxlcwoJICAgb2YgYXQgbGVhc3QgU0VDVE9SX1NJWkUsIGFzIGl0IGdldHMgaGFpcnkgdG8ga2VlcCB0cmFjawoJICAgb2YgdGhlIHRyYW5zZmVycyBvdGhlcndpc2UuICovCglpZiAoKGxlbiAlIFNFQ1RPUl9TSVpFKSAhPSAwKSB7CgkJcHJpbnRrIChLRVJOX0VSUiAiJXM6IGNkcm9tX3JlYWRfaW50cjogQmFkIHRyYW5zZmVyIHNpemUgJWRcbiIsCgkJCWRyaXZlLT5uYW1lLCBsZW4pOwoJCWlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5saW1pdF9uZnJhbWVzKQoJCQlwcmludGsgKEtFUk5fRVJSICIgIFRoaXMgZHJpdmUgaXMgbm90IHN1cHBvcnRlZCBieSB0aGlzIHZlcnNpb24gb2YgdGhlIGRyaXZlclxuIik7CgkJZWxzZSB7CgkJCXByaW50ayAoS0VSTl9FUlIgIiAgVHJ5aW5nIHRvIGxpbWl0IHRyYW5zZmVyIHNpemVzXG4iKTsKCQkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bGltaXRfbmZyYW1lcyA9IDE7CgkJfQoJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAwKTsKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7Cgl9CgoJLyogVGhlIG51bWJlciBvZiBzZWN0b3JzIHdlIG5lZWQgdG8gcmVhZCBmcm9tIHRoZSBkcml2ZS4gKi8KCXNlY3RvcnNfdG9fdHJhbnNmZXIgPSBsZW4gLyBTRUNUT1JfU0laRTsKCgkvKiBGaXJzdCwgZmlndXJlIG91dCBpZiB3ZSBuZWVkIHRvIGJpdC1idWNrZXQKCSAgIGFueSBvZiB0aGUgbGVhZGluZyBzZWN0b3JzLiAqLwoJbnNraXAgPSBtaW5fdChpbnQsIHJxLT5jdXJyZW50X25yX3NlY3RvcnMgLSBiaW9fY3VyX3NlY3RvcnMocnEtPmJpbyksIHNlY3RvcnNfdG9fdHJhbnNmZXIpOwoKCXdoaWxlIChuc2tpcCA+IDApIHsKCQkvKiBXZSBuZWVkIHRvIHRocm93IGF3YXkgYSBzZWN0b3IuICovCgkJc3RhdGljIGNoYXIgZHVtW1NFQ1RPUl9TSVpFXTsKCQlIV0lGKGRyaXZlKS0+YXRhcGlfaW5wdXRfYnl0ZXMoZHJpdmUsIGR1bSwgc2l6ZW9mIChkdW0pKTsKCgkJLS1ycS0+Y3VycmVudF9ucl9zZWN0b3JzOwoJCS0tbnNraXA7CgkJLS1zZWN0b3JzX3RvX3RyYW5zZmVyOwoJfQoKCS8qIE5vdyBsb29wIHdoaWxlIHdlIHN0aWxsIGhhdmUgZGF0YSB0byByZWFkIGZyb20gdGhlIGRyaXZlLiAqLwoJd2hpbGUgKHNlY3RvcnNfdG9fdHJhbnNmZXIgPiAwKSB7CgkJaW50IHRoaXNfdHJhbnNmZXI7CgoJCS8qIElmIHdlJ3ZlIGZpbGxlZCB0aGUgcHJlc2VudCBidWZmZXIgYnV0IHRoZXJlJ3MgYW5vdGhlcgoJCSAgIGNoYWluZWQgYnVmZmVyIGFmdGVyIGl0LCBtb3ZlIG9uLiAqLwoJCWlmIChycS0+Y3VycmVudF9ucl9zZWN0b3JzID09IDAgJiYgcnEtPm5yX3NlY3RvcnMpCgkJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAxKTsKCgkJLyogSWYgdGhlIGJ1ZmZlcnMgYXJlIGZ1bGwsIGNhY2hlIHRoZSByZXN0IG9mIHRoZSBkYXRhIGluIG91cgoJCSAgIGludGVybmFsIGJ1ZmZlci4gKi8KCQlpZiAocnEtPmN1cnJlbnRfbnJfc2VjdG9ycyA9PSAwKSB7CgkJCWNkcm9tX2J1ZmZlcl9zZWN0b3JzKGRyaXZlLCBycS0+c2VjdG9yLCBzZWN0b3JzX3RvX3RyYW5zZmVyKTsKCQkJc2VjdG9yc190b190cmFuc2ZlciA9IDA7CgkJfSBlbHNlIHsKCQkJLyogVHJhbnNmZXIgZGF0YSB0byB0aGUgYnVmZmVycy4KCQkJICAgRmlndXJlIG91dCBob3cgbWFueSBzZWN0b3JzIHdlIGNhbiB0cmFuc2ZlcgoJCQkgICB0byB0aGUgY3VycmVudCBidWZmZXIuICovCgkJCXRoaXNfdHJhbnNmZXIgPSBtaW5fdChpbnQsIHNlY3RvcnNfdG9fdHJhbnNmZXIsCgkJCQkJICAgICBycS0+Y3VycmVudF9ucl9zZWN0b3JzKTsKCgkJCS8qIFJlYWQgdGhpc190cmFuc2ZlciBzZWN0b3JzCgkJCSAgIGludG8gdGhlIGN1cnJlbnQgYnVmZmVyLiAqLwoJCQl3aGlsZSAodGhpc190cmFuc2ZlciA+IDApIHsKCQkJCUhXSUYoZHJpdmUpLT5hdGFwaV9pbnB1dF9ieXRlcyhkcml2ZSwgcnEtPmJ1ZmZlciwgU0VDVE9SX1NJWkUpOwoJCQkJcnEtPmJ1ZmZlciArPSBTRUNUT1JfU0laRTsKCQkJCS0tcnEtPm5yX3NlY3RvcnM7CgkJCQktLXJxLT5jdXJyZW50X25yX3NlY3RvcnM7CgkJCQkrK3JxLT5zZWN0b3I7CgkJCQktLXRoaXNfdHJhbnNmZXI7CgkJCQktLXNlY3RvcnNfdG9fdHJhbnNmZXI7CgkJCX0KCQl9Cgl9CgoJLyogRG9uZSBtb3ZpbmcgZGF0YSEgIFdhaXQgZm9yIGFub3RoZXIgaW50ZXJydXB0LiAqLwoJaWRlX3NldF9oYW5kbGVyKGRyaXZlLCAmY2Ryb21fcmVhZF9pbnRyLCBBVEFQSV9XQUlUX1BDLCBOVUxMKTsKCXJldHVybiBpZGVfc3RhcnRlZDsKfQoKLyoKICogVHJ5IHRvIHNhdGlzZnkgc29tZSBvZiB0aGUgY3VycmVudCByZWFkIHJlcXVlc3QgZnJvbSBvdXIgY2FjaGVkIGRhdGEuCiAqIFJldHVybnMgbm9uemVybyBpZiB0aGUgcmVxdWVzdCBoYXMgYmVlbiBjb21wbGV0ZWQsIHplcm8gb3RoZXJ3aXNlLgogKi8Kc3RhdGljIGludCBjZHJvbV9yZWFkX2Zyb21fYnVmZmVyIChpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJc3RydWN0IHJlcXVlc3QgKnJxID0gSFdHUk9VUChkcml2ZSktPnJxOwoJdW5zaWduZWQgc2hvcnQgc2VjdG9yc19wZXJfZnJhbWU7CgoJc2VjdG9yc19wZXJfZnJhbWUgPSBxdWV1ZV9oYXJkc2VjdF9zaXplKGRyaXZlLT5xdWV1ZSkgPj4gU0VDVE9SX0JJVFM7CgoJLyogQ2FuJ3QgZG8gYW55dGhpbmcgaWYgdGhlcmUncyBubyBidWZmZXIuICovCglpZiAoaW5mby0+YnVmZmVyID09IE5VTEwpIHJldHVybiAwOwoKCS8qIExvb3Agd2hpbGUgdGhpcyByZXF1ZXN0IG5lZWRzIGRhdGEgYW5kIHRoZSBuZXh0IGJsb2NrIGlzIHByZXNlbnQKCSAgIGluIG91ciBjYWNoZS4gKi8KCXdoaWxlIChycS0+bnJfc2VjdG9ycyA+IDAgJiYKCSAgICAgICBycS0+c2VjdG9yID49IGluZm8tPnNlY3Rvcl9idWZmZXJlZCAmJgoJICAgICAgIHJxLT5zZWN0b3IgPCBpbmZvLT5zZWN0b3JfYnVmZmVyZWQgKyBpbmZvLT5uc2VjdG9yc19idWZmZXJlZCkgewoJCWlmIChycS0+Y3VycmVudF9ucl9zZWN0b3JzID09IDApCgkJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAxKTsKCgkJbWVtY3B5IChycS0+YnVmZmVyLAoJCQlpbmZvLT5idWZmZXIgKwoJCQkocnEtPnNlY3RvciAtIGluZm8tPnNlY3Rvcl9idWZmZXJlZCkgKiBTRUNUT1JfU0laRSwKCQkJU0VDVE9SX1NJWkUpOwoJCXJxLT5idWZmZXIgKz0gU0VDVE9SX1NJWkU7CgkJLS1ycS0+Y3VycmVudF9ucl9zZWN0b3JzOwoJCS0tcnEtPm5yX3NlY3RvcnM7CgkJKytycS0+c2VjdG9yOwoJfQoKCS8qIElmIHdlJ3ZlIHNhdGlzZmllZCB0aGUgY3VycmVudCByZXF1ZXN0LAoJICAgdGVybWluYXRlIGl0IHN1Y2Nlc3NmdWxseS4gKi8KCWlmIChycS0+bnJfc2VjdG9ycyA9PSAwKSB7CgkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDEpOwoJCXJldHVybiAtMTsKCX0KCgkvKiBNb3ZlIG9uIHRvIHRoZSBuZXh0IGJ1ZmZlciBpZiBuZWVkZWQuICovCglpZiAocnEtPmN1cnJlbnRfbnJfc2VjdG9ycyA9PSAwKQoJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAxKTsKCgkvKiBJZiB0aGlzIGNvbmRpdGlvbiBkb2VzIG5vdCBob2xkLCB0aGVuIHRoZSBrbHVnZSBpIHVzZSB0bwoJICAgcmVwcmVzZW50IHRoZSBudW1iZXIgb2Ygc2VjdG9ycyB0byBza2lwIGF0IHRoZSBzdGFydCBvZiBhIHRyYW5zZmVyCgkgICB3aWxsIGZhaWwuICBJIHRoaW5rIHRoYXQgdGhpcyB3aWxsIG5ldmVyIGhhcHBlbiwgYnV0IGxldCdzIGJlCgkgICBwYXJhbm9pZCBhbmQgY2hlY2suICovCglpZiAocnEtPmN1cnJlbnRfbnJfc2VjdG9ycyA8IGJpb19jdXJfc2VjdG9ycyhycS0+YmlvKSAmJgoJICAgIChycS0+c2VjdG9yICYgKHNlY3RvcnNfcGVyX2ZyYW1lIC0gMSkpKSB7CgkJcHJpbnRrKEtFUk5fRVJSICIlczogY2Ryb21fcmVhZF9mcm9tX2J1ZmZlcjogYnVmZmVyIGJvdGNoICglbGQpXG4iLAoJCQlkcml2ZS0+bmFtZSwgKGxvbmcpcnEtPnNlY3Rvcik7CgkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDApOwoJCXJldHVybiAtMTsKCX0KCglyZXR1cm4gMDsKfQoKLyoKICogUm91dGluZSB0byBzZW5kIGEgcmVhZCBwYWNrZXQgY29tbWFuZCB0byB0aGUgZHJpdmUuCiAqIFRoaXMgaXMgdXN1YWxseSBjYWxsZWQgZGlyZWN0bHkgZnJvbSBjZHJvbV9zdGFydF9yZWFkLgogKiBIb3dldmVyLCBmb3IgZHJxX2ludGVycnVwdCBkZXZpY2VzLCBpdCBpcyBjYWxsZWQgZnJvbSBhbiBpbnRlcnJ1cHQKICogd2hlbiB0aGUgZHJpdmUgaXMgcmVhZHkgdG8gYWNjZXB0IHRoZSBjb21tYW5kLgogKi8Kc3RhdGljIGlkZV9zdGFydHN0b3BfdCBjZHJvbV9zdGFydF9yZWFkX2NvbnRpbnVhdGlvbiAoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7Cgl1bnNpZ25lZCBzaG9ydCBzZWN0b3JzX3Blcl9mcmFtZTsKCWludCBuc2tpcDsKCglzZWN0b3JzX3Blcl9mcmFtZSA9IHF1ZXVlX2hhcmRzZWN0X3NpemUoZHJpdmUtPnF1ZXVlKSA+PiBTRUNUT1JfQklUUzsKCgkvKiBJZiB0aGUgcmVxdWVzdGVkIHNlY3RvciBkb2Vzbid0IHN0YXJ0IG9uIGEgY2Ryb20gYmxvY2sgYm91bmRhcnksCgkgICB3ZSBtdXN0IGFkanVzdCB0aGUgc3RhcnQgb2YgdGhlIHRyYW5zZmVyIHNvIHRoYXQgaXQgZG9lcywKCSAgIGFuZCByZW1lbWJlciB0byBza2lwIHRoZSBmaXJzdCBmZXcgc2VjdG9ycy4KCSAgIElmIHRoZSBDVVJSRU5UX05SX1NFQ1RPUlMgZmllbGQgaXMgbGFyZ2VyIHRoYW4gdGhlIHNpemUKCSAgIG9mIHRoZSBidWZmZXIsIGl0IHdpbGwgbWVhbiB0aGF0IHdlJ3JlIHRvIHNraXAgYSBudW1iZXIKCSAgIG9mIHNlY3RvcnMgZXF1YWwgdG8gdGhlIGFtb3VudCBieSB3aGljaCBDVVJSRU5UX05SX1NFQ1RPUlMKCSAgIGlzIGxhcmdlciB0aGFuIHRoZSBidWZmZXIgc2l6ZS4gKi8KCW5za2lwID0gcnEtPnNlY3RvciAmIChzZWN0b3JzX3Blcl9mcmFtZSAtIDEpOwoJaWYgKG5za2lwID4gMCkgewoJCS8qIFNhbml0eSBjaGVjay4uLiAqLwoJCWlmIChycS0+Y3VycmVudF9ucl9zZWN0b3JzICE9IGJpb19jdXJfc2VjdG9ycyhycS0+YmlvKSAmJgoJCQkocnEtPnNlY3RvciAmIChzZWN0b3JzX3Blcl9mcmFtZSAtIDEpKSkgewoJCQlwcmludGsoS0VSTl9FUlIgIiVzOiBjZHJvbV9zdGFydF9yZWFkX2NvbnRpbnVhdGlvbjogYnVmZmVyIGJvdGNoICgldSlcbiIsCgkJCQlkcml2ZS0+bmFtZSwgcnEtPmN1cnJlbnRfbnJfc2VjdG9ycyk7CgkJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAwKTsKCQkJcmV0dXJuIGlkZV9zdG9wcGVkOwoJCX0KCQlycS0+Y3VycmVudF9ucl9zZWN0b3JzICs9IG5za2lwOwoJfQoKCS8qIFNldCB1cCB0aGUgY29tbWFuZCAqLwoJcnEtPnRpbWVvdXQgPSBBVEFQSV9XQUlUX1BDOwoKCS8qIFNlbmQgdGhlIGNvbW1hbmQgdG8gdGhlIGRyaXZlIGFuZCByZXR1cm4uICovCglyZXR1cm4gY2Ryb21fdHJhbnNmZXJfcGFja2V0X2NvbW1hbmQoZHJpdmUsIHJxLCAmY2Ryb21fcmVhZF9pbnRyKTsKfQoKCiNkZWZpbmUgSURFQ0RfU0VFS19USFJFU0hPTEQJKDEwMDApCQkJLyogMTAwMCBibG9ja3MgKi8KI2RlZmluZSBJREVDRF9TRUVLX1RJTUVSCSg1ICogV0FJVF9NSU5fU0xFRVApCS8qIDEwMCBtcyAqLwojZGVmaW5lIElERUNEX1NFRUtfVElNRU9VVAkoMiAqIFdBSVRfQ01EKQkJLyogMjAgc2VjICovCgpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX3NlZWtfaW50ciAoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCWludCBzdGF0OwoJc3RhdGljIGludCByZXRyeSA9IDEwOwoKCWlmIChjZHJvbV9kZWNvZGVfc3RhdHVzKGRyaXZlLCAwLCAmc3RhdCkpCgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+c2Vla2luZyA9IDE7CgoJaWYgKHJldHJ5ICYmIHRpbWVfYWZ0ZXIoamlmZmllcywgaW5mby0+c3RhcnRfc2VlayArIElERUNEX1NFRUtfVElNRVIpKSB7CgkJaWYgKC0tcmV0cnkgPT0gMCkgewoJCQkvKgoJCQkgKiB0aGlzIGNvbmRpdGlvbiBpcyBmYXIgdG9vIGNvbW1vbiwgdG8gYm90aGVyCgkJCSAqIHVzZXJzIGFib3V0IGl0CgkJCSAqLwoJCQkvKiBwcmludGsoIiVzOiBkaXNhYmxlZCBEU0Mgc2VlayBvdmVybGFwXG4iLCBkcml2ZS0+bmFtZSk7Ki8gCgkJCWRyaXZlLT5kc2Nfb3ZlcmxhcCA9IDA7CgkJfQoJfQoJcmV0dXJuIGlkZV9zdG9wcGVkOwp9CgpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX3N0YXJ0X3NlZWtfY29udGludWF0aW9uIChpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCXNlY3Rvcl90IGZyYW1lID0gcnEtPnNlY3RvcjsKCglzZWN0b3JfZGl2KGZyYW1lLCBxdWV1ZV9oYXJkc2VjdF9zaXplKGRyaXZlLT5xdWV1ZSkgPj4gU0VDVE9SX0JJVFMpOwoKCW1lbXNldChycS0+Y21kLCAwLCBzaXplb2YocnEtPmNtZCkpOwoJcnEtPmNtZFswXSA9IEdQQ01EX1NFRUs7CglwdXRfdW5hbGlnbmVkKGNwdV90b19iZTMyKGZyYW1lKSwgKHVuc2lnbmVkIGludCAqKSAmcnEtPmNtZFsyXSk7CgoJcnEtPnRpbWVvdXQgPSBBVEFQSV9XQUlUX1BDOwoJcmV0dXJuIGNkcm9tX3RyYW5zZmVyX3BhY2tldF9jb21tYW5kKGRyaXZlLCBycSwgJmNkcm9tX3NlZWtfaW50cik7Cn0KCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fc3RhcnRfc2VlayAoaWRlX2RyaXZlX3QgKmRyaXZlLCB1bnNpZ25lZCBpbnQgYmxvY2spCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoKCWluZm8tPmRtYSA9IDA7CglpbmZvLT5jbWQgPSAwOwoJaW5mby0+c3RhcnRfc2VlayA9IGppZmZpZXM7CglyZXR1cm4gY2Ryb21fc3RhcnRfcGFja2V0X2NvbW1hbmQoZHJpdmUsIDAsIGNkcm9tX3N0YXJ0X3NlZWtfY29udGludWF0aW9uKTsKfQoKLyogRml4IHVwIGEgcG9zc2libHkgcGFydGlhbGx5LXByb2Nlc3NlZCByZXF1ZXN0IHNvIHRoYXQgd2UgY2FuCiAgIHN0YXJ0IGl0IG92ZXIgZW50aXJlbHksIG9yIGV2ZW4gcHV0IGl0IGJhY2sgb24gdGhlIHJlcXVlc3QgcXVldWUuICovCnN0YXRpYyB2b2lkIHJlc3RvcmVfcmVxdWVzdCAoc3RydWN0IHJlcXVlc3QgKnJxKQp7CglpZiAocnEtPmJ1ZmZlciAhPSBiaW9fZGF0YShycS0+YmlvKSkgewoJCXNlY3Rvcl90IG4gPSAocnEtPmJ1ZmZlciAtIChjaGFyICopIGJpb19kYXRhKHJxLT5iaW8pKSAvIFNFQ1RPUl9TSVpFOwoKCQlycS0+YnVmZmVyID0gYmlvX2RhdGEocnEtPmJpbyk7CgkJcnEtPm5yX3NlY3RvcnMgKz0gbjsKCQlycS0+c2VjdG9yIC09IG47Cgl9CglycS0+aGFyZF9jdXJfc2VjdG9ycyA9IHJxLT5jdXJyZW50X25yX3NlY3RvcnMgPSBiaW9fY3VyX3NlY3RvcnMocnEtPmJpbyk7CglycS0+aGFyZF9ucl9zZWN0b3JzID0gcnEtPm5yX3NlY3RvcnM7CglycS0+aGFyZF9zZWN0b3IgPSBycS0+c2VjdG9yOwoJcnEtPnEtPnByZXBfcnFfZm4ocnEtPnEsIHJxKTsKfQoKLyoKICogU3RhcnQgYSByZWFkIHJlcXVlc3QgZnJvbSB0aGUgQ0QtUk9NLgogKi8Kc3RhdGljIGlkZV9zdGFydHN0b3BfdCBjZHJvbV9zdGFydF9yZWFkIChpZGVfZHJpdmVfdCAqZHJpdmUsIHVuc2lnbmVkIGludCBibG9jaykKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7Cgl1bnNpZ25lZCBzaG9ydCBzZWN0b3JzX3Blcl9mcmFtZTsKCglzZWN0b3JzX3Blcl9mcmFtZSA9IHF1ZXVlX2hhcmRzZWN0X3NpemUoZHJpdmUtPnF1ZXVlKSA+PiBTRUNUT1JfQklUUzsKCgkvKiBXZSBtYXkgYmUgcmV0cnlpbmcgdGhpcyByZXF1ZXN0IGFmdGVyIGFuIGVycm9yLiAgRml4IHVwCgkgICBhbnkgd2VpcmRuZXNzIHdoaWNoIG1pZ2h0IGJlIHByZXNlbnQgaW4gdGhlIHJlcXVlc3QgcGFja2V0LiAqLwoJcmVzdG9yZV9yZXF1ZXN0KHJxKTsKCgkvKiBTYXRpc2Z5IHdoYXRldmVyIHdlIGNhbiBvZiB0aGlzIHJlcXVlc3QgZnJvbSBvdXIgY2FjaGVkIHNlY3Rvci4gKi8KCWlmIChjZHJvbV9yZWFkX2Zyb21fYnVmZmVyKGRyaXZlKSkKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgoJYmxrX2F0dGVtcHRfcmVtZXJnZShkcml2ZS0+cXVldWUsIHJxKTsKCgkvKiBDbGVhciB0aGUgbG9jYWwgc2VjdG9yIGJ1ZmZlci4gKi8KCWluZm8tPm5zZWN0b3JzX2J1ZmZlcmVkID0gMDsKCgkvKiB1c2UgZG1hLCBpZiBwb3NzaWJsZS4gKi8KCWluZm8tPmRtYSA9IGRyaXZlLT51c2luZ19kbWE7CglpZiAoKHJxLT5zZWN0b3IgJiAoc2VjdG9yc19wZXJfZnJhbWUgLSAxKSkgfHwKCSAgICAocnEtPm5yX3NlY3RvcnMgJiAoc2VjdG9yc19wZXJfZnJhbWUgLSAxKSkpCgkJaW5mby0+ZG1hID0gMDsKCglpbmZvLT5jbWQgPSBSRUFEOwoKCS8qIFN0YXJ0IHNlbmRpbmcgdGhlIHJlYWQgcmVxdWVzdCB0byB0aGUgZHJpdmUuICovCglyZXR1cm4gY2Ryb21fc3RhcnRfcGFja2V0X2NvbW1hbmQoZHJpdmUsIDMyNzY4LCBjZHJvbV9zdGFydF9yZWFkX2NvbnRpbnVhdGlvbik7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIEV4ZWN1dGUgYWxsIG90aGVyIHBhY2tldCBjb21tYW5kcy4KICovCgovKiBJbnRlcnJ1cHQgcm91dGluZSBmb3IgcGFja2V0IGNvbW1hbmQgY29tcGxldGlvbi4gKi8Kc3RhdGljIGlkZV9zdGFydHN0b3BfdCBjZHJvbV9wY19pbnRyIChpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCWludCBpcmVhc29uLCBsZW4sIHRoaXNsZW47CglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7Cgl1OCBsb3djeWwgPSAwLCBoaWdoY3lsID0gMDsKCWludCBzdGF0OwoKCS8qIENoZWNrIGZvciBlcnJvcnMuICovCglpZiAoY2Ryb21fZGVjb2RlX3N0YXR1cyhkcml2ZSwgMCwgJnN0YXQpKQoJCXJldHVybiBpZGVfc3RvcHBlZDsKCgkvKiBSZWFkIHRoZSBpbnRlcnJ1cHQgcmVhc29uIGFuZCB0aGUgdHJhbnNmZXIgbGVuZ3RoLiAqLwoJaXJlYXNvbiA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX0lSRUFTT05fUkVHKTsKCWxvd2N5bCAgPSBIV0lGKGRyaXZlKS0+SU5CKElERV9CQ09VTlRMX1JFRyk7CgloaWdoY3lsID0gSFdJRihkcml2ZSktPklOQihJREVfQkNPVU5USF9SRUcpOwoKCWxlbiA9IGxvd2N5bCArICgyNTYgKiBoaWdoY3lsKTsKCgkvKiBJZiBEUlEgaXMgY2xlYXIsIHRoZSBjb21tYW5kIGhhcyBjb21wbGV0ZWQuCgkgICBDb21wbGFpbiBpZiB3ZSBzdGlsbCBoYXZlIGRhdGEgbGVmdCB0byB0cmFuc2Zlci4gKi8KCWlmICgoc3RhdCAmIERSUV9TVEFUKSA9PSAwKSB7CgkJLyogU29tZSBvZiB0aGUgdHJhaWxpbmcgcmVxdWVzdCBzZW5zZSBmaWVsZHMgYXJlIG9wdGlvbmFsLCBhbmQKCQkgICBzb21lIGRyaXZlcyBkb24ndCBzZW5kIHRoZW0uICBTaWdoLiAqLwoJCWlmIChycS0+Y21kWzBdID09IEdQQ01EX1JFUVVFU1RfU0VOU0UgJiYKCQkgICAgcnEtPmRhdGFfbGVuID4gMCAmJgoJCSAgICBycS0+ZGF0YV9sZW4gPD0gNSkgewoJCQl3aGlsZSAocnEtPmRhdGFfbGVuID4gMCkgewoJCQkJKih1bnNpZ25lZCBjaGFyICopcnEtPmRhdGErKyA9IDA7CgkJCQktLXJxLT5kYXRhX2xlbjsKCQkJfQoJCX0KCgkJaWYgKHJxLT5kYXRhX2xlbiA9PSAwKQoJCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMSk7CgkJZWxzZSB7CgkJCS8qIENvbW1lbnQgdGhpcyBvdXQsIGJlY2F1c2UgdGhpcyBhbHdheXMgaGFwcGVucyAKCQkJICAgcmlnaHQgYWZ0ZXIgYSByZXNldCBvY2N1cnMsIGFuZCBpdCBpcyBhbm5veWluZyB0byAKCQkJICAgYWx3YXlzIHByaW50IGV4cGVjdGVkIHN0dWZmLiAgKi8KCQkJLyoKCQkJcHJpbnRrICgiJXM6IGNkcm9tX3BjX2ludHI6IGRhdGEgdW5kZXJydW4gJWRcbiIsCgkJCQlkcml2ZS0+bmFtZSwgcGMtPmJ1Zmxlbik7CgkJCSovCgkJCXJxLT5mbGFncyB8PSBSRVFfRkFJTEVEOwoJCQljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7CgkJfQoJCXJldHVybiBpZGVfc3RvcHBlZDsKCX0KCgkvKiBGaWd1cmUgb3V0IGhvdyBtdWNoIGRhdGEgdG8gdHJhbnNmZXIuICovCgl0aGlzbGVuID0gcnEtPmRhdGFfbGVuOwoJaWYgKHRoaXNsZW4gPiBsZW4pIHRoaXNsZW4gPSBsZW47CgoJLyogVGhlIGRyaXZlIHdhbnRzIHRvIGJlIHdyaXR0ZW4gdG8uICovCglpZiAoKGlyZWFzb24gJiAzKSA9PSAwKSB7CgkJaWYgKCFycS0+ZGF0YSkgewoJCQlibGtfZHVtcF9ycV9mbGFncyhycSwgImNkcm9tX3BjX2ludHIsIHdyaXRlIik7CgkJCWdvdG8gY29uZnVzZWQ7CgkJfQoJCS8qIFRyYW5zZmVyIHRoZSBkYXRhLiAqLwoJCUhXSUYoZHJpdmUpLT5hdGFwaV9vdXRwdXRfYnl0ZXMoZHJpdmUsIHJxLT5kYXRhLCB0aGlzbGVuKTsKCgkJLyogSWYgd2UgaGF2ZW4ndCBtb3ZlZCBlbm91Z2ggZGF0YSB0byBzYXRpc2Z5IHRoZSBkcml2ZSwKCQkgICBhZGQgc29tZSBwYWRkaW5nLiAqLwoJCXdoaWxlIChsZW4gPiB0aGlzbGVuKSB7CgkJCWludCBkdW0gPSAwOwoJCQlIV0lGKGRyaXZlKS0+YXRhcGlfb3V0cHV0X2J5dGVzKGRyaXZlLCAmZHVtLCBzaXplb2YoZHVtKSk7CgkJCWxlbiAtPSBzaXplb2YoZHVtKTsKCQl9CgoJCS8qIEtlZXAgY291bnQgb2YgaG93IG11Y2ggZGF0YSB3ZSd2ZSBtb3ZlZC4gKi8KCQlycS0+ZGF0YSArPSB0aGlzbGVuOwoJCXJxLT5kYXRhX2xlbiAtPSB0aGlzbGVuOwoJfQoKCS8qIFNhbWUgZHJpbGwgZm9yIHJlYWRpbmcuICovCgllbHNlIGlmICgoaXJlYXNvbiAmIDMpID09IDIpIHsKCQlpZiAoIXJxLT5kYXRhKSB7CgkJCWJsa19kdW1wX3JxX2ZsYWdzKHJxLCAiY2Ryb21fcGNfaW50ciwgd3JpdGUiKTsKCQkJZ290byBjb25mdXNlZDsKCQl9CgkJLyogVHJhbnNmZXIgdGhlIGRhdGEuICovCgkJSFdJRihkcml2ZSktPmF0YXBpX2lucHV0X2J5dGVzKGRyaXZlLCBycS0+ZGF0YSwgdGhpc2xlbik7CgoJCS8qIElmIHdlIGhhdmVuJ3QgbW92ZWQgZW5vdWdoIGRhdGEgdG8gc2F0aXNmeSB0aGUgZHJpdmUsCgkJICAgYWRkIHNvbWUgcGFkZGluZy4gKi8KCQl3aGlsZSAobGVuID4gdGhpc2xlbikgewoJCQlpbnQgZHVtID0gMDsKCQkJSFdJRihkcml2ZSktPmF0YXBpX2lucHV0X2J5dGVzKGRyaXZlLCAmZHVtLCBzaXplb2YoZHVtKSk7CgkJCWxlbiAtPSBzaXplb2YoZHVtKTsKCQl9CgoJCS8qIEtlZXAgY291bnQgb2YgaG93IG11Y2ggZGF0YSB3ZSd2ZSBtb3ZlZC4gKi8KCQlycS0+ZGF0YSArPSB0aGlzbGVuOwoJCXJxLT5kYXRhX2xlbiAtPSB0aGlzbGVuOwoKCQlpZiAocnEtPmZsYWdzICYgUkVRX1NFTlNFKQoJCQlycS0+c2Vuc2VfbGVuICs9IHRoaXNsZW47Cgl9IGVsc2Ugewpjb25mdXNlZDoKCQlwcmludGsgKEtFUk5fRVJSICIlczogY2Ryb21fcGNfaW50cjogVGhlIGRyaXZlICIKCQkJImFwcGVhcnMgY29uZnVzZWQgKGlyZWFzb24gPSAweCUwMngpXG4iLAoJCQlkcml2ZS0+bmFtZSwgaXJlYXNvbik7CgkJcnEtPmZsYWdzIHw9IFJFUV9GQUlMRUQ7Cgl9CgoJLyogTm93IHdlIHdhaXQgZm9yIGFub3RoZXIgaW50ZXJydXB0LiAqLwoJaWRlX3NldF9oYW5kbGVyKGRyaXZlLCAmY2Ryb21fcGNfaW50ciwgQVRBUElfV0FJVF9QQywgY2Ryb21fdGltZXJfZXhwaXJ5KTsKCXJldHVybiBpZGVfc3RhcnRlZDsKfQoKc3RhdGljIGlkZV9zdGFydHN0b3BfdCBjZHJvbV9kb19wY19jb250aW51YXRpb24gKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJc3RydWN0IHJlcXVlc3QgKnJxID0gSFdHUk9VUChkcml2ZSktPnJxOwoKCWlmICghcnEtPnRpbWVvdXQpCgkJcnEtPnRpbWVvdXQgPSBBVEFQSV9XQUlUX1BDOwoKCS8qIFNlbmQgdGhlIGNvbW1hbmQgdG8gdGhlIGRyaXZlIGFuZCByZXR1cm4uICovCglyZXR1cm4gY2Ryb21fdHJhbnNmZXJfcGFja2V0X2NvbW1hbmQoZHJpdmUsIHJxLCAmY2Ryb21fcGNfaW50cik7Cn0KCgpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX2RvX3BhY2tldF9jb21tYW5kIChpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCWludCBsZW47CglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCglpbmZvLT5kbWEgPSAwOwoJaW5mby0+Y21kID0gMDsKCXJxLT5mbGFncyAmPSB+UkVRX0ZBSUxFRDsKCWxlbiA9IHJxLT5kYXRhX2xlbjsKCgkvKiBTdGFydCBzZW5kaW5nIHRoZSBjb21tYW5kIHRvIHRoZSBkcml2ZS4gKi8KCXJldHVybiBjZHJvbV9zdGFydF9wYWNrZXRfY29tbWFuZChkcml2ZSwgbGVuLCBjZHJvbV9kb19wY19jb250aW51YXRpb24pOwp9CgoKc3RhdGljCmludCBjZHJvbV9xdWV1ZV9wYWNrZXRfY29tbWFuZChpZGVfZHJpdmVfdCAqZHJpdmUsIHN0cnVjdCByZXF1ZXN0ICpycSkKewoJc3RydWN0IHJlcXVlc3Rfc2Vuc2Ugc2Vuc2U7CglpbnQgcmV0cmllcyA9IDEwOwoJdW5zaWduZWQgaW50IGZsYWdzID0gcnEtPmZsYWdzOwoKCWlmIChycS0+c2Vuc2UgPT0gTlVMTCkKCQlycS0+c2Vuc2UgPSAmc2Vuc2U7CgoJLyogU3RhcnQgb2YgcmV0cnkgbG9vcC4gKi8KCWRvIHsKCQlpbnQgZXJyb3I7CgkJdW5zaWduZWQgbG9uZyB0aW1lID0gamlmZmllczsKCQlycS0+ZmxhZ3MgPSBmbGFnczsKCgkJZXJyb3IgPSBpZGVfZG9fZHJpdmVfY21kKGRyaXZlLCBycSwgaWRlX3dhaXQpOwoJCXRpbWUgPSBqaWZmaWVzIC0gdGltZTsKCgkJLyogRklYTUU6IHdlIHNob3VsZCBwcm9iYWJseSBhYm9ydC9yZXRyeSBvciBzb21ldGhpbmcgCgkJICogaW4gY2FzZSBvZiBmYWlsdXJlICovCgkJaWYgKHJxLT5mbGFncyAmIFJFUV9GQUlMRUQpIHsKCQkJLyogVGhlIHJlcXVlc3QgZmFpbGVkLiAgUmV0cnkgaWYgaXQgd2FzIGR1ZSB0byBhIHVuaXQKCQkJICAgYXR0ZW50aW9uIHN0YXR1cwoJCQkgICAodXN1YWxseSBtZWFucyBtZWRpYSB3YXMgY2hhbmdlZCkuICovCgkJCXN0cnVjdCByZXF1ZXN0X3NlbnNlICpyZXFidWYgPSBycS0+c2Vuc2U7CgoJCQlpZiAocmVxYnVmLT5zZW5zZV9rZXkgPT0gVU5JVF9BVFRFTlRJT04pCgkJCQljZHJvbV9zYXdfbWVkaWFfY2hhbmdlKGRyaXZlKTsKCQkJZWxzZSBpZiAocmVxYnVmLT5zZW5zZV9rZXkgPT0gTk9UX1JFQURZICYmCgkJCQkgcmVxYnVmLT5hc2MgPT0gNCAmJiByZXFidWYtPmFzY3EgIT0gNCkgewoJCQkJLyogVGhlIGRyaXZlIGlzIGluIHRoZSBwcm9jZXNzIG9mIGxvYWRpbmcKCQkJCSAgIGEgZGlzay4gIFJldHJ5LCBidXQgd2FpdCBhIGxpdHRsZSB0byBnaXZlCgkJCQkgICB0aGUgZHJpdmUgdGltZSB0byBjb21wbGV0ZSB0aGUgbG9hZC4gKi8KCQkJCXNzbGVlcCgyKTsKCQkJfSBlbHNlIHsKCQkJCS8qIE90aGVyd2lzZSwgZG9uJ3QgcmV0cnkuICovCgkJCQlyZXRyaWVzID0gMDsKCQkJfQoJCQktLXJldHJpZXM7CgkJfQoKCQkvKiBFbmQgb2YgcmV0cnkgbG9vcC4gKi8KCX0gd2hpbGUgKChycS0+ZmxhZ3MgJiBSRVFfRkFJTEVEKSAmJiByZXRyaWVzID49IDApOwoKCS8qIFJldHVybiBhbiBlcnJvciBpZiB0aGUgY29tbWFuZCBmYWlsZWQuICovCglyZXR1cm4gKHJxLT5mbGFncyAmIFJFUV9GQUlMRUQpID8gLUVJTyA6IDA7Cn0KCi8qCiAqIFdyaXRlIGhhbmRsaW5nCiAqLwpzdGF0aWMgaW5saW5lIGludCBjZHJvbV93cml0ZV9jaGVja19pcmVhc29uKGlkZV9kcml2ZV90ICpkcml2ZSwgaW50IGxlbiwgaW50IGlyZWFzb24pCnsKCS8qIFR3byBub3RlcyBhYm91dCBJREUgaW50ZXJydXB0IHJlYXNvbiBoZXJlIC0gMCBtZWFucyB0aGF0CgkgKiB0aGUgZHJpdmUgd2FudHMgdG8gcmVjZWl2ZSBkYXRhIGZyb20gdXMsIDIgbWVhbnMgdGhhdAoJICogdGhlIGRyaXZlIGlzIGV4cGVjdGluZyB0byB0cmFuc2ZlciBkYXRhIHRvIHVzLgoJICovCglpZiAoaXJlYXNvbiA9PSAwKQoJCXJldHVybiAwOwoJZWxzZSBpZiAoaXJlYXNvbiA9PSAyKSB7CgkJLyogV2hvb3BzLi4uIFRoZSBkcml2ZSB3YW50cyB0byBzZW5kIGRhdGEuICovCgkJcHJpbnRrKEtFUk5fRVJSICIlczogd3JpdGVfaW50cjogd3JvbmcgdHJhbnNmZXIgZGlyZWN0aW9uIVxuIiwKCQkJCQkJCWRyaXZlLT5uYW1lKTsKCgkJd2hpbGUgKGxlbiA+IDApIHsKCQkJaW50IGR1bSA9IDA7CgkJCUhXSUYoZHJpdmUpLT5hdGFwaV9pbnB1dF9ieXRlcyhkcml2ZSwgJmR1bSwgc2l6ZW9mKGR1bSkpOwoJCQlsZW4gLT0gc2l6ZW9mKGR1bSk7CgkJfQoJfSBlbHNlIHsKCQkvKiBEcml2ZSB3YW50cyBhIGNvbW1hbmQgcGFja2V0LCBvciBpbnZhbGlkIGlyZWFzb24uLi4gKi8KCQlwcmludGsoS0VSTl9FUlIgIiVzOiB3cml0ZV9pbnRyOiBiYWQgaW50ZXJydXB0IHJlYXNvbiAleFxuIiwKCQkJCQkJCWRyaXZlLT5uYW1lLCBpcmVhc29uKTsKCX0KCgljZHJvbV9lbmRfcmVxdWVzdChkcml2ZSwgMCk7CglyZXR1cm4gMTsKfQoKc3RhdGljIHZvaWQgcG9zdF90cmFuc2Zvcm1fY29tbWFuZChzdHJ1Y3QgcmVxdWVzdCAqcmVxKQp7Cgl1OCAqYyA9IHJlcS0+Y21kOwoJY2hhciAqaWJ1ZjsKCglpZiAoIWJsa19wY19yZXF1ZXN0KHJlcSkpCgkJcmV0dXJuOwoKCWlmIChyZXEtPmJpbykKCQlpYnVmID0gYmlvX2RhdGEocmVxLT5iaW8pOwoJZWxzZQoJCWlidWYgPSByZXEtPmRhdGE7CgoJaWYgKCFpYnVmKQoJCXJldHVybjsKCgkvKgoJICogc2V0IGFuc2ktcmV2aXNpb24gYW5kIHJlc3BvbnNlIGRhdGEgYXMgYXRhcGkKCSAqLwoJaWYgKGNbMF0gPT0gR1BDTURfSU5RVUlSWSkgewoJCWlidWZbMl0gfD0gMjsKCQlpYnVmWzNdID0gKGlidWZbM10gJiAweGYwKSB8IDI7Cgl9Cn0KCnR5cGVkZWYgdm9pZCAoeGZlcl9mdW5jX3QpKGlkZV9kcml2ZV90ICosIHZvaWQgKiwgdTMyKTsKCi8qCiAqIGJlc3Qgd2F5IHRvIGRlYWwgd2l0aCBkbWEgdGhhdCBpcyBub3Qgc2VjdG9yIGFsaWduZWQgcmlnaHQgbm93Li4uIG5vdGUKICogdGhhdCBpbiB0aGlzIHBhdGggd2UgYXJlIG5vdCB1c2luZyAtPmRhdGEgb3IgLT5idWZmZXIgYXQgYWxsLiB0aGlzIGlycwogKiBjYW4gcmVwbGFjZSBjZHJvbV9wY19pbnRyLCBjZHJvbV9yZWFkX2ludHIsIGFuZCBjZHJvbV93cml0ZV9pbnRyIGluIHRoZQogKiBmdXR1cmUuCiAqLwpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX25ld3BjX2ludHIoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCWludCBkbWFfZXJyb3IsIGRtYSwgc3RhdCwgaXJlYXNvbiwgbGVuLCB0aGlzbGVuOwoJdTggbG93Y3lsLCBoaWdoY3lsOwoJeGZlcl9mdW5jX3QgKnhmZXJmdW5jOwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCgkvKiBDaGVjayBmb3IgZXJyb3JzLiAqLwoJZG1hX2Vycm9yID0gMDsKCWRtYSA9IGluZm8tPmRtYTsKCWlmIChkbWEpIHsKCQlpbmZvLT5kbWEgPSAwOwoJCWRtYV9lcnJvciA9IEhXSUYoZHJpdmUpLT5pZGVfZG1hX2VuZChkcml2ZSk7Cgl9CgoJaWYgKGNkcm9tX2RlY29kZV9zdGF0dXMoZHJpdmUsIDAsICZzdGF0KSkKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgoJLyoKCSAqIHVzaW5nIGRtYSwgdHJhbnNmZXIgaXMgY29tcGxldGUgbm93CgkgKi8KCWlmIChkbWEpIHsKCQlpZiAoZG1hX2Vycm9yKSB7CgkJCXByaW50ayhLRVJOX0VSUiAiaWRlLWNkOiBkbWEgZXJyb3JcbiIpOwoJCQlfX2lkZV9kbWFfb2ZmKGRyaXZlKTsKCQkJcmV0dXJuIGlkZV9lcnJvcihkcml2ZSwgImRtYSBlcnJvciIsIHN0YXQpOwoJCX0KCgkJZW5kX3RoYXRfcmVxdWVzdF9jaHVuayhycSwgMSwgcnEtPmRhdGFfbGVuKTsKCQlycS0+ZGF0YV9sZW4gPSAwOwoJCWdvdG8gZW5kX3JlcXVlc3Q7Cgl9CgoJLyoKCSAqIG9rIHdlIGZhbGwgdG8gcGlvIDovCgkgKi8KCWlyZWFzb24gPSBIV0lGKGRyaXZlKS0+SU5CKElERV9JUkVBU09OX1JFRykgJiAweDM7Cglsb3djeWwgID0gSFdJRihkcml2ZSktPklOQihJREVfQkNPVU5UTF9SRUcpOwoJaGlnaGN5bCA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX0JDT1VOVEhfUkVHKTsKCglsZW4gPSBsb3djeWwgKyAoMjU2ICogaGlnaGN5bCk7Cgl0aGlzbGVuID0gcnEtPmRhdGFfbGVuOwoJaWYgKHRoaXNsZW4gPiBsZW4pCgkJdGhpc2xlbiA9IGxlbjsKCgkvKgoJICogSWYgRFJRIGlzIGNsZWFyLCB0aGUgY29tbWFuZCBoYXMgY29tcGxldGVkLgoJICovCglpZiAoKHN0YXQgJiBEUlFfU1RBVCkgPT0gMCkKCQlnb3RvIGVuZF9yZXF1ZXN0OwoKCS8qCgkgKiBjaGVjayB3aGljaCB3YXkgdG8gdHJhbnNmZXIgZGF0YQoJICovCglpZiAocnFfZGF0YV9kaXIocnEpID09IFdSSVRFKSB7CgkJLyoKCQkgKiB3cml0ZSB0byBkcml2ZQoJCSAqLwoJCWlmIChjZHJvbV93cml0ZV9jaGVja19pcmVhc29uKGRyaXZlLCBsZW4sIGlyZWFzb24pKQoJCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgoJCXhmZXJmdW5jID0gSFdJRihkcml2ZSktPmF0YXBpX291dHB1dF9ieXRlczsKCX0gZWxzZSAgewoJCS8qCgkJICogcmVhZCBmcm9tIGRyaXZlCgkJICovCgkJaWYgKGNkcm9tX3JlYWRfY2hlY2tfaXJlYXNvbihkcml2ZSwgbGVuLCBpcmVhc29uKSkKCQkJcmV0dXJuIGlkZV9zdG9wcGVkOwoKCQl4ZmVyZnVuYyA9IEhXSUYoZHJpdmUpLT5hdGFwaV9pbnB1dF9ieXRlczsKCX0KCgkvKgoJICogdHJhbnNmZXIgZGF0YQoJICovCgl3aGlsZSAodGhpc2xlbiA+IDApIHsKCQlpbnQgYmxlbiA9IGJsZW4gPSBycS0+ZGF0YV9sZW47CgkJY2hhciAqcHRyID0gcnEtPmRhdGE7CgoJCS8qCgkJICogYmlvIGJhY2tlZD8KCQkgKi8KCQlpZiAocnEtPmJpbykgewoJCQlwdHIgPSBiaW9fZGF0YShycS0+YmlvKTsKCQkJYmxlbiA9IGJpb19pb3ZlYyhycS0+YmlvKS0+YnZfbGVuOwoJCX0KCgkJaWYgKCFwdHIpIHsKCQkJcHJpbnRrKEtFUk5fRVJSICIlczogY29uZnVzZWQsIG1pc3NpbmcgZGF0YVxuIiwgZHJpdmUtPm5hbWUpOwoJCQlicmVhazsKCQl9CgoJCWlmIChibGVuID4gdGhpc2xlbikKCQkJYmxlbiA9IHRoaXNsZW47CgoJCXhmZXJmdW5jKGRyaXZlLCBwdHIsIGJsZW4pOwoKCQl0aGlzbGVuIC09IGJsZW47CgkJbGVuIC09IGJsZW47CgkJcnEtPmRhdGFfbGVuIC09IGJsZW47CgoJCWlmIChycS0+YmlvKQoJCQllbmRfdGhhdF9yZXF1ZXN0X2NodW5rKHJxLCAxLCBibGVuKTsKCQllbHNlCgkJCXJxLT5kYXRhICs9IGJsZW47Cgl9CgoJLyoKCSAqIHBhZCwgaWYgbmVjZXNzYXJ5CgkgKi8KCWlmIChsZW4gPiAwKSB7CgkJd2hpbGUgKGxlbiA+IDApIHsKCQkJaW50IHBhZCA9IDA7CgoJCQl4ZmVyZnVuYyhkcml2ZSwgJnBhZCwgc2l6ZW9mKHBhZCkpOwoJCQlsZW4gLT0gc2l6ZW9mKHBhZCk7CgkJfQoJfQoKCWlmIChIV0dST1VQKGRyaXZlKS0+aGFuZGxlciAhPSBOVUxMKQoJCUJVRygpOwoKCWlkZV9zZXRfaGFuZGxlcihkcml2ZSwgY2Ryb21fbmV3cGNfaW50ciwgcnEtPnRpbWVvdXQsIE5VTEwpOwoJcmV0dXJuIGlkZV9zdGFydGVkOwoKZW5kX3JlcXVlc3Q6CglpZiAoIXJxLT5kYXRhX2xlbikKCQlwb3N0X3RyYW5zZm9ybV9jb21tYW5kKHJxKTsKCglzcGluX2xvY2tfaXJxc2F2ZSgmaWRlX2xvY2ssIGZsYWdzKTsKCWJsa2Rldl9kZXF1ZXVlX3JlcXVlc3QocnEpOwoJZW5kX3RoYXRfcmVxdWVzdF9sYXN0KHJxKTsKCUhXR1JPVVAoZHJpdmUpLT5ycSA9IE5VTEw7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZpZGVfbG9jaywgZmxhZ3MpOwoJcmV0dXJuIGlkZV9zdG9wcGVkOwp9CgpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX3dyaXRlX2ludHIoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglpbnQgc3RhdCwgaXJlYXNvbiwgbGVuLCBzZWN0b3JzX3RvX3RyYW5zZmVyLCB1cHRvZGF0ZTsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJaW50IGRtYV9lcnJvciA9IDAsIGRtYSA9IGluZm8tPmRtYTsKCXU4IGxvd2N5bCA9IDAsIGhpZ2hjeWwgPSAwOwoKCXN0cnVjdCByZXF1ZXN0ICpycSA9IEhXR1JPVVAoZHJpdmUpLT5ycTsKCgkvKiBDaGVjayBmb3IgZXJyb3JzLiAqLwoJaWYgKGRtYSkgewoJCWluZm8tPmRtYSA9IDA7CgkJaWYgKChkbWFfZXJyb3IgPSBIV0lGKGRyaXZlKS0+aWRlX2RtYV9lbmQoZHJpdmUpKSkgewoJCQlwcmludGsoS0VSTl9FUlIgImlkZS1jZDogd3JpdGUgZG1hIGVycm9yXG4iKTsKCQkJX19pZGVfZG1hX29mZihkcml2ZSk7CgkJfQoJfQoKCWlmIChjZHJvbV9kZWNvZGVfc3RhdHVzKGRyaXZlLCAwLCAmc3RhdCkpCgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoKCS8qCgkgKiB1c2luZyBkbWEsIHRyYW5zZmVyIGlzIGNvbXBsZXRlIG5vdwoJICovCglpZiAoZG1hKSB7CgkJaWYgKGRtYV9lcnJvcikKCQkJcmV0dXJuIGlkZV9lcnJvcihkcml2ZSwgImRtYSBlcnJvciIsIHN0YXQpOwoKCQlpZGVfZW5kX3JlcXVlc3QoZHJpdmUsIDEsIHJxLT5ucl9zZWN0b3JzKTsKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7Cgl9CgoJLyogUmVhZCB0aGUgaW50ZXJydXB0IHJlYXNvbiBhbmQgdGhlIHRyYW5zZmVyIGxlbmd0aC4gKi8KCWlyZWFzb24gPSBIV0lGKGRyaXZlKS0+SU5CKElERV9JUkVBU09OX1JFRyk7Cglsb3djeWwgID0gSFdJRihkcml2ZSktPklOQihJREVfQkNPVU5UTF9SRUcpOwoJaGlnaGN5bCA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX0JDT1VOVEhfUkVHKTsKCglsZW4gPSBsb3djeWwgKyAoMjU2ICogaGlnaGN5bCk7CgoJLyogSWYgRFJRIGlzIGNsZWFyLCB0aGUgY29tbWFuZCBoYXMgY29tcGxldGVkLiAqLwoJaWYgKChzdGF0ICYgRFJRX1NUQVQpID09IDApIHsKCQkvKiBJZiB3ZSdyZSBub3QgZG9uZSB3cml0aW5nLCBjb21wbGFpbi4KCQkgKiBPdGhlcndpc2UsIGNvbXBsZXRlIHRoZSBjb21tYW5kIG5vcm1hbGx5LgoJCSAqLwoJCXVwdG9kYXRlID0gMTsKCQlpZiAocnEtPmN1cnJlbnRfbnJfc2VjdG9ycyA+IDApIHsKCQkJcHJpbnRrKEtFUk5fRVJSICIlczogd3JpdGVfaW50cjogZGF0YSB1bmRlcnJ1biAoJWQgYmxvY2tzKVxuIiwKCQkJZHJpdmUtPm5hbWUsIHJxLT5jdXJyZW50X25yX3NlY3RvcnMpOwoJCQl1cHRvZGF0ZSA9IDA7CgkJfQoJCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCB1cHRvZGF0ZSk7CgkJcmV0dXJuIGlkZV9zdG9wcGVkOwoJfQoKCS8qIENoZWNrIHRoYXQgdGhlIGRyaXZlIGlzIGV4cGVjdGluZyB0byBkbyB0aGUgc2FtZSB0aGluZyB3ZSBhcmUuICovCglpZiAoY2Ryb21fd3JpdGVfY2hlY2tfaXJlYXNvbihkcml2ZSwgbGVuLCBpcmVhc29uKSkKCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgoJc2VjdG9yc190b190cmFuc2ZlciA9IGxlbiAvIFNFQ1RPUl9TSVpFOwoKCS8qCgkgKiBub3cgbG9vcCBhbmQgd3JpdGUgb3V0IHRoZSBkYXRhCgkgKi8KCXdoaWxlIChzZWN0b3JzX3RvX3RyYW5zZmVyID4gMCkgewoJCWludCB0aGlzX3RyYW5zZmVyOwoKCQlpZiAoIXJxLT5jdXJyZW50X25yX3NlY3RvcnMpIHsKCQkJcHJpbnRrKEtFUk5fRVJSICJpZGUtY2Q6IHdyaXRlX2ludHI6IG9vcHNcbiIpOwoJCQlicmVhazsKCQl9CgoJCS8qCgkJICogRmlndXJlIG91dCBob3cgbWFueSBzZWN0b3JzIHdlIGNhbiB0cmFuc2ZlcgoJCSAqLwoJCXRoaXNfdHJhbnNmZXIgPSBtaW5fdChpbnQsIHNlY3RvcnNfdG9fdHJhbnNmZXIsIHJxLT5jdXJyZW50X25yX3NlY3RvcnMpOwoKCQl3aGlsZSAodGhpc190cmFuc2ZlciA+IDApIHsKCQkJSFdJRihkcml2ZSktPmF0YXBpX291dHB1dF9ieXRlcyhkcml2ZSwgcnEtPmJ1ZmZlciwgU0VDVE9SX1NJWkUpOwoJCQlycS0+YnVmZmVyICs9IFNFQ1RPUl9TSVpFOwoJCQktLXJxLT5ucl9zZWN0b3JzOwoJCQktLXJxLT5jdXJyZW50X25yX3NlY3RvcnM7CgkJCSsrcnEtPnNlY3RvcjsKCQkJLS10aGlzX3RyYW5zZmVyOwoJCQktLXNlY3RvcnNfdG9fdHJhbnNmZXI7CgkJfQoKCQkvKgoJCSAqIGN1cnJlbnQgYnVmZmVyIGNvbXBsZXRlLCBtb3ZlIG9uCgkJICovCgkJaWYgKHJxLT5jdXJyZW50X25yX3NlY3RvcnMgPT0gMCAmJiBycS0+bnJfc2VjdG9ycykKCQkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDEpOwoJfQoKCS8qIHJlLWFybSBoYW5kbGVyICovCglpZGVfc2V0X2hhbmRsZXIoZHJpdmUsICZjZHJvbV93cml0ZV9pbnRyLCBBVEFQSV9XQUlUX1BDLCBOVUxMKTsKCXJldHVybiBpZGVfc3RhcnRlZDsKfQoKc3RhdGljIGlkZV9zdGFydHN0b3BfdCBjZHJvbV9zdGFydF93cml0ZV9jb250KGlkZV9kcml2ZV90ICpkcml2ZSkKewoJc3RydWN0IHJlcXVlc3QgKnJxID0gSFdHUk9VUChkcml2ZSktPnJxOwoKI2lmIDAJLyogdGhlIGltbWVkaWF0ZSBiaXQgKi8KCXJxLT5jbWRbMV0gPSAxIDw8IDM7CiNlbmRpZgoJcnEtPnRpbWVvdXQgPSBBVEFQSV9XQUlUX1BDOwoKCXJldHVybiBjZHJvbV90cmFuc2Zlcl9wYWNrZXRfY29tbWFuZChkcml2ZSwgcnEsIGNkcm9tX3dyaXRlX2ludHIpOwp9CgpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX3N0YXJ0X3dyaXRlKGlkZV9kcml2ZV90ICpkcml2ZSwgc3RydWN0IHJlcXVlc3QgKnJxKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXN0cnVjdCBnZW5kaXNrICpnID0gaW5mby0+ZGlzazsKCXVuc2lnbmVkIHNob3J0IHNlY3RvcnNfcGVyX2ZyYW1lID0gcXVldWVfaGFyZHNlY3Rfc2l6ZShkcml2ZS0+cXVldWUpID4+IFNFQ1RPUl9CSVRTOwoKCS8qCgkgKiB3cml0ZXMgKm11c3QqIGJlIGhhcmR3YXJlIGZyYW1lIGFsaWduZWQKCSAqLwoJaWYgKChycS0+bnJfc2VjdG9ycyAmIChzZWN0b3JzX3Blcl9mcmFtZSAtIDEpKSB8fAoJICAgIChycS0+c2VjdG9yICYgKHNlY3RvcnNfcGVyX2ZyYW1lIC0gMSkpKSB7CgkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDApOwoJCXJldHVybiBpZGVfc3RvcHBlZDsKCX0KCgkvKgoJICogZGlzayBoYXMgYmVjb21lIHdyaXRlIHByb3RlY3RlZAoJICovCglpZiAoZy0+cG9saWN5KSB7CgkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDApOwoJCXJldHVybiBpZGVfc3RvcHBlZDsKCX0KCgkvKgoJICogZm9yIGR2ZC1yYW0gYW5kIHN1Y2ggbWVkaWEsIGl0J3MgYSByZWFsbHkgYmlnIGRlYWwgdG8gZ2V0CgkgKiBiaWcgd3JpdGVzIGFsbCB0aGUgdGltZS4gc28gc2NvdXIgdGhlIHF1ZXVlIGFuZCBhdHRlbXB0IHRvCgkgKiByZW1lcmdlIHJlcXVlc3RzLCBvZnRlbiB0aGUgcGx1Z2dpbmcgd2lsbCBub3QgaGF2ZSBoYWQgdGltZQoJICogdG8gZG8gdGhpcyBwcm9wZXJseQoJICovCglibGtfYXR0ZW1wdF9yZW1lcmdlKGRyaXZlLT5xdWV1ZSwgcnEpOwoKCWluZm8tPm5zZWN0b3JzX2J1ZmZlcmVkID0gMDsKCgkvKiB1c2UgZG1hLCBpZiBwb3NzaWJsZS4gd2UgZG9uJ3QgbmVlZCB0byBjaGVjayBtb3JlLCBzaW5jZSB3ZQoJICoga25vdyB0aGF0IHRoZSB0cmFuc2ZlciBpcyBhbHdheXMgKGF0IGxlYXN0ISkgZnJhbWUgYWxpZ25lZCAqLwoJaW5mby0+ZG1hID0gZHJpdmUtPnVzaW5nX2RtYSA/IDEgOiAwOwoJaW5mby0+Y21kID0gV1JJVEU7CgoJaW5mby0+ZGV2aW5mby5tZWRpYV93cml0dGVuID0gMTsKCgkvKiBTdGFydCBzZW5kaW5nIHRoZSB3cml0ZSByZXF1ZXN0IHRvIHRoZSBkcml2ZS4gKi8KCXJldHVybiBjZHJvbV9zdGFydF9wYWNrZXRfY29tbWFuZChkcml2ZSwgMzI3NjgsIGNkcm9tX3N0YXJ0X3dyaXRlX2NvbnQpOwp9CgpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90IGNkcm9tX2RvX25ld3BjX2NvbnQoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgcmVxdWVzdCAqcnEgPSBIV0dST1VQKGRyaXZlKS0+cnE7CgoJaWYgKCFycS0+dGltZW91dCkKCQlycS0+dGltZW91dCA9IEFUQVBJX1dBSVRfUEM7CgoJcmV0dXJuIGNkcm9tX3RyYW5zZmVyX3BhY2tldF9jb21tYW5kKGRyaXZlLCBycSwgY2Ryb21fbmV3cGNfaW50cik7Cn0KCnN0YXRpYyBpZGVfc3RhcnRzdG9wX3QgY2Ryb21fZG9fYmxvY2tfcGMoaWRlX2RyaXZlX3QgKmRyaXZlLCBzdHJ1Y3QgcmVxdWVzdCAqcnEpCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoKCXJxLT5mbGFncyB8PSBSRVFfUVVJRVQ7CgoJaW5mby0+ZG1hID0gMDsKCWluZm8tPmNtZCA9IDA7CgoJLyoKCSAqIHNnIHJlcXVlc3QKCSAqLwoJaWYgKHJxLT5iaW8pIHsKCQlpbnQgbWFzayA9IGRyaXZlLT5xdWV1ZS0+ZG1hX2FsaWdubWVudDsKCQl1bnNpZ25lZCBsb25nIGFkZHIgPSAodW5zaWduZWQgbG9uZykgcGFnZV9hZGRyZXNzKGJpb19wYWdlKHJxLT5iaW8pKTsKCgkJaW5mby0+Y21kID0gcnFfZGF0YV9kaXIocnEpOwoJCWluZm8tPmRtYSA9IGRyaXZlLT51c2luZ19kbWE7CgoJCS8qCgkJICogY2hlY2sgaWYgZG1hIGlzIHNhZmUKCQkgKgoJCSAqIE5PVEUhIFRoZSAibGVuIiBhbmQgImFkZHIiIGNoZWNrcyBzaG91bGQgcG9zc2libHkgaGF2ZQoJCSAqIHNlcGFyYXRlIG1hc2tzLgoJCSAqLwoJCWlmICgocnEtPmRhdGFfbGVuICYgMTUpIHx8IChhZGRyICYgbWFzaykpCgkJCWluZm8tPmRtYSA9IDA7Cgl9CgoJLyogU3RhcnQgc2VuZGluZyB0aGUgY29tbWFuZCB0byB0aGUgZHJpdmUuICovCglyZXR1cm4gY2Ryb21fc3RhcnRfcGFja2V0X2NvbW1hbmQoZHJpdmUsIHJxLT5kYXRhX2xlbiwgY2Ryb21fZG9fbmV3cGNfY29udCk7Cn0KCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIGNkcm9tIGRyaXZlciByZXF1ZXN0IHJvdXRpbmUuCiAqLwpzdGF0aWMgaWRlX3N0YXJ0c3RvcF90CmlkZV9kb19yd19jZHJvbSAoaWRlX2RyaXZlX3QgKmRyaXZlLCBzdHJ1Y3QgcmVxdWVzdCAqcnEsIHNlY3Rvcl90IGJsb2NrKQp7CglpZGVfc3RhcnRzdG9wX3QgYWN0aW9uOwoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CgoJaWYgKGJsa19mc19yZXF1ZXN0KHJxKSkgewoJCWlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5zZWVraW5nKSB7CgkJCXVuc2lnbmVkIGxvbmcgZWxhcHNlZCA9IGppZmZpZXMgLSBpbmZvLT5zdGFydF9zZWVrOwoJCQlpbnQgc3RhdCA9IEhXSUYoZHJpdmUpLT5JTkIoSURFX1NUQVRVU19SRUcpOwoKCQkJaWYgKChzdGF0ICYgU0VFS19TVEFUKSAhPSBTRUVLX1NUQVQpIHsKCQkJCWlmIChlbGFwc2VkIDwgSURFQ0RfU0VFS19USU1FT1VUKSB7CgkJCQkJaWRlX3N0YWxsX3F1ZXVlKGRyaXZlLCBJREVDRF9TRUVLX1RJTUVSKTsKCQkJCQlyZXR1cm4gaWRlX3N0b3BwZWQ7CgkJCQl9CgkJCQlwcmludGsgKEtFUk5fRVJSICIlczogRFNDIHRpbWVvdXRcbiIsIGRyaXZlLT5uYW1lKTsKCQkJfQoJCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5zZWVraW5nID0gMDsKCQl9CgkJaWYgKChycV9kYXRhX2RpcihycSkgPT0gUkVBRCkgJiYgSURFX0xBUkdFX1NFRUsoaW5mby0+bGFzdF9ibG9jaywgYmxvY2ssIElERUNEX1NFRUtfVEhSRVNIT0xEKSAmJiBkcml2ZS0+ZHNjX292ZXJsYXApIHsKCQkJYWN0aW9uID0gY2Ryb21fc3RhcnRfc2Vlayhkcml2ZSwgYmxvY2spOwoJCX0gZWxzZSB7CgkJCWlmIChycV9kYXRhX2RpcihycSkgPT0gUkVBRCkKCQkJCWFjdGlvbiA9IGNkcm9tX3N0YXJ0X3JlYWQoZHJpdmUsIGJsb2NrKTsKCQkJZWxzZQoJCQkJYWN0aW9uID0gY2Ryb21fc3RhcnRfd3JpdGUoZHJpdmUsIHJxKTsKCQl9CgkJaW5mby0+bGFzdF9ibG9jayA9IGJsb2NrOwoJCXJldHVybiBhY3Rpb247Cgl9IGVsc2UgaWYgKHJxLT5mbGFncyAmIChSRVFfUEMgfCBSRVFfU0VOU0UpKSB7CgkJcmV0dXJuIGNkcm9tX2RvX3BhY2tldF9jb21tYW5kKGRyaXZlKTsKCX0gZWxzZSBpZiAocnEtPmZsYWdzICYgUkVRX0JMT0NLX1BDKSB7CgkJcmV0dXJuIGNkcm9tX2RvX2Jsb2NrX3BjKGRyaXZlLCBycSk7Cgl9IGVsc2UgaWYgKHJxLT5mbGFncyAmIFJFUV9TUEVDSUFMKSB7CgkJLyoKCQkgKiByaWdodCBub3cgdGhpcyBjYW4gb25seSBiZSBhIHJlc2V0Li4uCgkJICovCgkJY2Ryb21fZW5kX3JlcXVlc3QoZHJpdmUsIDEpOwoJCXJldHVybiBpZGVfc3RvcHBlZDsKCX0KCglibGtfZHVtcF9ycV9mbGFncyhycSwgImlkZS1jZCBiYWQgZmxhZ3MiKTsKCWNkcm9tX2VuZF9yZXF1ZXN0KGRyaXZlLCAwKTsKCXJldHVybiBpZGVfc3RvcHBlZDsKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBJb2N0bCBoYW5kbGluZy4KICoKICogUm91dGluZXMgd2hpY2ggcXVldWUgcGFja2V0IGNvbW1hbmRzIHRha2UgYXMgYSBmaW5hbCBhcmd1bWVudCBhIHBvaW50ZXIKICogdG8gYSByZXF1ZXN0X3NlbnNlIHN0cnVjdC4gIElmIGV4ZWN1dGlvbiBvZiB0aGUgY29tbWFuZCByZXN1bHRzCiAqIGluIGFuIGVycm9yIHdpdGggYSBDSEVDSyBDT05ESVRJT04gc3RhdHVzLCB0aGlzIHN0cnVjdHVyZSB3aWxsIGJlIGZpbGxlZAogKiB3aXRoIHRoZSByZXN1bHRzIG9mIHRoZSBzdWJzZXF1ZW50IHJlcXVlc3Qgc2Vuc2UgY29tbWFuZC4gIFRoZSBwb2ludGVyCiAqIGNhbiBhbHNvIGJlIE5VTEwsIGluIHdoaWNoIGNhc2Ugbm8gc2Vuc2UgaW5mb3JtYXRpb24gaXMgcmV0dXJuZWQuCiAqLwoKI2lmICEgU1RBTkRBUkRfQVRBUEkKc3RhdGljIGlubGluZQppbnQgYmluMmJjZCAoaW50IHgpCnsKCXJldHVybiAoeCUxMCkgfCAoKHgvMTApIDw8IDQpOwp9CgoKc3RhdGljIGlubGluZQppbnQgYmNkMmJpbiAoaW50IHgpCnsKCXJldHVybiAoeCA+PiA0KSAqIDEwICsgKHggJiAweDBmKTsKfQoKc3RhdGljCnZvaWQgbXNmX2Zyb21fYmNkIChzdHJ1Y3QgYXRhcGlfbXNmICptc2YpCnsKCW1zZi0+bWludXRlID0gYmNkMmJpbiAobXNmLT5taW51dGUpOwoJbXNmLT5zZWNvbmQgPSBiY2QyYmluIChtc2YtPnNlY29uZCk7Cgltc2YtPmZyYW1lICA9IGJjZDJiaW4gKG1zZi0+ZnJhbWUpOwp9CgojZW5kaWYgLyogbm90IFNUQU5EQVJEX0FUQVBJICovCgoKc3RhdGljIGlubGluZQp2b2lkIGxiYV90b19tc2YgKGludCBsYmEsIGJ5dGUgKm0sIGJ5dGUgKnMsIGJ5dGUgKmYpCnsKCWxiYSArPSBDRF9NU0ZfT0ZGU0VUOwoJbGJhICY9IDB4ZmZmZmZmOyAgLyogbmVnYXRpdmUgbGJhcyB1c2Ugb25seSAyNCBiaXRzICovCgkqbSA9IGxiYSAvIChDRF9TRUNTICogQ0RfRlJBTUVTKTsKCWxiYSAlPSAoQ0RfU0VDUyAqIENEX0ZSQU1FUyk7CgkqcyA9IGxiYSAvIENEX0ZSQU1FUzsKCSpmID0gbGJhICUgQ0RfRlJBTUVTOwp9CgoKc3RhdGljIGlubGluZQppbnQgbXNmX3RvX2xiYSAoYnl0ZSBtLCBieXRlIHMsIGJ5dGUgZikKewoJcmV0dXJuICgoKG0gKiBDRF9TRUNTKSArIHMpICogQ0RfRlJBTUVTICsgZikgLSBDRF9NU0ZfT0ZGU0VUOwp9CgpzdGF0aWMgaW50IGNkcm9tX2NoZWNrX3N0YXR1cyhpZGVfZHJpdmVfdCAqZHJpdmUsIHN0cnVjdCByZXF1ZXN0X3NlbnNlICpzZW5zZSkKewoJc3RydWN0IHJlcXVlc3QgcmVxOwoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSA9ICZpbmZvLT5kZXZpbmZvOwoKCWNkcm9tX3ByZXBhcmVfcmVxdWVzdChkcml2ZSwgJnJlcSk7CgoJcmVxLnNlbnNlID0gc2Vuc2U7CglyZXEuY21kWzBdID0gR1BDTURfVEVTVF9VTklUX1JFQURZOwoJcmVxLmZsYWdzIHw9IFJFUV9RVUlFVDsKCiNpZiAhIFNUQU5EQVJEX0FUQVBJCiAgICAgICAgLyogdGhlIFNhbnlvIDMgQ0QgY2hhbmdlciB1c2VzIGJ5dGUgNyBvZiBURVNUX1VOSVRfUkVBRFkgdG8gCiAgICAgICAgICAgc3dpdGNoIENEcyBpbnN0ZWFkIG9mIHN1cHBvcnRpbmcgdGhlIExPQURfVU5MT0FEIG9wY29kZSAgICovCgoJcmVxLmNtZFs3XSA9IGNkaS0+c2FueW9fc2xvdCAlIDM7CiNlbmRpZiAvKiBub3QgU1RBTkRBUkRfQVRBUEkgKi8KCglyZXR1cm4gY2Ryb21fcXVldWVfcGFja2V0X2NvbW1hbmQoZHJpdmUsICZyZXEpOwp9CgoKLyogTG9jayB0aGUgZG9vciBpZiBMT0NLRkxBRyBpcyBub256ZXJvOyB1bmxvY2sgaXQgb3RoZXJ3aXNlLiAqLwpzdGF0aWMgaW50CmNkcm9tX2xvY2tkb29yKGlkZV9kcml2ZV90ICpkcml2ZSwgaW50IGxvY2tmbGFnLCBzdHJ1Y3QgcmVxdWVzdF9zZW5zZSAqc2Vuc2UpCnsKCXN0cnVjdCByZXF1ZXN0X3NlbnNlIG15X3NlbnNlOwoJc3RydWN0IHJlcXVlc3QgcmVxOwoJaW50IHN0YXQ7CgoJaWYgKHNlbnNlID09IE5VTEwpCgkJc2Vuc2UgPSAmbXlfc2Vuc2U7CgoJLyogSWYgdGhlIGRyaXZlIGNhbm5vdCBsb2NrIHRoZSBkb29yLCBqdXN0IHByZXRlbmQuICovCglpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bm9fZG9vcmxvY2spIHsKCQlzdGF0ID0gMDsKCX0gZWxzZSB7CgkJY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGRyaXZlLCAmcmVxKTsKCQlyZXEuc2Vuc2UgPSBzZW5zZTsKCQlyZXEuY21kWzBdID0gR1BDTURfUFJFVkVOVF9BTExPV19NRURJVU1fUkVNT1ZBTDsKCQlyZXEuY21kWzRdID0gbG9ja2ZsYWcgPyAxIDogMDsKCQlzdGF0ID0gY2Ryb21fcXVldWVfcGFja2V0X2NvbW1hbmQoZHJpdmUsICZyZXEpOwoJfQoKCS8qIElmIHdlIGdvdCBhbiBpbGxlZ2FsIGZpZWxkIGVycm9yLCB0aGUgZHJpdmUKCSAgIHByb2JhYmx5IGNhbm5vdCBsb2NrIHRoZSBkb29yLiAqLwoJaWYgKHN0YXQgIT0gMCAmJgoJICAgIHNlbnNlLT5zZW5zZV9rZXkgPT0gSUxMRUdBTF9SRVFVRVNUICYmCgkgICAgKHNlbnNlLT5hc2MgPT0gMHgyNCB8fCBzZW5zZS0+YXNjID09IDB4MjApKSB7CgkJcHJpbnRrIChLRVJOX0VSUiAiJXM6IGRvb3IgbG9ja2luZyBub3Qgc3VwcG9ydGVkXG4iLAoJCQlkcml2ZS0+bmFtZSk7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bm9fZG9vcmxvY2sgPSAxOwoJCXN0YXQgPSAwOwoJfQoJCgkvKiBubyBtZWRpdW0sIHRoYXQncyBhbHJpZ2h0LiAqLwoJaWYgKHN0YXQgIT0gMCAmJiBzZW5zZS0+c2Vuc2Vfa2V5ID09IE5PVF9SRUFEWSAmJiBzZW5zZS0+YXNjID09IDB4M2EpCgkJc3RhdCA9IDA7CgoJaWYgKHN0YXQgPT0gMCkKCQlDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPmRvb3JfbG9ja2VkID0gbG9ja2ZsYWc7CgoJcmV0dXJuIHN0YXQ7Cn0KCgovKiBFamVjdCB0aGUgZGlzayBpZiBFSkVDVEZMQUcgaXMgMC4KICAgSWYgRUpFQ1RGTEFHIGlzIDEsIHRyeSB0byByZWxvYWQgdGhlIGRpc2suICovCnN0YXRpYyBpbnQgY2Ryb21fZWplY3QoaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgZWplY3RmbGFnLAoJCSAgICAgICBzdHJ1Y3QgcmVxdWVzdF9zZW5zZSAqc2Vuc2UpCnsKCXN0cnVjdCByZXF1ZXN0IHJlcTsKCWNoYXIgbG9laiA9IDB4MDI7CgoJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPm5vX2VqZWN0ICYmICFlamVjdGZsYWcpCgkJcmV0dXJuIC1FRFJJVkVfQ0FOVF9ET19USElTOwoJCgkvKiByZWxvYWQgZmFpbHMgb24gc29tZSBkcml2ZXMsIGlmIHRoZSB0cmF5IGlzIGxvY2tlZCAqLwoJaWYgKENEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+ZG9vcl9sb2NrZWQgJiYgZWplY3RmbGFnKQoJCXJldHVybiAwOwoKCWNkcm9tX3ByZXBhcmVfcmVxdWVzdChkcml2ZSwgJnJlcSk7CgoJLyogb25seSB0ZWxsIGRyaXZlIHRvIGNsb3NlIHRyYXkgaWYgb3BlbiwgaWYgaXQgY2FuIGRvIHRoYXQgKi8KCWlmIChlamVjdGZsYWcgJiYgIUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNsb3NlX3RyYXkpCgkJbG9laiA9IDA7CgoJcmVxLnNlbnNlID0gc2Vuc2U7CglyZXEuY21kWzBdID0gR1BDTURfU1RBUlRfU1RPUF9VTklUOwoJcmVxLmNtZFs0XSA9IGxvZWogfCAoZWplY3RmbGFnICE9IDApOwoJcmV0dXJuIGNkcm9tX3F1ZXVlX3BhY2tldF9jb21tYW5kKGRyaXZlLCAmcmVxKTsKfQoKc3RhdGljIGludCBjZHJvbV9yZWFkX2NhcGFjaXR5KGlkZV9kcml2ZV90ICpkcml2ZSwgdW5zaWduZWQgbG9uZyAqY2FwYWNpdHksCgkJCSAgICAgICB1bnNpZ25lZCBsb25nICpzZWN0b3JzX3Blcl9mcmFtZSwKCQkJICAgICAgIHN0cnVjdCByZXF1ZXN0X3NlbnNlICpzZW5zZSkKewoJc3RydWN0IHsKCQlfX3UzMiBsYmE7CgkJX191MzIgYmxvY2tsZW47Cgl9IGNhcGJ1ZjsKCglpbnQgc3RhdDsKCXN0cnVjdCByZXF1ZXN0IHJlcTsKCgljZHJvbV9wcmVwYXJlX3JlcXVlc3QoZHJpdmUsICZyZXEpOwoKCXJlcS5zZW5zZSA9IHNlbnNlOwoJcmVxLmNtZFswXSA9IEdQQ01EX1JFQURfQ0RWRF9DQVBBQ0lUWTsKCXJlcS5kYXRhID0gKGNoYXIgKikmY2FwYnVmOwoJcmVxLmRhdGFfbGVuID0gc2l6ZW9mKGNhcGJ1Zik7CgoJc3RhdCA9IGNkcm9tX3F1ZXVlX3BhY2tldF9jb21tYW5kKGRyaXZlLCAmcmVxKTsKCWlmIChzdGF0ID09IDApIHsKCQkqY2FwYWNpdHkgPSAxICsgYmUzMl90b19jcHUoY2FwYnVmLmxiYSk7CgkJKnNlY3RvcnNfcGVyX2ZyYW1lID0KCQkJYmUzMl90b19jcHUoY2FwYnVmLmJsb2NrbGVuKSA+PiBTRUNUT1JfQklUUzsKCX0KCglyZXR1cm4gc3RhdDsKfQoKc3RhdGljIGludCBjZHJvbV9yZWFkX3RvY2VudHJ5KGlkZV9kcml2ZV90ICpkcml2ZSwgaW50IHRyYWNrbm8sIGludCBtc2ZfZmxhZywKCQkJCWludCBmb3JtYXQsIGNoYXIgKmJ1ZiwgaW50IGJ1ZmxlbiwKCQkJCXN0cnVjdCByZXF1ZXN0X3NlbnNlICpzZW5zZSkKewoJc3RydWN0IHJlcXVlc3QgcmVxOwoKCWNkcm9tX3ByZXBhcmVfcmVxdWVzdChkcml2ZSwgJnJlcSk7CgoJcmVxLnNlbnNlID0gc2Vuc2U7CglyZXEuZGF0YSA9ICBidWY7CglyZXEuZGF0YV9sZW4gPSBidWZsZW47CglyZXEuZmxhZ3MgfD0gUkVRX1FVSUVUOwoJcmVxLmNtZFswXSA9IEdQQ01EX1JFQURfVE9DX1BNQV9BVElQOwoJcmVxLmNtZFs2XSA9IHRyYWNrbm87CglyZXEuY21kWzddID0gKGJ1ZmxlbiA+PiA4KTsKCXJlcS5jbWRbOF0gPSAoYnVmbGVuICYgMHhmZik7CglyZXEuY21kWzldID0gKGZvcm1hdCA8PCA2KTsKCglpZiAobXNmX2ZsYWcpCgkJcmVxLmNtZFsxXSA9IDI7CgoJcmV0dXJuIGNkcm9tX3F1ZXVlX3BhY2tldF9jb21tYW5kKGRyaXZlLCAmcmVxKTsKfQoKCi8qIFRyeSB0byByZWFkIHRoZSBlbnRpcmUgVE9DIGZvciB0aGUgZGlzayBpbnRvIG91ciBpbnRlcm5hbCBidWZmZXIuICovCnN0YXRpYyBpbnQgY2Ryb21fcmVhZF90b2MoaWRlX2RyaXZlX3QgKmRyaXZlLCBzdHJ1Y3QgcmVxdWVzdF9zZW5zZSAqc2Vuc2UpCnsKCWludCBzdGF0LCBudHJhY2tzLCBpOwoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSA9ICZpbmZvLT5kZXZpbmZvOwoJc3RydWN0IGF0YXBpX3RvYyAqdG9jID0gaW5mby0+dG9jOwoJc3RydWN0IHsKCQlzdHJ1Y3QgYXRhcGlfdG9jX2hlYWRlciBoZHI7CgkJc3RydWN0IGF0YXBpX3RvY19lbnRyeSAgZW50OwoJfSBtc190bXA7Cglsb25nIGxhc3Rfd3JpdHRlbjsKCXVuc2lnbmVkIGxvbmcgc2VjdG9yc19wZXJfZnJhbWUgPSBTRUNUT1JTX1BFUl9GUkFNRTsKCglpZiAodG9jID09IE5VTEwpIHsKCQkvKiBUcnkgdG8gYWxsb2NhdGUgc3BhY2UuICovCgkJdG9jID0gKHN0cnVjdCBhdGFwaV90b2MgKikga21hbGxvYyAoc2l6ZW9mIChzdHJ1Y3QgYXRhcGlfdG9jKSwKCQkJCQkJICAgIEdGUF9LRVJORUwpOwoJCWluZm8tPnRvYyA9IHRvYzsKCQlpZiAodG9jID09IE5VTEwpIHsKCQkJcHJpbnRrIChLRVJOX0VSUiAiJXM6IE5vIGNkcm9tIFRPQyBidWZmZXIhXG4iLCBkcml2ZS0+bmFtZSk7CgkJCXJldHVybiAtRU5PTUVNOwoJCX0KCX0KCgkvKiBDaGVjayB0byBzZWUgaWYgdGhlIGV4aXN0aW5nIGRhdGEgaXMgc3RpbGwgdmFsaWQuCgkgICBJZiBpdCBpcywganVzdCByZXR1cm4uICovCgkodm9pZCkgY2Ryb21fY2hlY2tfc3RhdHVzKGRyaXZlLCBzZW5zZSk7CgoJaWYgKENEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+dG9jX3ZhbGlkKQoJCXJldHVybiAwOwoKCS8qIFRyeSB0byBnZXQgdGhlIHRvdGFsIGNkcm9tIGNhcGFjaXR5IGFuZCBzZWN0b3Igc2l6ZS4gKi8KCXN0YXQgPSBjZHJvbV9yZWFkX2NhcGFjaXR5KGRyaXZlLCAmdG9jLT5jYXBhY2l0eSwgJnNlY3RvcnNfcGVyX2ZyYW1lLAoJCQkJICAgc2Vuc2UpOwoJaWYgKHN0YXQpCgkJdG9jLT5jYXBhY2l0eSA9IDB4MWZmZmZmOwoKCXNldF9jYXBhY2l0eShpbmZvLT5kaXNrLCB0b2MtPmNhcGFjaXR5ICogc2VjdG9yc19wZXJfZnJhbWUpOwoJYmxrX3F1ZXVlX2hhcmRzZWN0X3NpemUoZHJpdmUtPnF1ZXVlLAoJCQkJc2VjdG9yc19wZXJfZnJhbWUgPDwgU0VDVE9SX0JJVFMpOwoKCS8qIEZpcnN0IHJlYWQganVzdCB0aGUgaGVhZGVyLCBzbyB3ZSBrbm93IGhvdyBsb25nIHRoZSBUT0MgaXMuICovCglzdGF0ID0gY2Ryb21fcmVhZF90b2NlbnRyeShkcml2ZSwgMCwgMSwgMCwgKGNoYXIgKikgJnRvYy0+aGRyLAoJCQkJICAgIHNpemVvZihzdHJ1Y3QgYXRhcGlfdG9jX2hlYWRlciksIHNlbnNlKTsKCWlmIChzdGF0KSByZXR1cm4gc3RhdDsKCiNpZiAhIFNUQU5EQVJEX0FUQVBJCglpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dG9jdHJhY2tzX2FzX2JjZCkgewoJCXRvYy0+aGRyLmZpcnN0X3RyYWNrID0gYmNkMmJpbih0b2MtPmhkci5maXJzdF90cmFjayk7CgkJdG9jLT5oZHIubGFzdF90cmFjayAgPSBiY2QyYmluKHRvYy0+aGRyLmxhc3RfdHJhY2spOwoJfQojZW5kaWYgIC8qIG5vdCBTVEFOREFSRF9BVEFQSSAqLwoKCW50cmFja3MgPSB0b2MtPmhkci5sYXN0X3RyYWNrIC0gdG9jLT5oZHIuZmlyc3RfdHJhY2sgKyAxOwoJaWYgKG50cmFja3MgPD0gMCkKCQlyZXR1cm4gLUVJTzsKCWlmIChudHJhY2tzID4gTUFYX1RSQUNLUykKCQludHJhY2tzID0gTUFYX1RSQUNLUzsKCgkvKiBOb3cgcmVhZCB0aGUgd2hvbGUgc2NobWVlci4gKi8KCXN0YXQgPSBjZHJvbV9yZWFkX3RvY2VudHJ5KGRyaXZlLCB0b2MtPmhkci5maXJzdF90cmFjaywgMSwgMCwKCQkJCSAgKGNoYXIgKikmdG9jLT5oZHIsCgkJCQkgICBzaXplb2Yoc3RydWN0IGF0YXBpX3RvY19oZWFkZXIpICsKCQkJCSAgIChudHJhY2tzICsgMSkgKgoJCQkJICAgc2l6ZW9mKHN0cnVjdCBhdGFwaV90b2NfZW50cnkpLCBzZW5zZSk7CgoJaWYgKHN0YXQgJiYgdG9jLT5oZHIuZmlyc3RfdHJhY2sgPiAxKSB7CgkJLyogQ2RzIHdpdGggQ0RJIHRyYWNrcyBvbmx5IGRvbid0IGhhdmUgYW55IFRPQyBlbnRyaWVzLAoJCSAgIGRlc3BpdGUgb2YgdGhpcyB0aGUgcmV0dXJuZWQgdmFsdWVzIGFyZQoJCSAgIGZpcnN0X3RyYWNrID09IGxhc3RfdHJhY2sgPSBudW1iZXIgb2YgQ0RJIHRyYWNrcyArIDEsCgkJICAgc28gdGhhdCB0aGlzIGNhc2UgaXMgaW5kaXN0aW5ndWlzaGFibGUgZnJvbSB0aGUgc2FtZQoJCSAgIGxheW91dCBwbHVzIGFuIGFkZGl0aW9uYWwgYXVkaW8gdHJhY2suCgkJICAgSWYgd2UgZ2V0IGFuIGVycm9yIGZvciB0aGUgcmVndWxhciBjYXNlLCB3ZSBhc3N1bWUKCQkgICBhIENESSB3aXRob3V0IGFkZGl0aW9uYWwgYXVkaW8gdHJhY2tzLiBJbiB0aGlzIGNhc2UKCQkgICB0aGUgcmVhZGFibGUgVE9DIGlzIGVtcHR5IChDREkgdHJhY2tzIGFyZSBub3QgaW5jbHVkZWQpCgkJICAgYW5kIG9ubHkgaG9sZHMgdGhlIExlYWRvdXQgZW50cnkuIEhlaWtvIEVp32ZlbGR0ICovCgkJbnRyYWNrcyA9IDA7CgkJc3RhdCA9IGNkcm9tX3JlYWRfdG9jZW50cnkoZHJpdmUsIENEUk9NX0xFQURPVVQsIDEsIDAsCgkJCQkJICAgKGNoYXIgKikmdG9jLT5oZHIsCgkJCQkJICAgc2l6ZW9mKHN0cnVjdCBhdGFwaV90b2NfaGVhZGVyKSArCgkJCQkJICAgKG50cmFja3MgKyAxKSAqCgkJCQkJICAgc2l6ZW9mKHN0cnVjdCBhdGFwaV90b2NfZW50cnkpLAoJCQkJCSAgIHNlbnNlKTsKCQlpZiAoc3RhdCkgewoJCQlyZXR1cm4gc3RhdDsKCQl9CiNpZiAhIFNUQU5EQVJEX0FUQVBJCgkJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnRvY3RyYWNrc19hc19iY2QpIHsKCQkJdG9jLT5oZHIuZmlyc3RfdHJhY2sgPSBiaW4yYmNkKENEUk9NX0xFQURPVVQpOwoJCQl0b2MtPmhkci5sYXN0X3RyYWNrID0gYmluMmJjZChDRFJPTV9MRUFET1VUKTsKCQl9IGVsc2UKI2VuZGlmICAvKiBub3QgU1RBTkRBUkRfQVRBUEkgKi8KCQl7CgkJCXRvYy0+aGRyLmZpcnN0X3RyYWNrID0gQ0RST01fTEVBRE9VVDsKCQkJdG9jLT5oZHIubGFzdF90cmFjayA9IENEUk9NX0xFQURPVVQ7CgkJfQoJfQoKCWlmIChzdGF0KQoJCXJldHVybiBzdGF0OwoKCXRvYy0+aGRyLnRvY19sZW5ndGggPSBudG9ocyAodG9jLT5oZHIudG9jX2xlbmd0aCk7CgojaWYgISBTVEFOREFSRF9BVEFQSQoJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnRvY3RyYWNrc19hc19iY2QpIHsKCQl0b2MtPmhkci5maXJzdF90cmFjayA9IGJjZDJiaW4odG9jLT5oZHIuZmlyc3RfdHJhY2spOwoJCXRvYy0+aGRyLmxhc3RfdHJhY2sgID0gYmNkMmJpbih0b2MtPmhkci5sYXN0X3RyYWNrKTsKCX0KI2VuZGlmICAvKiBub3QgU1RBTkRBUkRfQVRBUEkgKi8KCglmb3IgKGk9MDsgaTw9bnRyYWNrczsgaSsrKSB7CiNpZiAhIFNUQU5EQVJEX0FUQVBJCgkJaWYgKENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnRvY2FkZHJfYXNfYmNkKSB7CgkJCWlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT50b2N0cmFja3NfYXNfYmNkKQoJCQkJdG9jLT5lbnRbaV0udHJhY2sgPSBiY2QyYmluKHRvYy0+ZW50W2ldLnRyYWNrKTsKCQkJbXNmX2Zyb21fYmNkKCZ0b2MtPmVudFtpXS5hZGRyLm1zZik7CgkJfQojZW5kaWYgIC8qIG5vdCBTVEFOREFSRF9BVEFQSSAqLwoJCXRvYy0+ZW50W2ldLmFkZHIubGJhID0gbXNmX3RvX2xiYSAodG9jLT5lbnRbaV0uYWRkci5tc2YubWludXRlLAoJCQkJCQkgICB0b2MtPmVudFtpXS5hZGRyLm1zZi5zZWNvbmQsCgkJCQkJCSAgIHRvYy0+ZW50W2ldLmFkZHIubXNmLmZyYW1lKTsKCX0KCgkvKiBSZWFkIHRoZSBtdWx0aXNlc3Npb24gaW5mb3JtYXRpb24uICovCglpZiAodG9jLT5oZHIuZmlyc3RfdHJhY2sgIT0gQ0RST01fTEVBRE9VVCkgewoJCS8qIFJlYWQgdGhlIG11bHRpc2Vzc2lvbiBpbmZvcm1hdGlvbi4gKi8KCQlzdGF0ID0gY2Ryb21fcmVhZF90b2NlbnRyeShkcml2ZSwgMCwgMCwgMSwgKGNoYXIgKikmbXNfdG1wLAoJCQkJCSAgIHNpemVvZihtc190bXApLCBzZW5zZSk7CgkJaWYgKHN0YXQpIHJldHVybiBzdGF0OwoKCQl0b2MtPmxhc3Rfc2Vzc2lvbl9sYmEgPSBiZTMyX3RvX2NwdShtc190bXAuZW50LmFkZHIubGJhKTsKCX0gZWxzZSB7CgkJbXNfdG1wLmhkci5maXJzdF90cmFjayA9IG1zX3RtcC5oZHIubGFzdF90cmFjayA9IENEUk9NX0xFQURPVVQ7CgkJdG9jLT5sYXN0X3Nlc3Npb25fbGJhID0gbXNmX3RvX2xiYSgwLCAyLCAwKTsgLyogMG0gMnMgMGYgKi8KCX0KCiNpZiAhIFNUQU5EQVJEX0FUQVBJCglpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dG9jYWRkcl9hc19iY2QpIHsKCQkvKiBSZS1yZWFkIG11bHRpc2Vzc2lvbiBpbmZvcm1hdGlvbiB1c2luZyBNU0YgZm9ybWF0ICovCgkJc3RhdCA9IGNkcm9tX3JlYWRfdG9jZW50cnkoZHJpdmUsIDAsIDEsIDEsIChjaGFyICopJm1zX3RtcCwKCQkJCQkgICBzaXplb2YobXNfdG1wKSwgc2Vuc2UpOwoJCWlmIChzdGF0KQoJCQlyZXR1cm4gc3RhdDsKCgkJbXNmX2Zyb21fYmNkICgmbXNfdG1wLmVudC5hZGRyLm1zZik7CgkJdG9jLT5sYXN0X3Nlc3Npb25fbGJhID0gbXNmX3RvX2xiYShtc190bXAuZW50LmFkZHIubXNmLm1pbnV0ZSwKCQkJCQkgIAkgICBtc190bXAuZW50LmFkZHIubXNmLnNlY29uZCwKCQkJCQkJICAgbXNfdG1wLmVudC5hZGRyLm1zZi5mcmFtZSk7Cgl9CiNlbmRpZiAgLyogbm90IFNUQU5EQVJEX0FUQVBJICovCgoJdG9jLT54YV9mbGFnID0gKG1zX3RtcC5oZHIuZmlyc3RfdHJhY2sgIT0gbXNfdG1wLmhkci5sYXN0X3RyYWNrKTsKCgkvKiBOb3cgdHJ5IHRvIGdldCB0aGUgdG90YWwgY2Ryb20gY2FwYWNpdHkuICovCglzdGF0ID0gY2Ryb21fZ2V0X2xhc3Rfd3JpdHRlbihjZGksICZsYXN0X3dyaXR0ZW4pOwoJaWYgKCFzdGF0ICYmIChsYXN0X3dyaXR0ZW4gPiB0b2MtPmNhcGFjaXR5KSkgewoJCXRvYy0+Y2FwYWNpdHkgPSBsYXN0X3dyaXR0ZW47CgkJc2V0X2NhcGFjaXR5KGluZm8tPmRpc2ssIHRvYy0+Y2FwYWNpdHkgKiBzZWN0b3JzX3Blcl9mcmFtZSk7Cgl9CgoJLyogUmVtZW1iZXIgdGhhdCB3ZSd2ZSByZWFkIHRoaXMgc3R1ZmYuICovCglDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPnRvY192YWxpZCA9IDE7CgoJcmV0dXJuIDA7Cn0KCgpzdGF0aWMgaW50IGNkcm9tX3JlYWRfc3ViY2hhbm5lbChpZGVfZHJpdmVfdCAqZHJpdmUsIGludCBmb3JtYXQsIGNoYXIgKmJ1ZiwKCQkJCSBpbnQgYnVmbGVuLCBzdHJ1Y3QgcmVxdWVzdF9zZW5zZSAqc2Vuc2UpCnsKCXN0cnVjdCByZXF1ZXN0IHJlcTsKCgljZHJvbV9wcmVwYXJlX3JlcXVlc3QoZHJpdmUsICZyZXEpOwoKCXJlcS5zZW5zZSA9IHNlbnNlOwoJcmVxLmRhdGEgPSBidWY7CglyZXEuZGF0YV9sZW4gPSBidWZsZW47CglyZXEuY21kWzBdID0gR1BDTURfUkVBRF9TVUJDSEFOTkVMOwoJcmVxLmNtZFsxXSA9IDI7ICAgICAvKiBNU0YgYWRkcmVzc2luZyAqLwoJcmVxLmNtZFsyXSA9IDB4NDA7ICAvKiByZXF1ZXN0IHN1YlEgZGF0YSAqLwoJcmVxLmNtZFszXSA9IGZvcm1hdDsKCXJlcS5jbWRbN10gPSAoYnVmbGVuID4+IDgpOwoJcmVxLmNtZFs4XSA9IChidWZsZW4gJiAweGZmKTsKCXJldHVybiBjZHJvbV9xdWV1ZV9wYWNrZXRfY29tbWFuZChkcml2ZSwgJnJlcSk7Cn0KCi8qIEFUQVBJIGNkcm9tIGRyaXZlcyBhcmUgZnJlZSB0byBzZWxlY3QgdGhlIHNwZWVkIHlvdSByZXF1ZXN0IG9yIGFueSBzbG93ZXIKICAgcmF0ZSA6LSggUmVxdWVzdGluZyB0b28gZmFzdCBhIHNwZWVkIHdpbGwgX25vdF8gcHJvZHVjZSBhbiBlcnJvci4gKi8Kc3RhdGljIGludCBjZHJvbV9zZWxlY3Rfc3BlZWQoaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgc3BlZWQsCgkJCSAgICAgIHN0cnVjdCByZXF1ZXN0X3NlbnNlICpzZW5zZSkKewoJc3RydWN0IHJlcXVlc3QgcmVxOwoJY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGRyaXZlLCAmcmVxKTsKCglyZXEuc2Vuc2UgPSBzZW5zZTsKCWlmIChzcGVlZCA9PSAwKQoJCXNwZWVkID0gMHhmZmZmOyAvKiBzZXQgdG8gbWF4ICovCgllbHNlCgkJc3BlZWQgKj0gMTc3OyAgIC8qIE54IHRvIGtieXRlcy9zICovCgoJcmVxLmNtZFswXSA9IEdQQ01EX1NFVF9TUEVFRDsKCS8qIFJlYWQgRHJpdmUgc3BlZWQgaW4ga2J5dGVzL3NlY29uZCBNU0IgKi8KCXJlcS5jbWRbMl0gPSAoc3BlZWQgPj4gOCkgJiAweGZmOwkKCS8qIFJlYWQgRHJpdmUgc3BlZWQgaW4ga2J5dGVzL3NlY29uZCBMU0IgKi8KCXJlcS5jbWRbM10gPSBzcGVlZCAmIDB4ZmY7CglpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2RfciB8fAoJICAgIENEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNkX3J3IHx8CgkgICAgQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkX3IpIHsKCQkvKiBXcml0ZSBEcml2ZSBzcGVlZCBpbiBrYnl0ZXMvc2Vjb25kIE1TQiAqLwoJCXJlcS5jbWRbNF0gPSAoc3BlZWQgPj4gOCkgJiAweGZmOwoJCS8qIFdyaXRlIERyaXZlIHNwZWVkIGluIGtieXRlcy9zZWNvbmQgTFNCICovCgkJcmVxLmNtZFs1XSA9IHNwZWVkICYgMHhmZjsKICAgICAgIH0KCglyZXR1cm4gY2Ryb21fcXVldWVfcGFja2V0X2NvbW1hbmQoZHJpdmUsICZyZXEpOwp9CgpzdGF0aWMgaW50IGNkcm9tX3BsYXlfYXVkaW8oaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgbGJhX3N0YXJ0LCBpbnQgbGJhX2VuZCkKewoJc3RydWN0IHJlcXVlc3Rfc2Vuc2Ugc2Vuc2U7CglzdHJ1Y3QgcmVxdWVzdCByZXE7CgoJY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGRyaXZlLCAmcmVxKTsKCglyZXEuc2Vuc2UgPSAmc2Vuc2U7CglyZXEuY21kWzBdID0gR1BDTURfUExBWV9BVURJT19NU0Y7CglsYmFfdG9fbXNmKGxiYV9zdGFydCwgJnJlcS5jbWRbM10sICZyZXEuY21kWzRdLCAmcmVxLmNtZFs1XSk7CglsYmFfdG9fbXNmKGxiYV9lbmQtMSwgJnJlcS5jbWRbNl0sICZyZXEuY21kWzddLCAmcmVxLmNtZFs4XSk7CgoJcmV0dXJuIGNkcm9tX3F1ZXVlX3BhY2tldF9jb21tYW5kKGRyaXZlLCAmcmVxKTsKfQoKc3RhdGljIGludCBjZHJvbV9nZXRfdG9jX2VudHJ5KGlkZV9kcml2ZV90ICpkcml2ZSwgaW50IHRyYWNrLAoJCQkJc3RydWN0IGF0YXBpX3RvY19lbnRyeSAqKmVudCkKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBkcml2ZS0+ZHJpdmVyX2RhdGE7CglzdHJ1Y3QgYXRhcGlfdG9jICp0b2MgPSBpbmZvLT50b2M7CglpbnQgbnRyYWNrczsKCgkvKgoJICogZG9uJ3Qgc2VydmUgY2FjaGVkIGRhdGEsIGlmIHRoZSB0b2MgaXNuJ3QgdmFsaWQKCSAqLwoJaWYgKCFDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPnRvY192YWxpZCkKCQlyZXR1cm4gLUVJTlZBTDsKCgkvKiBDaGVjayB2YWxpZGl0eSBvZiByZXF1ZXN0ZWQgdHJhY2sgbnVtYmVyLiAqLwoJbnRyYWNrcyA9IHRvYy0+aGRyLmxhc3RfdHJhY2sgLSB0b2MtPmhkci5maXJzdF90cmFjayArIDE7CglpZiAodG9jLT5oZHIuZmlyc3RfdHJhY2sgPT0gQ0RST01fTEVBRE9VVCkgbnRyYWNrcyA9IDA7CglpZiAodHJhY2sgPT0gQ0RST01fTEVBRE9VVCkKCQkqZW50ID0gJnRvYy0+ZW50W250cmFja3NdOwoJZWxzZSBpZiAodHJhY2sgPCB0b2MtPmhkci5maXJzdF90cmFjayB8fAoJCSB0cmFjayA+IHRvYy0+aGRyLmxhc3RfdHJhY2spCgkJcmV0dXJuIC1FSU5WQUw7CgllbHNlCgkJKmVudCA9ICZ0b2MtPmVudFt0cmFjayAtIHRvYy0+aGRyLmZpcnN0X3RyYWNrXTsKCglyZXR1cm4gMDsKfQoKLyogdGhlIGdlbmVyaWMgcGFja2V0IGludGVyZmFjZSB0byBjZHJvbS5jICovCnN0YXRpYyBpbnQgaWRlX2Nkcm9tX3BhY2tldChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSwKCQkJICAgIHN0cnVjdCBwYWNrZXRfY29tbWFuZCAqY2djKQp7CglzdHJ1Y3QgcmVxdWVzdCByZXE7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSAoaWRlX2RyaXZlX3QqKSBjZGktPmhhbmRsZTsKCglpZiAoY2djLT50aW1lb3V0IDw9IDApCgkJY2djLT50aW1lb3V0ID0gQVRBUElfV0FJVF9QQzsKCgkvKiBoZXJlIHdlIHF1ZXVlIHRoZSBjb21tYW5kcyBmcm9tIHRoZSB1bmlmb3JtIENELVJPTQoJICAgbGF5ZXIuIHRoZSBwYWNrZXQgbXVzdCBiZSBjb21wbGV0ZSwgYXMgd2UgZG8gbm90CgkgICB0b3VjaCBpdCBhdCBhbGwuICovCgljZHJvbV9wcmVwYXJlX3JlcXVlc3QoZHJpdmUsICZyZXEpOwoJbWVtY3B5KHJlcS5jbWQsIGNnYy0+Y21kLCBDRFJPTV9QQUNLRVRfU0laRSk7CglpZiAoY2djLT5zZW5zZSkKCQltZW1zZXQoY2djLT5zZW5zZSwgMCwgc2l6ZW9mKHN0cnVjdCByZXF1ZXN0X3NlbnNlKSk7CglyZXEuZGF0YSA9IGNnYy0+YnVmZmVyOwoJcmVxLmRhdGFfbGVuID0gY2djLT5idWZsZW47CglyZXEudGltZW91dCA9IGNnYy0+dGltZW91dDsKCglpZiAoY2djLT5xdWlldCkKCQlyZXEuZmxhZ3MgfD0gUkVRX1FVSUVUOwoKCXJlcS5zZW5zZSA9IGNnYy0+c2Vuc2U7CgljZ2MtPnN0YXQgPSBjZHJvbV9xdWV1ZV9wYWNrZXRfY29tbWFuZChkcml2ZSwgJnJlcSk7CglpZiAoIWNnYy0+c3RhdCkKCQljZ2MtPmJ1ZmxlbiAtPSByZXEuZGF0YV9sZW47CglyZXR1cm4gY2djLT5zdGF0Owp9CgpzdGF0aWMKaW50IGlkZV9jZHJvbV9kZXZfaW9jdGwgKHN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpLAoJCQkgdW5zaWduZWQgaW50IGNtZCwgdW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCBwYWNrZXRfY29tbWFuZCBjZ2M7CgljaGFyIGJ1ZmZlclsxNl07CglpbnQgc3RhdDsKCglpbml0X2Nkcm9tX2NvbW1hbmQoJmNnYywgYnVmZmVyLCBzaXplb2YoYnVmZmVyKSwgQ0dDX0RBVEFfVU5LTk9XTik7CgoJLyogVGhlc2Ugd2lsbCBiZSBtb3ZlZCBpbnRvIHRoZSBVbmlmb3JtIGxheWVyIHNob3J0bHkuLi4gKi8KCXN3aXRjaCAoY21kKSB7CiAJY2FzZSBDRFJPTVNFVFNQSU5ET1dOOiB7CiAJCWNoYXIgc3BpbmRvd247CiAKIAkJaWYgKGNvcHlfZnJvbV91c2VyKCZzcGluZG93biwgKHZvaWQgX191c2VyICopIGFyZywgc2l6ZW9mKGNoYXIpKSkKCQkJcmV0dXJuIC1FRkFVTFQ7CiAKICAgICAgICAgICAgICAgIGlmICgoc3RhdCA9IGNkcm9tX21vZGVfc2Vuc2UoY2RpLCAmY2djLCBHUE1PREVfQ0RST01fUEFHRSwgMCkpKQoJCQlyZXR1cm4gc3RhdDsKCiAJCWJ1ZmZlclsxMV0gPSAoYnVmZmVyWzExXSAmIDB4ZjApIHwgKHNwaW5kb3duICYgMHgwZik7CgogCQlyZXR1cm4gY2Ryb21fbW9kZV9zZWxlY3QoY2RpLCAmY2djKTsKIAl9IAogCiAJY2FzZSBDRFJPTUdFVFNQSU5ET1dOOiB7CiAJCWNoYXIgc3BpbmRvd247CiAKICAgICAgICAgICAgICAgIGlmICgoc3RhdCA9IGNkcm9tX21vZGVfc2Vuc2UoY2RpLCAmY2djLCBHUE1PREVfQ0RST01fUEFHRSwgMCkpKQoJCQlyZXR1cm4gc3RhdDsKIAogCQlzcGluZG93biA9IGJ1ZmZlclsxMV0gJiAweDBmOwogCgkJaWYgKGNvcHlfdG9fdXNlcigodm9pZCBfX3VzZXIgKikgYXJnLCAmc3BpbmRvd24sIHNpemVvZiAoY2hhcikpKQoJCQlyZXR1cm4gLUVGQVVMVDsKIAogCQlyZXR1cm4gMDsKIAl9CiAgCglkZWZhdWx0OgoJCXJldHVybiAtRUlOVkFMOwoJfQoKfQoKc3RhdGljCmludCBpZGVfY2Ryb21fYXVkaW9faW9jdGwgKHN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpLAoJCQkgICB1bnNpZ25lZCBpbnQgY21kLCB2b2lkICphcmcpCgkJCSAgIAp7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSAoaWRlX2RyaXZlX3QqKSBjZGktPmhhbmRsZTsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJaW50IHN0YXQ7CgoJc3dpdGNoIChjbWQpIHsKCS8qCgkgKiBlbXVsYXRlIFBMQVlfQVVESU9fVEkgY29tbWFuZCB3aXRoIFBMQVlfQVVESU9fMTAsIHNpbmNlCgkgKiBhdGFwaSBkb2Vzbid0IHN1cHBvcnQgaXQKCSAqLwoJY2FzZSBDRFJPTVBMQVlUUktJTkQ6IHsKCQl1bnNpZ25lZCBsb25nIGxiYV9zdGFydCwgbGJhX2VuZDsKCQlzdHJ1Y3QgY2Ryb21fdGkgKnRpID0gKHN0cnVjdCBjZHJvbV90aSAqKWFyZzsKCQlzdHJ1Y3QgYXRhcGlfdG9jX2VudHJ5ICpmaXJzdF90b2MsICpsYXN0X3RvYzsKCgkJc3RhdCA9IGNkcm9tX2dldF90b2NfZW50cnkoZHJpdmUsIHRpLT5jZHRpX3RyazAsICZmaXJzdF90b2MpOwoJCWlmIChzdGF0KQoJCQlyZXR1cm4gc3RhdDsKCgkJc3RhdCA9IGNkcm9tX2dldF90b2NfZW50cnkoZHJpdmUsIHRpLT5jZHRpX3RyazEsICZsYXN0X3RvYyk7CgkJaWYgKHN0YXQpCgkJCXJldHVybiBzdGF0OwoKCQlpZiAodGktPmNkdGlfdHJrMSAhPSBDRFJPTV9MRUFET1VUKQoJCQkrK2xhc3RfdG9jOwoJCWxiYV9zdGFydCA9IGZpcnN0X3RvYy0+YWRkci5sYmE7CgkJbGJhX2VuZCAgID0gbGFzdF90b2MtPmFkZHIubGJhOwoKCQlpZiAobGJhX2VuZCA8PSBsYmFfc3RhcnQpCgkJCXJldHVybiAtRUlOVkFMOwoKCQlyZXR1cm4gY2Ryb21fcGxheV9hdWRpbyhkcml2ZSwgbGJhX3N0YXJ0LCBsYmFfZW5kKTsKCX0KCgljYXNlIENEUk9NUkVBRFRPQ0hEUjogewoJCXN0cnVjdCBjZHJvbV90b2NoZHIgKnRvY2hkciA9IChzdHJ1Y3QgY2Ryb21fdG9jaGRyICopIGFyZzsKCQlzdHJ1Y3QgYXRhcGlfdG9jICp0b2M7CgoJCS8qIE1ha2Ugc3VyZSBvdXIgc2F2ZWQgVE9DIGlzIHZhbGlkLiAqLwoJCXN0YXQgPSBjZHJvbV9yZWFkX3RvYyhkcml2ZSwgTlVMTCk7CgkJaWYgKHN0YXQpIHJldHVybiBzdGF0OwoKCQl0b2MgPSBpbmZvLT50b2M7CgkJdG9jaGRyLT5jZHRoX3RyazAgPSB0b2MtPmhkci5maXJzdF90cmFjazsKCQl0b2NoZHItPmNkdGhfdHJrMSA9IHRvYy0+aGRyLmxhc3RfdHJhY2s7CgoJCXJldHVybiAwOwoJfQoKCWNhc2UgQ0RST01SRUFEVE9DRU5UUlk6IHsKCQlzdHJ1Y3QgY2Ryb21fdG9jZW50cnkgKnRvY2VudHJ5ID0gKHN0cnVjdCBjZHJvbV90b2NlbnRyeSopIGFyZzsKCQlzdHJ1Y3QgYXRhcGlfdG9jX2VudHJ5ICp0b2NlOwoKCQlzdGF0ID0gY2Ryb21fZ2V0X3RvY19lbnRyeShkcml2ZSwgdG9jZW50cnktPmNkdGVfdHJhY2ssICZ0b2NlKTsKCQlpZiAoc3RhdCkgcmV0dXJuIHN0YXQ7CgoJCXRvY2VudHJ5LT5jZHRlX2N0cmwgPSB0b2NlLT5jb250cm9sOwoJCXRvY2VudHJ5LT5jZHRlX2FkciAgPSB0b2NlLT5hZHI7CgkJaWYgKHRvY2VudHJ5LT5jZHRlX2Zvcm1hdCA9PSBDRFJPTV9NU0YpIHsKCQkJbGJhX3RvX21zZiAodG9jZS0+YWRkci5sYmEsCgkJCQkgICAmdG9jZW50cnktPmNkdGVfYWRkci5tc2YubWludXRlLAoJCQkJICAgJnRvY2VudHJ5LT5jZHRlX2FkZHIubXNmLnNlY29uZCwKCQkJCSAgICZ0b2NlbnRyeS0+Y2R0ZV9hZGRyLm1zZi5mcmFtZSk7CgkJfSBlbHNlCgkJCXRvY2VudHJ5LT5jZHRlX2FkZHIubGJhID0gdG9jZS0+YWRkci5sYmE7CgoJCXJldHVybiAwOwoJfQoKCWRlZmF1bHQ6CgkJcmV0dXJuIC1FSU5WQUw7Cgl9Cn0KCnN0YXRpYwppbnQgaWRlX2Nkcm9tX3Jlc2V0IChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSkKewoJaWRlX2RyaXZlX3QgKmRyaXZlID0gKGlkZV9kcml2ZV90KikgY2RpLT5oYW5kbGU7CglzdHJ1Y3QgcmVxdWVzdF9zZW5zZSBzZW5zZTsKCXN0cnVjdCByZXF1ZXN0IHJlcTsKCWludCByZXQ7CgoJY2Ryb21fcHJlcGFyZV9yZXF1ZXN0KGRyaXZlLCAmcmVxKTsKCXJlcS5mbGFncyA9IFJFUV9TUEVDSUFMIHwgUkVRX1FVSUVUOwoJcmV0ID0gaWRlX2RvX2RyaXZlX2NtZChkcml2ZSwgJnJlcSwgaWRlX3dhaXQpOwoKCS8qCgkgKiBBIHJlc2V0IHdpbGwgdW5sb2NrIHRoZSBkb29yLiBJZiBpdCB3YXMgcHJldmlvdXNseSBsb2NrZWQsCgkgKiBsb2NrIGl0IGFnYWluLgoJICovCglpZiAoQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT5kb29yX2xvY2tlZCkKCQkodm9pZCkgY2Ryb21fbG9ja2Rvb3IoZHJpdmUsIDEsICZzZW5zZSk7CgoJcmV0dXJuIHJldDsKfQoKCnN0YXRpYwppbnQgaWRlX2Nkcm9tX3RyYXlfbW92ZSAoc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGksIGludCBwb3NpdGlvbikKewoJaWRlX2RyaXZlX3QgKmRyaXZlID0gKGlkZV9kcml2ZV90KikgY2RpLT5oYW5kbGU7CglzdHJ1Y3QgcmVxdWVzdF9zZW5zZSBzZW5zZTsKCglpZiAocG9zaXRpb24pIHsKCQlpbnQgc3RhdCA9IGNkcm9tX2xvY2tkb29yKGRyaXZlLCAwLCAmc2Vuc2UpOwoJCWlmIChzdGF0KSByZXR1cm4gc3RhdDsKCX0KCglyZXR1cm4gY2Ryb21fZWplY3QoZHJpdmUsICFwb3NpdGlvbiwgJnNlbnNlKTsKfQoKc3RhdGljCmludCBpZGVfY2Ryb21fbG9ja19kb29yIChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSwgaW50IGxvY2spCnsKCWlkZV9kcml2ZV90ICpkcml2ZSA9IChpZGVfZHJpdmVfdCopIGNkaS0+aGFuZGxlOwoJcmV0dXJuIGNkcm9tX2xvY2tkb29yKGRyaXZlLCBsb2NrLCBOVUxMKTsKfQoKc3RhdGljCmludCBpZGVfY2Ryb21fZ2V0X2NhcGFiaWxpdGllcyhpZGVfZHJpdmVfdCAqZHJpdmUsIHN0cnVjdCBhdGFwaV9jYXBhYmlsaXRpZXNfcGFnZSAqY2FwKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpID0gJmluZm8tPmRldmluZm87CglzdHJ1Y3QgcGFja2V0X2NvbW1hbmQgY2djOwoJaW50IHN0YXQsIGF0dGVtcHRzID0gMywgc2l6ZSA9IHNpemVvZigqY2FwKTsKCgkvKgoJICogQUNFUjUwIChhbmQgb3RoZXJzPykgcmVxdWlyZSB0aGUgZnVsbCBzcGVjIGxlbmd0aCBtb2RlIHNlbnNlCgkgKiBwYWdlIGNhcGFiaWxpdGllcyBzaXplLCBidXQgb2xkZXIgZHJpdmVzIGJyZWFrLgoJICovCglpZiAoISghc3RyY21wKGRyaXZlLT5pZC0+bW9kZWwsICJBVEFQSSBDRCBST00gRFJJVkUgNTBYIE1BWCIpIHx8CgkgICAgIXN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiV1BJIENEUy0zMlgiKSkpCgkJc2l6ZSAtPSBzaXplb2YoY2FwLT5wYWQpOwoKCWluaXRfY2Ryb21fY29tbWFuZCgmY2djLCBjYXAsIHNpemUsIENHQ19EQVRBX1VOS05PV04pOwoJZG8geyAvKiB3ZSBzZWVtIHRvIGdldCBzdGF0PTB4MDEsZXJyPTB4MDAgdGhlIGZpcnN0IHRpbWUgKD8/KSAqLwoJCXN0YXQgPSBjZHJvbV9tb2RlX3NlbnNlKGNkaSwgJmNnYywgR1BNT0RFX0NBUEFCSUxJVElFU19QQUdFLCAwKTsKCQlpZiAoIXN0YXQpCgkJCWJyZWFrOwoJfSB3aGlsZSAoLS1hdHRlbXB0cyk7CglyZXR1cm4gc3RhdDsKfQoKc3RhdGljCnZvaWQgaWRlX2Nkcm9tX3VwZGF0ZV9zcGVlZCAoaWRlX2RyaXZlX3QgKmRyaXZlLCBzdHJ1Y3QgYXRhcGlfY2FwYWJpbGl0aWVzX3BhZ2UgKmNhcCkKewoJLyogVGhlIEFDRVIvQU9wZW4gMjRYIGNkcm9tIGhhcyB0aGUgc3BlZWQgZmllbGRzIGJ5dGUtc3dhcHBlZCAqLwoJaWYgKCFkcml2ZS0+aWQtPm1vZGVsWzBdICYmCgkgICAgIXN0cm5jbXAoZHJpdmUtPmlkLT5md19yZXYsICIyNDFOIiwgNCkpIHsKCQlDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPmN1cnJlbnRfc3BlZWQgID0KCQkJKCgodW5zaWduZWQgaW50KWNhcC0+Y3Vyc3BlZWQpICsgKDE3Ni8yKSkgLyAxNzY7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bWF4X3NwZWVkID0KCQkJKCgodW5zaWduZWQgaW50KWNhcC0+bWF4c3BlZWQpICsgKDE3Ni8yKSkgLyAxNzY7Cgl9IGVsc2UgewoJCUNEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+Y3VycmVudF9zcGVlZCAgPQoJCQkobnRvaHMoY2FwLT5jdXJzcGVlZCkgKyAoMTc2LzIpKSAvIDE3NjsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5tYXhfc3BlZWQgPQoJCQkobnRvaHMoY2FwLT5tYXhzcGVlZCkgKyAoMTc2LzIpKSAvIDE3NjsKCX0KfQoKc3RhdGljCmludCBpZGVfY2Ryb21fc2VsZWN0X3NwZWVkIChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSwgaW50IHNwZWVkKQp7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSAoaWRlX2RyaXZlX3QqKSBjZGktPmhhbmRsZTsKCXN0cnVjdCByZXF1ZXN0X3NlbnNlIHNlbnNlOwoJc3RydWN0IGF0YXBpX2NhcGFiaWxpdGllc19wYWdlIGNhcDsKCWludCBzdGF0OwoKCWlmICgoc3RhdCA9IGNkcm9tX3NlbGVjdF9zcGVlZChkcml2ZSwgc3BlZWQsICZzZW5zZSkpIDwgMCkKCQlyZXR1cm4gc3RhdDsKCglpZiAoIWlkZV9jZHJvbV9nZXRfY2FwYWJpbGl0aWVzKGRyaXZlLCAmY2FwKSkgewoJCWlkZV9jZHJvbV91cGRhdGVfc3BlZWQoZHJpdmUsICZjYXApOwoJCWNkaS0+c3BlZWQgPSBDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPmN1cnJlbnRfc3BlZWQ7Cgl9CiAgICAgICAgcmV0dXJuIDA7Cn0KCi8qCiAqIGFkZCBsb2dpYyB0byB0cnkgR0VUX0VWRU5UIGNvbW1hbmQgZmlyc3QgdG8gY2hlY2sgZm9yIG1lZGlhIGFuZCB0cmF5CiAqIHN0YXR1cy4gdGhpcyBzaG91bGQgYmUgc3VwcG9ydGVkIGJ5IG5ld2VyIGNkLXIvdyBhbmQgYWxsIERWRCBldGMKICogZHJpdmVzCiAqLwpzdGF0aWMKaW50IGlkZV9jZHJvbV9kcml2ZV9zdGF0dXMgKHN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpLCBpbnQgc2xvdF9ucikKewoJaWRlX2RyaXZlX3QgKmRyaXZlID0gKGlkZV9kcml2ZV90KikgY2RpLT5oYW5kbGU7CglzdHJ1Y3QgbWVkaWFfZXZlbnRfZGVzYyBtZWQ7CglzdHJ1Y3QgcmVxdWVzdF9zZW5zZSBzZW5zZTsKCWludCBzdGF0OwoKCWlmIChzbG90X25yICE9IENEU0xfQ1VSUkVOVCkKCQlyZXR1cm4gLUVJTlZBTDsKCglzdGF0ID0gY2Ryb21fY2hlY2tfc3RhdHVzKGRyaXZlLCAmc2Vuc2UpOwoJaWYgKCFzdGF0IHx8IHNlbnNlLnNlbnNlX2tleSA9PSBVTklUX0FUVEVOVElPTikKCQlyZXR1cm4gQ0RTX0RJU0NfT0s7CgoJaWYgKCFjZHJvbV9nZXRfbWVkaWFfZXZlbnQoY2RpLCAmbWVkKSkgewoJCWlmIChtZWQubWVkaWFfcHJlc2VudCkKCQkJcmV0dXJuIENEU19ESVNDX09LOwoJCWVsc2UgaWYgKG1lZC5kb29yX29wZW4pCgkJCXJldHVybiBDRFNfVFJBWV9PUEVOOwoJCWVsc2UKCQkJcmV0dXJuIENEU19OT19ESVNDOwoJfQoKCWlmIChzZW5zZS5zZW5zZV9rZXkgPT0gTk9UX1JFQURZICYmIHNlbnNlLmFzYyA9PSAweDA0ICYmIHNlbnNlLmFzY3EgPT0gMHgwNCkKCQlyZXR1cm4gQ0RTX0RJU0NfT0s7CgoJLyoKCSAqIElmIG5vdCB1c2luZyBNdCBGdWppIGV4dGVuZGVkIG1lZGlhIHRyYXkgcmVwb3J0cywKCSAqIGp1c3QgcmV0dXJuIFRSQVlfT1BFTiBzaW5jZSBBVEFQSSBkb2Vzbid0IHByb3ZpZGUKCSAqIGFueSBvdGhlciB3YXkgdG8gZGV0ZWN0IHRoaXMuLi4KCSAqLwoJaWYgKHNlbnNlLnNlbnNlX2tleSA9PSBOT1RfUkVBRFkpIHsKCQlpZiAoc2Vuc2UuYXNjID09IDB4M2EpIHsKCQkJaWYgKHNlbnNlLmFzY3EgPT0gMSkKCQkJCXJldHVybiBDRFNfTk9fRElTQzsKCQkJZWxzZSBpZiAoc2Vuc2UuYXNjcSA9PSAwIHx8IHNlbnNlLmFzY3EgPT0gMikKCQkJCXJldHVybiBDRFNfVFJBWV9PUEVOOwoJCX0KCX0KCglyZXR1cm4gQ0RTX0RSSVZFX05PVF9SRUFEWTsKfQoKc3RhdGljCmludCBpZGVfY2Ryb21fZ2V0X2xhc3Rfc2Vzc2lvbiAoc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGksCgkJCQlzdHJ1Y3QgY2Ryb21fbXVsdGlzZXNzaW9uICptc19pbmZvKQp7CglzdHJ1Y3QgYXRhcGlfdG9jICp0b2M7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSAoaWRlX2RyaXZlX3QqKSBjZGktPmhhbmRsZTsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJc3RydWN0IHJlcXVlc3Rfc2Vuc2Ugc2Vuc2U7CglpbnQgcmV0OwoKCWlmICghQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT50b2NfdmFsaWQgfHwgaW5mby0+dG9jID09IE5VTEwpCgkJaWYgKChyZXQgPSBjZHJvbV9yZWFkX3RvYyhkcml2ZSwgJnNlbnNlKSkpCgkJCXJldHVybiByZXQ7CgoJdG9jID0gaW5mby0+dG9jOwoJbXNfaW5mby0+YWRkci5sYmEgPSB0b2MtPmxhc3Rfc2Vzc2lvbl9sYmE7Cgltc19pbmZvLT54YV9mbGFnID0gdG9jLT54YV9mbGFnOwoKCXJldHVybiAwOwp9CgpzdGF0aWMKaW50IGlkZV9jZHJvbV9nZXRfbWNuIChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSwKCQkgICAgICAgc3RydWN0IGNkcm9tX21jbiAqbWNuX2luZm8pCnsKCWludCBzdGF0OwoJY2hhciBtY25idWZbMjRdOwoJaWRlX2RyaXZlX3QgKmRyaXZlID0gKGlkZV9kcml2ZV90KikgY2RpLT5oYW5kbGU7CgovKiBnZXQgTUNOICovCglpZiAoKHN0YXQgPSBjZHJvbV9yZWFkX3N1YmNoYW5uZWwoZHJpdmUsIDIsIG1jbmJ1Ziwgc2l6ZW9mIChtY25idWYpLCBOVUxMKSkpCgkJcmV0dXJuIHN0YXQ7CgoJbWVtY3B5IChtY25faW5mby0+bWVkaXVtX2NhdGFsb2dfbnVtYmVyLCBtY25idWYrOSwKCQlzaXplb2YgKG1jbl9pbmZvLT5tZWRpdW1fY2F0YWxvZ19udW1iZXIpLTEpOwoJbWNuX2luZm8tPm1lZGl1bV9jYXRhbG9nX251bWJlcltzaXplb2YgKG1jbl9pbmZvLT5tZWRpdW1fY2F0YWxvZ19udW1iZXIpLTFdCgkJPSAnXDAnOwoKCXJldHVybiAwOwp9CgoKCi8qKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqIE90aGVyIGRyaXZlciByZXF1ZXN0cyAob3BlbiwgY2xvc2UsIGNoZWNrIG1lZGlhIGNoYW5nZSkuCiAqLwoKc3RhdGljCmludCBpZGVfY2Ryb21fY2hlY2tfbWVkaWFfY2hhbmdlX3JlYWwgKHN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpLAoJCQkJICAgICAgIGludCBzbG90X25yKQp7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSAoaWRlX2RyaXZlX3QqKSBjZGktPmhhbmRsZTsKCWludCByZXR2YWw7CgkKCWlmIChzbG90X25yID09IENEU0xfQ1VSUkVOVCkgewoJCSh2b2lkKSBjZHJvbV9jaGVja19zdGF0dXMoZHJpdmUsIE5VTEwpOwoJCXJldHZhbCA9IENEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+bWVkaWFfY2hhbmdlZDsKCQlDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPm1lZGlhX2NoYW5nZWQgPSAwOwoJCXJldHVybiByZXR2YWw7Cgl9IGVsc2UgewoJCXJldHVybiAtRUlOVkFMOwoJfQp9CgoKc3RhdGljCmludCBpZGVfY2Ryb21fb3Blbl9yZWFsIChzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmNkaSwgaW50IHB1cnBvc2UpCnsKCXJldHVybiAwOwp9CgovKgogKiBDbG9zZSBkb3duIHRoZSBkZXZpY2UuICBJbnZhbGlkYXRlIGFsbCBjYWNoZWQgYmxvY2tzLgogKi8KCnN0YXRpYwp2b2lkIGlkZV9jZHJvbV9yZWxlYXNlX3JlYWwgKHN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpKQp7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSBjZGktPmhhbmRsZTsKCglpZiAoIWNkaS0+dXNlX2NvdW50KQoJCUNEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+dG9jX3ZhbGlkID0gMDsKfQoKCgovKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKiBEZXZpY2UgaW5pdGlhbGl6YXRpb24uCiAqLwpzdGF0aWMgc3RydWN0IGNkcm9tX2RldmljZV9vcHMgaWRlX2Nkcm9tX2RvcHMgPSB7Cgkub3BlbgkJCT0gaWRlX2Nkcm9tX29wZW5fcmVhbCwKCS5yZWxlYXNlCQk9IGlkZV9jZHJvbV9yZWxlYXNlX3JlYWwsCgkuZHJpdmVfc3RhdHVzCQk9IGlkZV9jZHJvbV9kcml2ZV9zdGF0dXMsCgkubWVkaWFfY2hhbmdlZAkJPSBpZGVfY2Ryb21fY2hlY2tfbWVkaWFfY2hhbmdlX3JlYWwsCgkudHJheV9tb3ZlCQk9IGlkZV9jZHJvbV90cmF5X21vdmUsCgkubG9ja19kb29yCQk9IGlkZV9jZHJvbV9sb2NrX2Rvb3IsCgkuc2VsZWN0X3NwZWVkCQk9IGlkZV9jZHJvbV9zZWxlY3Rfc3BlZWQsCgkuZ2V0X2xhc3Rfc2Vzc2lvbgk9IGlkZV9jZHJvbV9nZXRfbGFzdF9zZXNzaW9uLAoJLmdldF9tY24JCT0gaWRlX2Nkcm9tX2dldF9tY24sCgkucmVzZXQJCQk9IGlkZV9jZHJvbV9yZXNldCwKCS5hdWRpb19pb2N0bAkJPSBpZGVfY2Ryb21fYXVkaW9faW9jdGwsCgkuZGV2X2lvY3RsCQk9IGlkZV9jZHJvbV9kZXZfaW9jdGwsCgkuY2FwYWJpbGl0eQkJPSBDRENfQ0xPU0VfVFJBWSB8IENEQ19PUEVOX1RSQVkgfCBDRENfTE9DSyB8CgkJCQlDRENfU0VMRUNUX1NQRUVEIHwgQ0RDX1NFTEVDVF9ESVNDIHwKCQkJCUNEQ19NVUxUSV9TRVNTSU9OIHwgQ0RDX01DTiB8CgkJCQlDRENfTUVESUFfQ0hBTkdFRCB8IENEQ19QTEFZX0FVRElPIHwgQ0RDX1JFU0VUIHwKCQkJCUNEQ19JT0NUTFMgfCBDRENfRFJJVkVfU1RBVFVTIHwgQ0RDX0NEX1IgfAoJCQkJQ0RDX0NEX1JXIHwgQ0RDX0RWRCB8IENEQ19EVkRfUnwgQ0RDX0RWRF9SQU0gfAoJCQkJQ0RDX0dFTkVSSUNfUEFDS0VUIHwgQ0RDX01PX0RSSVZFIHwgQ0RDX01SVyB8CgkJCQlDRENfTVJXX1cgfCBDRENfUkFNLAoJLmdlbmVyaWNfcGFja2V0CQk9IGlkZV9jZHJvbV9wYWNrZXQsCn07CgpzdGF0aWMgaW50IGlkZV9jZHJvbV9yZWdpc3RlciAoaWRlX2RyaXZlX3QgKmRyaXZlLCBpbnQgbnNsb3RzKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqZGV2aW5mbyA9ICZpbmZvLT5kZXZpbmZvOwoKCWRldmluZm8tPm9wcyA9ICZpZGVfY2Ryb21fZG9wczsKCWRldmluZm8tPm1hc2sgPSAwOwoJZGV2aW5mby0+c3BlZWQgPSBDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPmN1cnJlbnRfc3BlZWQ7CglkZXZpbmZvLT5jYXBhY2l0eSA9IG5zbG90czsKCWRldmluZm8tPmhhbmRsZSA9ICh2b2lkICopIGRyaXZlOwoJc3RyY3B5KGRldmluZm8tPm5hbWUsIGRyaXZlLT5uYW1lKTsKCQoJLyogc2V0IGNhcGFiaWxpdHkgbWFzayB0byBtYXRjaCB0aGUgcHJvYmUuICovCglpZiAoIUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNkX3IpCgkJZGV2aW5mby0+bWFzayB8PSBDRENfQ0RfUjsKCWlmICghQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2RfcncpCgkJZGV2aW5mby0+bWFzayB8PSBDRENfQ0RfUlc7CglpZiAoIUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZCkKCQlkZXZpbmZvLT5tYXNrIHw9IENEQ19EVkQ7CglpZiAoIUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZF9yKQoJCWRldmluZm8tPm1hc2sgfD0gQ0RDX0RWRF9SOwoJaWYgKCFDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5kdmRfcmFtKQoJCWRldmluZm8tPm1hc2sgfD0gQ0RDX0RWRF9SQU07CglpZiAoIUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmlzX2NoYW5nZXIpCgkJZGV2aW5mby0+bWFzayB8PSBDRENfU0VMRUNUX0RJU0M7CglpZiAoIUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmF1ZGlvX3BsYXkpCgkJZGV2aW5mby0+bWFzayB8PSBDRENfUExBWV9BVURJTzsKCWlmICghQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2xvc2VfdHJheSkKCQlkZXZpbmZvLT5tYXNrIHw9IENEQ19DTE9TRV9UUkFZOwoJaWYgKCFDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5tb19kcml2ZSkKCQlkZXZpbmZvLT5tYXNrIHw9IENEQ19NT19EUklWRTsKCglkZXZpbmZvLT5kaXNrID0gaW5mby0+ZGlzazsKCXJldHVybiByZWdpc3Rlcl9jZHJvbShkZXZpbmZvKTsKfQoKc3RhdGljCmludCBpZGVfY2Ryb21fcHJvYmVfY2FwYWJpbGl0aWVzIChpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoJc3RydWN0IGNkcm9tX2RldmljZV9pbmZvICpjZGkgPSAmaW5mby0+ZGV2aW5mbzsKCXN0cnVjdCBhdGFwaV9jYXBhYmlsaXRpZXNfcGFnZSBjYXA7CglpbnQgbnNsb3RzID0gMTsKCglpZiAoZHJpdmUtPm1lZGlhID09IGlkZV9vcHRpY2FsKSB7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bW9fZHJpdmUgPSAxOwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnJhbSA9IDE7CgkJcHJpbnRrKEtFUk5fRVJSICIlczogQVRBUEkgbWFnbmV0by1vcHRpY2FsIGRyaXZlXG4iLCBkcml2ZS0+bmFtZSk7CgkJcmV0dXJuIG5zbG90czsKCX0KCglpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bmVjMjYwIHx8CgkgICAgIXN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCJTVElOR1JBWSA4NDIyIElERSA4WCBDRC1ST00gNy0yNy05NSIpKSB7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bm9fZWplY3QgPSAwOwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmF1ZGlvX3BsYXkgPSAxOwoJCXJldHVybiBuc2xvdHM7Cgl9CgoJLyoKCSAqIHdlIGhhdmUgdG8gY2hlYXQgYSBsaXR0bGUgaGVyZS4gdGhlIHBhY2tldCB3aWxsIGV2ZW50dWFsbHkKCSAqIGJlIHF1ZXVlZCB3aXRoIGlkZV9jZHJvbV9wYWNrZXQoKSwgd2hpY2ggZXh0cmFjdHMgdGhlCgkgKiBkcml2ZSBmcm9tIGNkaS0+aGFuZGxlLiBTaW5jZSB0aGlzIGRldmljZSBoYXNuJ3QgYmVlbgoJICogcmVnaXN0ZXJlZCB3aXRoIHRoZSBVbmlmb3JtIGxheWVyIHlldCwgaXQgY2FuJ3QgZG8gdGhpcy4KCSAqIFNhbWUgZ29lcyBmb3IgY2RpLT5vcHMuCgkgKi8KCWNkaS0+aGFuZGxlID0gKGlkZV9kcml2ZV90ICopIGRyaXZlOwoJY2RpLT5vcHMgPSAmaWRlX2Nkcm9tX2RvcHM7CgoJaWYgKGlkZV9jZHJvbV9nZXRfY2FwYWJpbGl0aWVzKGRyaXZlLCAmY2FwKSkKCQlyZXR1cm4gMDsKCglpZiAoY2FwLmxvY2sgPT0gMCkKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5ub19kb29ybG9jayA9IDE7CglpZiAoY2FwLmVqZWN0KQoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPm5vX2VqZWN0ID0gMDsKCWlmIChjYXAuY2Rfcl93cml0ZSkKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5jZF9yID0gMTsKCWlmIChjYXAuY2Rfcndfd3JpdGUpIHsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5jZF9ydyA9IDE7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+cmFtID0gMTsKCX0KCWlmIChjYXAudGVzdF93cml0ZSkKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT50ZXN0X3dyaXRlID0gMTsKCWlmIChjYXAuZHZkX3JhbV9yZWFkIHx8IGNhcC5kdmRfcl9yZWFkIHx8IGNhcC5kdmRfcm9tKQoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmR2ZCA9IDE7CglpZiAoY2FwLmR2ZF9yYW1fd3JpdGUpIHsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5kdmRfcmFtID0gMTsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5yYW0gPSAxOwoJfQoJaWYgKGNhcC5kdmRfcl93cml0ZSkKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5kdmRfciA9IDE7CglpZiAoY2FwLmF1ZGlvX3BsYXkpCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+YXVkaW9fcGxheSA9IDE7CglpZiAoY2FwLm1lY2h0eXBlID09IG1lY2h0eXBlX2NhZGR5IHx8IGNhcC5tZWNodHlwZSA9PSBtZWNodHlwZV9wb3B1cCkKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5jbG9zZV90cmF5ID0gMDsKCgkvKiBTb21lIGRyaXZlcyB1c2VkIGJ5IEFwcGxlIGRvbid0IGFkdmVydGlzZSBhdWRpbyBwbGF5CgkgKiBidXQgdGhleSBkbyBzdXBwb3J0IHJlYWRpbmcgVE9DICYgYXVkaW8gZGF0YXMKCSAqLwoJaWYgKHN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiTUFUU0hJVEFEVkQtUk9NIFNSLTgxODciKSA9PSAwIHx8CgkgICAgc3RyY21wKGRyaXZlLT5pZC0+bW9kZWwsICJNQVRTSElUQURWRC1ST00gU1ItODE4NiIpID09IDAgfHwKCSAgICBzdHJjbXAoZHJpdmUtPmlkLT5tb2RlbCwgIk1BVFNISVRBRFZELVJPTSBTUi04MTc2IikgPT0gMCB8fAoJICAgIHN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiTUFUU0hJVEFEVkQtUk9NIFNSLTgxNzQiKSA9PSAwKQoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmF1ZGlvX3BsYXkgPSAxOwoKI2lmICEgU1RBTkRBUkRfQVRBUEkKCWlmIChjZGktPnNhbnlvX3Nsb3QgPiAwKSB7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+aXNfY2hhbmdlciA9IDE7CgkJbnNsb3RzID0gMzsKCX0KCgllbHNlCiNlbmRpZiAvKiBub3QgU1RBTkRBUkRfQVRBUEkgKi8KCWlmIChjYXAubWVjaHR5cGUgPT0gbWVjaHR5cGVfaW5kaXZpZHVhbF9jaGFuZ2VyIHx8CgkgICAgY2FwLm1lY2h0eXBlID09IG1lY2h0eXBlX2NhcnRyaWRnZV9jaGFuZ2VyKSB7CgkJaWYgKChuc2xvdHMgPSBjZHJvbV9udW1iZXJfb2Zfc2xvdHMoY2RpKSkgPiAxKSB7CgkJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmlzX2NoYW5nZXIgPSAxOwoJCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5zdXBwX2Rpc2NfcHJlc2VudCA9IDE7CgkJfQoJfQoKCWlkZV9jZHJvbV91cGRhdGVfc3BlZWQoZHJpdmUsICZjYXApOwoJLyogZG9uJ3QgcHJpbnQgc3BlZWQgaWYgdGhlIGRyaXZlIHJlcG9ydGVkIDAuCgkgKi8KCXByaW50ayhLRVJOX0lORk8gIiVzOiBBVEFQSSIsIGRyaXZlLT5uYW1lKTsKCWlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5tYXhfc3BlZWQpCgkJcHJpbnRrKCIgJWRYIiwgQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bWF4X3NwZWVkKTsKCXByaW50aygiICVzIiwgQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkID8gIkRWRC1ST00iIDogIkNELVJPTSIpOwoKCWlmIChDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5kdmRfcnxDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5kdmRfcmFtKQogICAgICAgIAlwcmludGsoIiBEVkQlcyVzIiwgCiAgICAgICAgCShDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5kdmRfcik/ICItUiIgOiAiIiwgCiAgICAgICAgCShDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5kdmRfcmFtKT8gIi1SQU0iIDogIiIpOwoKICAgICAgICBpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2RfcnxDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5jZF9ydykgCiAgICAgICAgCXByaW50aygiIENEJXMlcyIsIAogICAgICAgIAkoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2Rfcik/ICItUiIgOiAiIiwgCiAgICAgICAgCShDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5jZF9ydyk/ICIvUlciIDogIiIpOwoKICAgICAgICBpZiAoQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+aXNfY2hhbmdlcikgCiAgICAgICAgCXByaW50aygiIGNoYW5nZXIgdy8lZCBzbG90cyIsIG5zbG90cyk7CiAgICAgICAgZWxzZSAJCiAgICAgICAgCXByaW50aygiIGRyaXZlIik7CgoJcHJpbnRrKCIsICVka0IgQ2FjaGUiLCBiZTE2X3RvX2NwdShjYXAuYnVmZmVyX3NpemUpKTsKCglpZiAoZHJpdmUtPnVzaW5nX2RtYSkKCQlpZGVfZG1hX3ZlcmJvc2UoZHJpdmUpOwoKCXByaW50aygiXG4iKTsKCglyZXR1cm4gbnNsb3RzOwp9CgpzdGF0aWMgdm9pZCBpZGVfY2Ryb21fYWRkX3NldHRpbmdzKGlkZV9kcml2ZV90ICpkcml2ZSkKewoJaWRlX2FkZF9zZXR0aW5nKGRyaXZlLAkiZHNjX292ZXJsYXAiLAkJU0VUVElOR19SVywgLTEsIC0xLCBUWVBFX0JZVEUsIDAsIDEsIDEsCTEsICZkcml2ZS0+ZHNjX292ZXJsYXAsIE5VTEwpOwp9CgovKgogKiBzdGFuZGFyZCBwcmVwX3JxX2ZuIHRoYXQgYnVpbGRzIDEwIGJ5dGUgY21kcwogKi8Kc3RhdGljIGludCBpZGVfY2Ryb21fcHJlcF9mcyhyZXF1ZXN0X3F1ZXVlX3QgKnEsIHN0cnVjdCByZXF1ZXN0ICpycSkKewoJaW50IGhhcmRfc2VjdCA9IHF1ZXVlX2hhcmRzZWN0X3NpemUocSk7Cglsb25nIGJsb2NrID0gKGxvbmcpcnEtPmhhcmRfc2VjdG9yIC8gKGhhcmRfc2VjdCA+PiA5KTsKCXVuc2lnbmVkIGxvbmcgYmxvY2tzID0gcnEtPmhhcmRfbnJfc2VjdG9ycyAvIChoYXJkX3NlY3QgPj4gOSk7CgoJbWVtc2V0KHJxLT5jbWQsIDAsIHNpemVvZihycS0+Y21kKSk7CgoJaWYgKHJxX2RhdGFfZGlyKHJxKSA9PSBSRUFEKQoJCXJxLT5jbWRbMF0gPSBHUENNRF9SRUFEXzEwOwoJZWxzZQoJCXJxLT5jbWRbMF0gPSBHUENNRF9XUklURV8xMDsKCgkvKgoJICogZmlsbCBpbiBsYmEKCSAqLwoJcnEtPmNtZFsyXSA9IChibG9jayA+PiAyNCkgJiAweGZmOwoJcnEtPmNtZFszXSA9IChibG9jayA+PiAxNikgJiAweGZmOwoJcnEtPmNtZFs0XSA9IChibG9jayA+PiAgOCkgJiAweGZmOwoJcnEtPmNtZFs1XSA9IGJsb2NrICYgMHhmZjsKCgkvKgoJICogYW5kIHRyYW5zZmVyIGxlbmd0aAoJICovCglycS0+Y21kWzddID0gKGJsb2NrcyA+PiA4KSAmIDB4ZmY7CglycS0+Y21kWzhdID0gYmxvY2tzICYgMHhmZjsKCXJxLT5jbWRfbGVuID0gMTA7CglyZXR1cm4gQkxLUFJFUF9PSzsKfQoKLyoKICogTW9zdCBvZiB0aGUgU0NTSSBjb21tYW5kcyBhcmUgc3VwcG9ydGVkIGRpcmVjdGx5IGJ5IEFUQVBJIGRldmljZXMuCiAqIFRoaXMgdHJhbnNmb3JtIGhhbmRsZXMgdGhlIGZldyBleGNlcHRpb25zLgogKi8Kc3RhdGljIGludCBpZGVfY2Ryb21fcHJlcF9wYyhzdHJ1Y3QgcmVxdWVzdCAqcnEpCnsKCXU4ICpjID0gcnEtPmNtZDsKCgkvKgoJICogVHJhbnNmb3JtIDYtYnl0ZSByZWFkL3dyaXRlIGNvbW1hbmRzIHRvIHRoZSAxMC1ieXRlIHZlcnNpb24KCSAqLwoJaWYgKGNbMF0gPT0gUkVBRF82IHx8IGNbMF0gPT0gV1JJVEVfNikgewoJCWNbOF0gPSBjWzRdOwoJCWNbNV0gPSBjWzNdOwoJCWNbNF0gPSBjWzJdOwoJCWNbM10gPSBjWzFdICYgMHgxZjsKCQljWzJdID0gMDsKCQljWzFdICY9IDB4ZTA7CgkJY1swXSArPSAoUkVBRF8xMCAtIFJFQURfNik7CgkJcnEtPmNtZF9sZW4gPSAxMDsKCQlyZXR1cm4gQkxLUFJFUF9PSzsKCX0KCgkvKgoJICogaXQncyBzaWxseSB0byBwcmV0ZW5kIHdlIHVuZGVyc3RhbmQgNi1ieXRlIHNlbnNlIGNvbW1hbmRzLCBqdXN0CgkgKiByZWplY3Qgd2l0aCBJTExFR0FMX1JFUVVFU1QgYW5kIHRoZSBjYWxsZXIgc2hvdWxkIHRha2UgdGhlCgkgKiBhcHByb3ByaWF0ZSBhY3Rpb24KCSAqLwoJaWYgKGNbMF0gPT0gTU9ERV9TRU5TRSB8fCBjWzBdID09IE1PREVfU0VMRUNUKSB7CgkJcnEtPmVycm9ycyA9IElMTEVHQUxfUkVRVUVTVDsKCQlyZXR1cm4gQkxLUFJFUF9LSUxMOwoJfQoJCglyZXR1cm4gQkxLUFJFUF9PSzsKfQoKc3RhdGljIGludCBpZGVfY2Ryb21fcHJlcF9mbihyZXF1ZXN0X3F1ZXVlX3QgKnEsIHN0cnVjdCByZXF1ZXN0ICpycSkKewoJaWYgKHJxLT5mbGFncyAmIFJFUV9DTUQpCgkJcmV0dXJuIGlkZV9jZHJvbV9wcmVwX2ZzKHEsIHJxKTsKCWVsc2UgaWYgKHJxLT5mbGFncyAmIFJFUV9CTE9DS19QQykKCQlyZXR1cm4gaWRlX2Nkcm9tX3ByZXBfcGMocnEpOwoKCXJldHVybiAwOwp9CgpzdGF0aWMKaW50IGlkZV9jZHJvbV9zZXR1cCAoaWRlX2RyaXZlX3QgKmRyaXZlKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGRyaXZlLT5kcml2ZXJfZGF0YTsKCXN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqY2RpID0gJmluZm8tPmRldmluZm87CglpbnQgbnNsb3RzOwoKCWJsa19xdWV1ZV9wcmVwX3JxKGRyaXZlLT5xdWV1ZSwgaWRlX2Nkcm9tX3ByZXBfZm4pOwoJYmxrX3F1ZXVlX2RtYV9hbGlnbm1lbnQoZHJpdmUtPnF1ZXVlLCAzMSk7Cglkcml2ZS0+cXVldWUtPnVucGx1Z19kZWxheSA9ICgxICogSFopIC8gMTAwMDsKCWlmICghZHJpdmUtPnF1ZXVlLT51bnBsdWdfZGVsYXkpCgkJZHJpdmUtPnF1ZXVlLT51bnBsdWdfZGVsYXkgPSAxOwoKCWRyaXZlLT5zcGVjaWFsLmFsbAk9IDA7CgoJQ0RST01fU1RBVEVfRkxBR1MoZHJpdmUpLT5tZWRpYV9jaGFuZ2VkID0gMTsKCUNEUk9NX1NUQVRFX0ZMQUdTKGRyaXZlKS0+dG9jX3ZhbGlkICAgICA9IDA7CglDRFJPTV9TVEFURV9GTEFHUyhkcml2ZSktPmRvb3JfbG9ja2VkICAgPSAwOwoKI2lmIE5PX0RPT1JfTE9DS0lORwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bm9fZG9vcmxvY2sgPSAxOwojZWxzZQoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bm9fZG9vcmxvY2sgPSAwOwojZW5kaWYKCglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5kcnFfaW50ZXJydXB0ID0gKChkcml2ZS0+aWQtPmNvbmZpZyAmIDB4MDA2MCkgPT0gMHgyMCk7CglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5pc19jaGFuZ2VyID0gMDsKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNkX3IgPSAwOwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+Y2RfcncgPSAwOwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dGVzdF93cml0ZSA9IDA7CglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5kdmQgPSAwOwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkX3IgPSAwOwoJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+ZHZkX3JhbSA9IDA7CglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5ub19lamVjdCA9IDE7CglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5zdXBwX2Rpc2NfcHJlc2VudCA9IDA7CglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5hdWRpb19wbGF5ID0gMDsKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmNsb3NlX3RyYXkgPSAxOwoJCgkvKiBsaW1pdCB0cmFuc2ZlciBzaXplIHBlciBpbnRlcnJ1cHQuICovCglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5saW1pdF9uZnJhbWVzID0gMDsKCS8qIGEgdGVzdGFtZW50IHRvIHRoZSBuaWNlIHF1YWxpdHkgb2YgU2Ftc3VuZyBkcml2ZXMuLi4gKi8KCWlmICghc3RyY21wKGRyaXZlLT5pZC0+bW9kZWwsICJTQU1TVU5HIENELVJPTSBTQ1ItMjQzMCIpKQoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPmxpbWl0X25mcmFtZXMgPSAxOwoJZWxzZSBpZiAoIXN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiU0FNU1VORyBDRC1ST00gU0NSLTI0MzIiKSkKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5saW1pdF9uZnJhbWVzID0gMTsKCS8qIHRoZSAzMjMxIG1vZGVsIGRvZXMgbm90IHN1cHBvcnQgdGhlIFNFVF9DRF9TUEVFRCBjb21tYW5kICovCgllbHNlIGlmICghc3RyY21wKGRyaXZlLT5pZC0+bW9kZWwsICJTQU1TVU5HIENELVJPTSBTQ1ItMzIzMSIpKQoJCWNkaS0+bWFzayB8PSBDRENfU0VMRUNUX1NQRUVEOwoKI2lmICEgU1RBTkRBUkRfQVRBUEkKCS8qIGJ5IGRlZmF1bHQgU2FueW8gMyBDRCBjaGFuZ2VyIHN1cHBvcnQgaXMgdHVybmVkIG9mZiBhbmQKICAgICAgICAgICBBVEFQSSBSZXYgMi4yKyBzdGFuZGFyZCBzdXBwb3J0IGZvciBDRCBjaGFuZ2VycyBpcyB1c2VkICovCgljZGktPnNhbnlvX3Nsb3QgPSAwOwoKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPm5lYzI2MCA9IDA7CglDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT50b2N0cmFja3NfYXNfYmNkID0gMDsKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnRvY2FkZHJfYXNfYmNkID0gMDsKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnBsYXltc2ZfYXNfYmNkID0gMDsKCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnN1YmNoYW5fYXNfYmNkID0gMDsKCglpZiAoc3RyY21wIChkcml2ZS0+aWQtPm1vZGVsLCAiVjAwM1MwRFMiKSA9PSAwICYmCgkgICAgZHJpdmUtPmlkLT5md19yZXZbNF0gPT0gJzEnICYmCgkgICAgZHJpdmUtPmlkLT5md19yZXZbNl0gPD0gJzInKSB7CgkJLyogVmVydG9zIDMwMC4KCQkgICBTb21lIHZlcnNpb25zIG9mIHRoaXMgZHJpdmUgbGlrZSB0byB0YWxrIEJDRC4gKi8KCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT50b2N0cmFja3NfYXNfYmNkID0gMTsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT50b2NhZGRyX2FzX2JjZCA9IDE7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+cGxheW1zZl9hc19iY2QgPSAxOwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnN1YmNoYW5fYXNfYmNkID0gMTsKCX0KCgllbHNlIGlmIChzdHJjbXAgKGRyaXZlLT5pZC0+bW9kZWwsICJWMDA2RTBEUyIpID09IDAgJiYKCSAgICBkcml2ZS0+aWQtPmZ3X3Jldls0XSA9PSAnMScgJiYKCSAgICBkcml2ZS0+aWQtPmZ3X3Jldls2XSA8PSAnMicpIHsKCQkvKiBWZXJ0b3MgNjAwIEVTRC4gKi8KCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT50b2N0cmFja3NfYXNfYmNkID0gMTsKCX0KCWVsc2UgaWYgKHN0cmNtcChkcml2ZS0+aWQtPm1vZGVsLCAiTkVDIENELVJPTSBEUklWRToyNjAiKSA9PSAwICYmCgkJIHN0cm5jbXAoZHJpdmUtPmlkLT5md19yZXYsICIxLjAxIiwgNCkgPT0gMCkgeyAvKiBGSVhNRSAqLwoJCS8qIE9sZCBORUMyNjAgKG5vdCBSKS4KCQkgICBUaGlzIGRyaXZlIHdhcyByZWxlYXNlZCBiZWZvcmUgdGhlIDEuMiB2ZXJzaW9uCgkJICAgb2YgdGhlIHNwZWMuICovCgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+dG9jYWRkcl9hc19iY2QgPSAxOwoJCUNEUk9NX0NPTkZJR19GTEFHUyhkcml2ZSktPnBsYXltc2ZfYXNfYmNkID0gMTsKCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5zdWJjaGFuX2FzX2JjZCA9IDE7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+bmVjMjYwICAgICAgICAgPSAxOwoJfQoJZWxzZSBpZiAoc3RyY21wKGRyaXZlLT5pZC0+bW9kZWwsICJXRUFSTkVTIENERC0xMjAiKSA9PSAwICYmCgkJIHN0cm5jbXAoZHJpdmUtPmlkLT5md19yZXYsICJBMS4xIiwgNCkgPT0gMCkgeyAvKiBGSVhNRSAqLwoJCS8qIFdlYXJuZXMgKi8KCQlDRFJPTV9DT05GSUdfRkxBR1MoZHJpdmUpLT5wbGF5bXNmX2FzX2JjZCA9IDE7CgkJQ0RST01fQ09ORklHX0ZMQUdTKGRyaXZlKS0+c3ViY2hhbl9hc19iY2QgPSAxOwoJfQogICAgICAgIC8qIFNhbnlvIDMgQ0QgY2hhbmdlciB1c2VzIGEgbm9uLXN0YW5kYXJkIGNvbW1hbmQKICAgICAgICAgICBmb3IgQ0QgY2hhbmdpbmcgKi8KICAgICAgICBlbHNlIGlmICgoc3RyY21wKGRyaXZlLT5pZC0+bW9kZWwsICJDRC1ST00gQ0RSLUMzIEciKSA9PSAwKSB8fAogICAgICAgICAgICAgICAgIChzdHJjbXAoZHJpdmUtPmlkLT5tb2RlbCwgIkNELVJPTSBDRFItQzNHIikgPT0gMCkgfHwKICAgICAgICAgICAgICAgICAoc3RyY21wKGRyaXZlLT5pZC0+bW9kZWwsICJDRC1ST00gQ0RSX0MzNiIpID09IDApKSB7CiAgICAgICAgICAgICAgICAgLyogdXNlcyBDRCBpbiBzbG90IDAgd2hlbiB2YWx1ZSBpcyBzZXQgdG8gMyAqLwogICAgICAgICAgICAgICAgIGNkaS0+c2FueW9fc2xvdCA9IDM7CiAgICAgICAgfQojZW5kaWYgLyogbm90IFNUQU5EQVJEX0FUQVBJICovCgoJaW5mby0+dG9jCQk9IE5VTEw7CglpbmZvLT5idWZmZXIJCT0gTlVMTDsKCWluZm8tPnNlY3Rvcl9idWZmZXJlZAk9IDA7CglpbmZvLT5uc2VjdG9yc19idWZmZXJlZAk9IDA7CglpbmZvLT5jaGFuZ2VyX2luZm8gICAgICA9IE5VTEw7CglpbmZvLT5sYXN0X2Jsb2NrCT0gMDsKCWluZm8tPnN0YXJ0X3NlZWsJPSAwOwoKCW5zbG90cyA9IGlkZV9jZHJvbV9wcm9iZV9jYXBhYmlsaXRpZXMgKGRyaXZlKTsKCgkvKgoJICogc2V0IGNvcnJlY3QgYmxvY2sgc2l6ZQoJICovCglibGtfcXVldWVfaGFyZHNlY3Rfc2l6ZShkcml2ZS0+cXVldWUsIENEX0ZSQU1FU0laRSk7CgoJaWYgKGRyaXZlLT5hdXRvdHVuZSA9PSBJREVfVFVORV9ERUZBVUxUIHx8CgkgICAgZHJpdmUtPmF1dG90dW5lID09IElERV9UVU5FX0FVVE8pCgkJZHJpdmUtPmRzY19vdmVybGFwID0gKGRyaXZlLT5uZXh0ICE9IGRyaXZlKTsKI2lmIDAKCWRyaXZlLT5kc2Nfb3ZlcmxhcCA9IChIV0lGKGRyaXZlKS0+bm9fZHNjKSA/IDAgOiAxOwoJaWYgKEhXSUYoZHJpdmUpLT5ub19kc2MpIHsKCQlwcmludGsoS0VSTl9JTkZPICJpZGUtY2Q6ICVzOiBkaXNhYmxpbmcgRFNDIG92ZXJsYXBcbiIsCgkJCWRyaXZlLT5uYW1lKTsKCQlkcml2ZS0+ZHNjX292ZXJsYXAgPSAwOwoJfQojZW5kaWYKCglpZiAoaWRlX2Nkcm9tX3JlZ2lzdGVyKGRyaXZlLCBuc2xvdHMpKSB7CgkJcHJpbnRrIChLRVJOX0VSUiAiJXM6IGlkZV9jZHJvbV9zZXR1cCBmYWlsZWQgdG8gcmVnaXN0ZXIgZGV2aWNlIHdpdGggdGhlIGNkcm9tIGRyaXZlci5cbiIsIGRyaXZlLT5uYW1lKTsKCQlpbmZvLT5kZXZpbmZvLmhhbmRsZSA9IE5VTEw7CgkJcmV0dXJuIDE7Cgl9CglpZGVfY2Ryb21fYWRkX3NldHRpbmdzKGRyaXZlKTsKCXJldHVybiAwOwp9CgpzdGF0aWMKc2VjdG9yX3QgaWRlX2Nkcm9tX2NhcGFjaXR5IChpZGVfZHJpdmVfdCAqZHJpdmUpCnsKCXVuc2lnbmVkIGxvbmcgY2FwYWNpdHksIHNlY3RvcnNfcGVyX2ZyYW1lOwoKCWlmIChjZHJvbV9yZWFkX2NhcGFjaXR5KGRyaXZlLCAmY2FwYWNpdHksICZzZWN0b3JzX3Blcl9mcmFtZSwgTlVMTCkpCgkJcmV0dXJuIDA7CgoJcmV0dXJuIGNhcGFjaXR5ICogc2VjdG9yc19wZXJfZnJhbWU7Cn0KCnN0YXRpYyBpbnQgaWRlX2NkX3JlbW92ZShzdHJ1Y3QgZGV2aWNlICpkZXYpCnsKCWlkZV9kcml2ZV90ICpkcml2ZSA9IHRvX2lkZV9kZXZpY2UoZGV2KTsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gZHJpdmUtPmRyaXZlcl9kYXRhOwoKCWlkZV91bnJlZ2lzdGVyX3N1YmRyaXZlcihkcml2ZSwgaW5mby0+ZHJpdmVyKTsKCglkZWxfZ2VuZGlzayhpbmZvLT5kaXNrKTsKCglpZGVfY2RfcHV0KGluZm8pOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgdm9pZCBpZGVfY2RfcmVsZWFzZShzdHJ1Y3Qga3JlZiAqa3JlZikKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSB0b19pZGVfY2Qoa3JlZik7CglzdHJ1Y3QgY2Ryb21fZGV2aWNlX2luZm8gKmRldmluZm8gPSAmaW5mby0+ZGV2aW5mbzsKCWlkZV9kcml2ZV90ICpkcml2ZSA9IGluZm8tPmRyaXZlOwoJc3RydWN0IGdlbmRpc2sgKmcgPSBpbmZvLT5kaXNrOwoKCWlmIChpbmZvLT5idWZmZXIgIT0gTlVMTCkKCQlrZnJlZShpbmZvLT5idWZmZXIpOwoJaWYgKGluZm8tPnRvYyAhPSBOVUxMKQoJCWtmcmVlKGluZm8tPnRvYyk7CglpZiAoaW5mby0+Y2hhbmdlcl9pbmZvICE9IE5VTEwpCgkJa2ZyZWUoaW5mby0+Y2hhbmdlcl9pbmZvKTsKCWlmIChkZXZpbmZvLT5oYW5kbGUgPT0gZHJpdmUgJiYgdW5yZWdpc3Rlcl9jZHJvbShkZXZpbmZvKSkKCQlwcmludGsoS0VSTl9FUlIgIiVzOiAlcyBmYWlsZWQgdG8gdW5yZWdpc3RlciBkZXZpY2UgZnJvbSB0aGUgY2Ryb20gIgoJCQkJImRyaXZlci5cbiIsIF9fRlVOQ1RJT05fXywgZHJpdmUtPm5hbWUpOwoJZHJpdmUtPmRzY19vdmVybGFwID0gMDsKCWRyaXZlLT5kcml2ZXJfZGF0YSA9IE5VTEw7CglibGtfcXVldWVfcHJlcF9ycShkcml2ZS0+cXVldWUsIE5VTEwpOwoJZy0+cHJpdmF0ZV9kYXRhID0gTlVMTDsKCXB1dF9kaXNrKGcpOwoJa2ZyZWUoaW5mbyk7Cn0KCnN0YXRpYyBpbnQgaWRlX2NkX3Byb2JlKHN0cnVjdCBkZXZpY2UgKik7CgojaWZkZWYgQ09ORklHX1BST0NfRlMKc3RhdGljIGludCBwcm9jX2lkZWNkX3JlYWRfY2FwYWNpdHkKCShjaGFyICpwYWdlLCBjaGFyICoqc3RhcnQsIG9mZl90IG9mZiwgaW50IGNvdW50LCBpbnQgKmVvZiwgdm9pZCAqZGF0YSkKewoJaWRlX2RyaXZlX3QqZHJpdmUgPSAoaWRlX2RyaXZlX3QgKilkYXRhOwoJaW50IGxlbjsKCglsZW4gPSBzcHJpbnRmKHBhZ2UsIiVsbHVcbiIsIChsb25nIGxvbmcpaWRlX2Nkcm9tX2NhcGFjaXR5KGRyaXZlKSk7CglQUk9DX0lERV9SRUFEX1JFVFVSTihwYWdlLHN0YXJ0LG9mZixjb3VudCxlb2YsbGVuKTsKfQoKc3RhdGljIGlkZV9wcm9jX2VudHJ5X3QgaWRlY2RfcHJvY1tdID0gewoJeyAiY2FwYWNpdHkiLCBTX0lGUkVHfFNfSVJVR08sIHByb2NfaWRlY2RfcmVhZF9jYXBhY2l0eSwgTlVMTCB9LAoJeyBOVUxMLCAwLCBOVUxMLCBOVUxMIH0KfTsKI2Vsc2UKIyBkZWZpbmUgaWRlY2RfcHJvYwlOVUxMCiNlbmRpZgoKc3RhdGljIGlkZV9kcml2ZXJfdCBpZGVfY2Ryb21fZHJpdmVyID0gewoJLm93bmVyCQkJPSBUSElTX01PRFVMRSwKCS5nZW5fZHJpdmVyID0gewoJCS5uYW1lCQk9ICJpZGUtY2Ryb20iLAoJCS5idXMJCT0gJmlkZV9idXNfdHlwZSwKCQkucHJvYmUJCT0gaWRlX2NkX3Byb2JlLAoJCS5yZW1vdmUJCT0gaWRlX2NkX3JlbW92ZSwKCX0sCgkudmVyc2lvbgkJPSBJREVDRF9WRVJTSU9OLAoJLm1lZGlhCQkJPSBpZGVfY2Ryb20sCgkuc3VwcG9ydHNfZHNjX292ZXJsYXAJPSAxLAoJLmRvX3JlcXVlc3QJCT0gaWRlX2RvX3J3X2Nkcm9tLAoJLmVuZF9yZXF1ZXN0CQk9IGlkZV9lbmRfcmVxdWVzdCwKCS5lcnJvcgkJCT0gX19pZGVfZXJyb3IsCgkuYWJvcnQJCQk9IF9faWRlX2Fib3J0LAoJLnByb2MJCQk9IGlkZWNkX3Byb2MsCn07CgpzdGF0aWMgaW50IGlkZWNkX29wZW4oc3RydWN0IGlub2RlICogaW5vZGUsIHN0cnVjdCBmaWxlICogZmlsZSkKewoJc3RydWN0IGdlbmRpc2sgKmRpc2sgPSBpbm9kZS0+aV9iZGV2LT5iZF9kaXNrOwoJc3RydWN0IGNkcm9tX2luZm8gKmluZm87CglpZGVfZHJpdmVfdCAqZHJpdmU7CglpbnQgcmMgPSAtRU5PTUVNOwoKCWlmICghKGluZm8gPSBpZGVfY2RfZ2V0KGRpc2spKSkKCQlyZXR1cm4gLUVOWElPOwoKCWRyaXZlID0gaW5mby0+ZHJpdmU7CgoJZHJpdmUtPnVzYWdlKys7CgoJaWYgKCFpbmZvLT5idWZmZXIpCgkJaW5mby0+YnVmZmVyID0ga21hbGxvYyhTRUNUT1JfQlVGRkVSX1NJWkUsCgkJCQkJR0ZQX0tFUk5FTHxfX0dGUF9SRVBFQVQpOwogICAgICAgIGlmICghaW5mby0+YnVmZmVyIHx8IChyYyA9IGNkcm9tX29wZW4oJmluZm8tPmRldmluZm8sIGlub2RlLCBmaWxlKSkpCgkJZHJpdmUtPnVzYWdlLS07CgoJaWYgKHJjIDwgMCkKCQlpZGVfY2RfcHV0KGluZm8pOwoKCXJldHVybiByYzsKfQoKc3RhdGljIGludCBpZGVjZF9yZWxlYXNlKHN0cnVjdCBpbm9kZSAqIGlub2RlLCBzdHJ1Y3QgZmlsZSAqIGZpbGUpCnsKCXN0cnVjdCBnZW5kaXNrICpkaXNrID0gaW5vZGUtPmlfYmRldi0+YmRfZGlzazsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvID0gaWRlX2NkX2coZGlzayk7CglpZGVfZHJpdmVfdCAqZHJpdmUgPSBpbmZvLT5kcml2ZTsKCgljZHJvbV9yZWxlYXNlICgmaW5mby0+ZGV2aW5mbywgZmlsZSk7Cglkcml2ZS0+dXNhZ2UtLTsKCglpZGVfY2RfcHV0KGluZm8pOwoKCXJldHVybiAwOwp9CgpzdGF0aWMgaW50IGlkZWNkX2lvY3RsIChzdHJ1Y3QgaW5vZGUgKmlub2RlLCBzdHJ1Y3QgZmlsZSAqZmlsZSwKCQkJdW5zaWduZWQgaW50IGNtZCwgdW5zaWduZWQgbG9uZyBhcmcpCnsKCXN0cnVjdCBibG9ja19kZXZpY2UgKmJkZXYgPSBpbm9kZS0+aV9iZGV2OwoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBpZGVfY2RfZyhiZGV2LT5iZF9kaXNrKTsKCWludCBlcnI7CgoJZXJyICA9IGdlbmVyaWNfaWRlX2lvY3RsKGluZm8tPmRyaXZlLCBmaWxlLCBiZGV2LCBjbWQsIGFyZyk7CglpZiAoZXJyID09IC1FSU5WQUwpCgkJZXJyID0gY2Ryb21faW9jdGwoZmlsZSwgJmluZm8tPmRldmluZm8sIGlub2RlLCBjbWQsIGFyZyk7CgoJcmV0dXJuIGVycjsKfQoKc3RhdGljIGludCBpZGVjZF9tZWRpYV9jaGFuZ2VkKHN0cnVjdCBnZW5kaXNrICpkaXNrKQp7CglzdHJ1Y3QgY2Ryb21faW5mbyAqaW5mbyA9IGlkZV9jZF9nKGRpc2spOwoJcmV0dXJuIGNkcm9tX21lZGlhX2NoYW5nZWQoJmluZm8tPmRldmluZm8pOwp9CgpzdGF0aWMgaW50IGlkZWNkX3JldmFsaWRhdGVfZGlzayhzdHJ1Y3QgZ2VuZGlzayAqZGlzaykKewoJc3RydWN0IGNkcm9tX2luZm8gKmluZm8gPSBpZGVfY2RfZyhkaXNrKTsKCXN0cnVjdCByZXF1ZXN0X3NlbnNlIHNlbnNlOwoJY2Ryb21fcmVhZF90b2MoaW5mby0+ZHJpdmUsICZzZW5zZSk7CglyZXR1cm4gIDA7Cn0KCnN0YXRpYyBzdHJ1Y3QgYmxvY2tfZGV2aWNlX29wZXJhdGlvbnMgaWRlY2Rfb3BzID0gewoJLm93bmVyCQk9IFRISVNfTU9EVUxFLAoJLm9wZW4JCT0gaWRlY2Rfb3BlbiwKCS5yZWxlYXNlCT0gaWRlY2RfcmVsZWFzZSwKCS5pb2N0bAkJPSBpZGVjZF9pb2N0bCwKCS5tZWRpYV9jaGFuZ2VkCT0gaWRlY2RfbWVkaWFfY2hhbmdlZCwKCS5yZXZhbGlkYXRlX2Rpc2s9IGlkZWNkX3JldmFsaWRhdGVfZGlzawp9OwoKLyogb3B0aW9ucyAqLwpzdGF0aWMgY2hhciAqaWdub3JlID0gTlVMTDsKCm1vZHVsZV9wYXJhbShpZ25vcmUsIGNoYXJwLCAwNDAwKTsKTU9EVUxFX0RFU0NSSVBUSU9OKCJBVEFQSSBDRC1ST00gRHJpdmVyIik7CgpzdGF0aWMgaW50IGlkZV9jZF9wcm9iZShzdHJ1Y3QgZGV2aWNlICpkZXYpCnsKCWlkZV9kcml2ZV90ICpkcml2ZSA9IHRvX2lkZV9kZXZpY2UoZGV2KTsKCXN0cnVjdCBjZHJvbV9pbmZvICppbmZvOwoJc3RydWN0IGdlbmRpc2sgKmc7CglzdHJ1Y3QgcmVxdWVzdF9zZW5zZSBzZW5zZTsKCglpZiAoIXN0cnN0cigiaWRlLWNkcm9tIiwgZHJpdmUtPmRyaXZlcl9yZXEpKQoJCWdvdG8gZmFpbGVkOwoJaWYgKCFkcml2ZS0+cHJlc2VudCkKCQlnb3RvIGZhaWxlZDsKCWlmIChkcml2ZS0+bWVkaWEgIT0gaWRlX2Nkcm9tICYmIGRyaXZlLT5tZWRpYSAhPSBpZGVfb3B0aWNhbCkKCQlnb3RvIGZhaWxlZDsKCS8qIHNraXAgZHJpdmVzIHRoYXQgd2Ugd2VyZSB0b2xkIHRvIGlnbm9yZSAqLwoJaWYgKGlnbm9yZSAhPSBOVUxMKSB7CgkJaWYgKHN0cnN0cihpZ25vcmUsIGRyaXZlLT5uYW1lKSkgewoJCQlwcmludGsoS0VSTl9JTkZPICJpZGUtY2Q6IGlnbm9yaW5nIGRyaXZlICVzXG4iLCBkcml2ZS0+bmFtZSk7CgkJCWdvdG8gZmFpbGVkOwoJCX0KCX0KCWlmIChkcml2ZS0+c2NzaSkgewoJCXByaW50ayhLRVJOX0lORk8gImlkZS1jZDogcGFzc2luZyBkcml2ZSAlcyB0byBpZGUtc2NzaSBlbXVsYXRpb24uXG4iLCBkcml2ZS0+bmFtZSk7CgkJZ290byBmYWlsZWQ7Cgl9CglpbmZvID0gKHN0cnVjdCBjZHJvbV9pbmZvICopIGttYWxsb2MgKHNpemVvZiAoc3RydWN0IGNkcm9tX2luZm8pLCBHRlBfS0VSTkVMKTsKCWlmIChpbmZvID09IE5VTEwpIHsKCQlwcmludGsoS0VSTl9FUlIgIiVzOiBDYW4ndCBhbGxvY2F0ZSBhIGNkcm9tIHN0cnVjdHVyZVxuIiwgZHJpdmUtPm5hbWUpOwoJCWdvdG8gZmFpbGVkOwoJfQoKCWcgPSBhbGxvY19kaXNrKDEgPDwgUEFSVE5fQklUUyk7CglpZiAoIWcpCgkJZ290byBvdXRfZnJlZV9jZDsKCglpZGVfaW5pdF9kaXNrKGcsIGRyaXZlKTsKCglpZGVfcmVnaXN0ZXJfc3ViZHJpdmVyKGRyaXZlLCAmaWRlX2Nkcm9tX2RyaXZlcik7CgoJbWVtc2V0KGluZm8sIDAsIHNpemVvZiAoc3RydWN0IGNkcm9tX2luZm8pKTsKCglrcmVmX2luaXQoJmluZm8tPmtyZWYpOwoKCWluZm8tPmRyaXZlID0gZHJpdmU7CglpbmZvLT5kcml2ZXIgPSAmaWRlX2Nkcm9tX2RyaXZlcjsKCWluZm8tPmRpc2sgPSBnOwoKCWctPnByaXZhdGVfZGF0YSA9ICZpbmZvLT5kcml2ZXI7CgoJZHJpdmUtPmRyaXZlcl9kYXRhID0gaW5mbzsKCglnLT5taW5vcnMgPSAxOwoJc25wcmludGYoZy0+ZGV2ZnNfbmFtZSwgc2l6ZW9mKGctPmRldmZzX25hbWUpLAoJCQkiJXMvY2QiLCBkcml2ZS0+ZGV2ZnNfbmFtZSk7CglnLT5kcml2ZXJmc19kZXYgPSAmZHJpdmUtPmdlbmRldjsKCWctPmZsYWdzID0gR0VOSERfRkxfQ0QgfCBHRU5IRF9GTF9SRU1PVkFCTEU7CglpZiAoaWRlX2Nkcm9tX3NldHVwKGRyaXZlKSkgewoJCXN0cnVjdCBjZHJvbV9kZXZpY2VfaW5mbyAqZGV2aW5mbyA9ICZpbmZvLT5kZXZpbmZvOwoJCWlkZV91bnJlZ2lzdGVyX3N1YmRyaXZlcihkcml2ZSwgJmlkZV9jZHJvbV9kcml2ZXIpOwoJCWlmIChpbmZvLT5idWZmZXIgIT0gTlVMTCkKCQkJa2ZyZWUoaW5mby0+YnVmZmVyKTsKCQlpZiAoaW5mby0+dG9jICE9IE5VTEwpCgkJCWtmcmVlKGluZm8tPnRvYyk7CgkJaWYgKGluZm8tPmNoYW5nZXJfaW5mbyAhPSBOVUxMKQoJCQlrZnJlZShpbmZvLT5jaGFuZ2VyX2luZm8pOwoJCWlmIChkZXZpbmZvLT5oYW5kbGUgPT0gZHJpdmUgJiYgdW5yZWdpc3Rlcl9jZHJvbShkZXZpbmZvKSkKCQkJcHJpbnRrIChLRVJOX0VSUiAiJXM6IGlkZV9jZHJvbV9jbGVhbnVwIGZhaWxlZCB0byB1bnJlZ2lzdGVyIGRldmljZSBmcm9tIHRoZSBjZHJvbSBkcml2ZXIuXG4iLCBkcml2ZS0+bmFtZSk7CgkJa2ZyZWUoaW5mbyk7CgkJZHJpdmUtPmRyaXZlcl9kYXRhID0gTlVMTDsKCQlnb3RvIGZhaWxlZDsKCX0KCgljZHJvbV9yZWFkX3RvYyhkcml2ZSwgJnNlbnNlKTsKCWctPmZvcHMgPSAmaWRlY2Rfb3BzOwoJZy0+ZmxhZ3MgfD0gR0VOSERfRkxfUkVNT1ZBQkxFOwoJYWRkX2Rpc2soZyk7CglyZXR1cm4gMDsKCm91dF9mcmVlX2NkOgoJa2ZyZWUoaW5mbyk7CmZhaWxlZDoKCXJldHVybiAtRU5PREVWOwp9CgpzdGF0aWMgdm9pZCBfX2V4aXQgaWRlX2Nkcm9tX2V4aXQodm9pZCkKewoJZHJpdmVyX3VucmVnaXN0ZXIoJmlkZV9jZHJvbV9kcml2ZXIuZ2VuX2RyaXZlcik7Cn0KIApzdGF0aWMgaW50IGlkZV9jZHJvbV9pbml0KHZvaWQpCnsKCXJldHVybiBkcml2ZXJfcmVnaXN0ZXIoJmlkZV9jZHJvbV9kcml2ZXIuZ2VuX2RyaXZlcik7Cn0KCm1vZHVsZV9pbml0KGlkZV9jZHJvbV9pbml0KTsKbW9kdWxlX2V4aXQoaWRlX2Nkcm9tX2V4aXQpOwpNT0RVTEVfTElDRU5TRSgiR1BMIik7Cg==