Ci8qCiAqIElCTSBBU00gU2VydmljZSBQcm9jZXNzb3IgRGV2aWNlIERyaXZlcgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLgogKgogKiBDb3B5cmlnaHQgKEMpIElCTSBDb3Jwb3JhdGlvbiwgMjAwNAogKgogKiBBdXRob3I6IE1heCBBc2L2Y2sgPGFtYXhAdXMuaWJtLmNvbT4gCiAqCiAqLwoKI2luY2x1ZGUgImlibWFzbS5oIgojaW5jbHVkZSAibG93bGV2ZWwuaCIKCi8qCiAqIEFTTSBzZXJ2aWNlIHByb2Nlc3NvciBldmVudCBoYW5kbGluZyByb3V0aW5lcy4KICoKICogRXZlbnRzIGFyZSBzaWduYWxsZWQgdG8gdGhlIGRldmljZSBkcml2ZXJzIHRocm91Z2ggaW50ZXJydXB0cy4KICogVGhleSBoYXZlIHRoZSBmb3JtYXQgb2YgZG90IGNvbW1hbmRzLCB3aXRoIHRoZSB0eXBlIGZpZWxkIHNldCB0bwogKiBzcF9ldmVudC4KICogVGhlIGRyaXZlciBkb2VzIG5vdCBpbnRlcnByZXQgdGhlIGV2ZW50cywgaXQgc2ltcGx5IHN0b3JlcyB0aGVtIGluIGEKICogY2lyY3VsYXIgYnVmZmVyLgogKi8KCnN0YXRpYyB2b2lkIHdha2VfdXBfZXZlbnRfcmVhZGVycyhzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwKQp7CglzdHJ1Y3QgZXZlbnRfcmVhZGVyICpyZWFkZXI7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShyZWFkZXIsICZzcC0+ZXZlbnRfYnVmZmVyLT5yZWFkZXJzLCBub2RlKQogICAgICAgICAgICAgICAgd2FrZV91cF9pbnRlcnJ1cHRpYmxlKCZyZWFkZXItPndhaXQpOwp9CgovKioKICogcmVjZWl2ZV9ldmVudAogKiBDYWxsZWQgYnkgdGhlIGludGVycnVwdCBoYW5kbGVyIHdoZW4gYSBkb3QgY29tbWFuZCBvZiB0eXBlIHNwX2V2ZW50IGlzCiAqIHJlY2VpdmVkLgogKiBTdG9yZSB0aGUgZXZlbnQgaW4gdGhlIGNpcmN1bGFyIGV2ZW50IGJ1ZmZlciwgd2FrZSB1cCBhbnkgc2xlZXBpbmcKICogZXZlbnQgcmVhZGVycy4KICogVGhlcmUgaXMgbm8gcmVhZGVyIG1hcmtlciBpbiB0aGUgYnVmZmVyLCB0aGVyZWZvcmUgcmVhZGVycyBhcmUKICogcmVzcG9uc2libGUgZm9yIGtlZXBpbmcgdXAgd2l0aCB0aGUgd3JpdGVyLCBvciB0aGV5IHdpbGwgbG9vc2UgZXZlbnRzLgogKi8gCnZvaWQgaWJtYXNtX3JlY2VpdmVfZXZlbnQoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCwgdm9pZCAqZGF0YSwgdW5zaWduZWQgaW50IGRhdGFfc2l6ZSkKewoJc3RydWN0IGV2ZW50X2J1ZmZlciAqYnVmZmVyID0gc3AtPmV2ZW50X2J1ZmZlcjsKCXN0cnVjdCBpYm1hc21fZXZlbnQgKmV2ZW50OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglkYXRhX3NpemUgPSBtaW4oZGF0YV9zaXplLCBJQk1BU01fRVZFTlRfTUFYX1NJWkUpOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZzcC0+bG9jaywgZmxhZ3MpOwoJLyogY29weSB0aGUgZXZlbnQgaW50byB0aGUgbmV4dCBzbG90IGluIHRoZSBjaXJjdWxhciBidWZmZXIgKi8KCWV2ZW50ID0gJmJ1ZmZlci0+ZXZlbnRzW2J1ZmZlci0+bmV4dF9pbmRleF07CgltZW1jcHlfZnJvbWlvKGV2ZW50LT5kYXRhLCBkYXRhLCBkYXRhX3NpemUpOwoJZXZlbnQtPmRhdGFfc2l6ZSA9IGRhdGFfc2l6ZTsKCWV2ZW50LT5zZXJpYWxfbnVtYmVyID0gYnVmZmVyLT5uZXh0X3NlcmlhbF9udW1iZXI7CgoJLyogYWR2YW5jZSBpbmRpY2VzIGluIHRoZSBidWZmZXIgKi8KCWJ1ZmZlci0+bmV4dF9pbmRleCA9IChidWZmZXItPm5leHRfaW5kZXggKyAxKSAlIElCTUFTTV9OVU1fRVZFTlRTOwoJYnVmZmVyLT5uZXh0X3NlcmlhbF9udW1iZXIrKzsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNwLT5sb2NrLCBmbGFncyk7CgoJd2FrZV91cF9ldmVudF9yZWFkZXJzKHNwKTsKfQoKc3RhdGljIGlubGluZSBpbnQgZXZlbnRfYXZhaWxhYmxlKHN0cnVjdCBldmVudF9idWZmZXIgKmIsIHN0cnVjdCBldmVudF9yZWFkZXIgKnIpCnsKCXJldHVybiAJKHItPm5leHRfc2VyaWFsX251bWJlciA8IGItPm5leHRfc2VyaWFsX251bWJlcik7Cn0KCi8qKgogKiBnZXRfbmV4dF9ldmVudAogKiBDYWxsZWQgYnkgZXZlbnQgcmVhZGVycyAoaW5pdGlhdGVkIGZyb20gdXNlciBzcGFjZSB0aHJvdWdoIHRoZSBmaWxlCiAqIHN5c3RlbSkuIAogKiBTbGVlcHMgdW50aWwgYSBuZXcgZXZlbnQgaXMgYXZhaWxhYmxlLgogKi8KaW50IGlibWFzbV9nZXRfbmV4dF9ldmVudChzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwLCBzdHJ1Y3QgZXZlbnRfcmVhZGVyICpyZWFkZXIpCnsKCXN0cnVjdCBldmVudF9idWZmZXIgKmJ1ZmZlciA9IHNwLT5ldmVudF9idWZmZXI7CglzdHJ1Y3QgaWJtYXNtX2V2ZW50ICpldmVudDsKCXVuc2lnbmVkIGludCBpbmRleDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJcmVhZGVyLT5jYW5jZWxsZWQgPSAwOwoKCWlmICh3YWl0X2V2ZW50X2ludGVycnVwdGlibGUocmVhZGVyLT53YWl0LAoJCQlldmVudF9hdmFpbGFibGUoYnVmZmVyLCByZWFkZXIpIHx8IHJlYWRlci0+Y2FuY2VsbGVkKSkKCQlyZXR1cm4gLUVSRVNUQVJUU1lTOwoKCWlmICghZXZlbnRfYXZhaWxhYmxlKGJ1ZmZlciwgcmVhZGVyKSkKCQlyZXR1cm4gMDsKCglzcGluX2xvY2tfaXJxc2F2ZSgmc3AtPmxvY2ssIGZsYWdzKTsKCglpbmRleCA9IGJ1ZmZlci0+bmV4dF9pbmRleDsKCWV2ZW50ID0gJmJ1ZmZlci0+ZXZlbnRzW2luZGV4XTsKCXdoaWxlIChldmVudC0+c2VyaWFsX251bWJlciA8IHJlYWRlci0+bmV4dF9zZXJpYWxfbnVtYmVyKSB7CgkJaW5kZXggPSAoaW5kZXggKyAxKSAlIElCTUFTTV9OVU1fRVZFTlRTOwoJCWV2ZW50ID0gJmJ1ZmZlci0+ZXZlbnRzW2luZGV4XTsKCX0KCW1lbWNweShyZWFkZXItPmRhdGEsIGV2ZW50LT5kYXRhLCBldmVudC0+ZGF0YV9zaXplKTsKCXJlYWRlci0+ZGF0YV9zaXplID0gZXZlbnQtPmRhdGFfc2l6ZTsKCXJlYWRlci0+bmV4dF9zZXJpYWxfbnVtYmVyID0gZXZlbnQtPnNlcmlhbF9udW1iZXIgKyAxOwoKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNwLT5sb2NrLCBmbGFncyk7CgoJcmV0dXJuIGV2ZW50LT5kYXRhX3NpemU7Cn0KCnZvaWQgaWJtYXNtX2NhbmNlbF9uZXh0X2V2ZW50KHN0cnVjdCBldmVudF9yZWFkZXIgKnJlYWRlcikKewogICAgICAgIHJlYWRlci0+Y2FuY2VsbGVkID0gMTsKICAgICAgICB3YWtlX3VwX2ludGVycnVwdGlibGUoJnJlYWRlci0+d2FpdCk7Cn0KCnZvaWQgaWJtYXNtX2V2ZW50X3JlYWRlcl9yZWdpc3RlcihzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwLCBzdHJ1Y3QgZXZlbnRfcmVhZGVyICpyZWFkZXIpCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJcmVhZGVyLT5uZXh0X3NlcmlhbF9udW1iZXIgPSBzcC0+ZXZlbnRfYnVmZmVyLT5uZXh0X3NlcmlhbF9udW1iZXI7Cglpbml0X3dhaXRxdWV1ZV9oZWFkKCZyZWFkZXItPndhaXQpOwoJc3Bpbl9sb2NrX2lycXNhdmUoJnNwLT5sb2NrLCBmbGFncyk7CglsaXN0X2FkZCgmcmVhZGVyLT5ub2RlLCAmc3AtPmV2ZW50X2J1ZmZlci0+cmVhZGVycyk7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZzcC0+bG9jaywgZmxhZ3MpOwp9Cgp2b2lkIGlibWFzbV9ldmVudF9yZWFkZXJfdW5yZWdpc3RlcihzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwLCBzdHJ1Y3QgZXZlbnRfcmVhZGVyICpyZWFkZXIpCnsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJc3Bpbl9sb2NrX2lycXNhdmUoJnNwLT5sb2NrLCBmbGFncyk7CglsaXN0X2RlbCgmcmVhZGVyLT5ub2RlKTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNwLT5sb2NrLCBmbGFncyk7Cn0KCmludCBpYm1hc21fZXZlbnRfYnVmZmVyX2luaXQoc3RydWN0IHNlcnZpY2VfcHJvY2Vzc29yICpzcCkKewoJc3RydWN0IGV2ZW50X2J1ZmZlciAqYnVmZmVyOwoJc3RydWN0IGlibWFzbV9ldmVudCAqZXZlbnQ7CglpbnQgaTsKCglidWZmZXIgPSBrbWFsbG9jKHNpemVvZihzdHJ1Y3QgZXZlbnRfYnVmZmVyKSwgR0ZQX0tFUk5FTCk7CglpZiAoIWJ1ZmZlcikKCQlyZXR1cm4gMTsKCglidWZmZXItPm5leHRfaW5kZXggPSAwOwoJYnVmZmVyLT5uZXh0X3NlcmlhbF9udW1iZXIgPSAxOwoKCWV2ZW50ID0gYnVmZmVyLT5ldmVudHM7Cglmb3IgKGk9MDsgaTxJQk1BU01fTlVNX0VWRU5UUzsgaSsrLCBldmVudCsrKQoJCWV2ZW50LT5zZXJpYWxfbnVtYmVyID0gMDsKCglJTklUX0xJU1RfSEVBRCgmYnVmZmVyLT5yZWFkZXJzKTsKCglzcC0+ZXZlbnRfYnVmZmVyID0gYnVmZmVyOwoKCXJldHVybiAwOwp9Cgp2b2lkIGlibWFzbV9ldmVudF9idWZmZXJfZXhpdChzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwKQp7CglrZnJlZShzcC0+ZXZlbnRfYnVmZmVyKTsKfQo=