Ci8qCiAqIElCTSBBU00gU2VydmljZSBQcm9jZXNzb3IgRGV2aWNlIERyaXZlcgogKgogKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeQogKiBpdCB1bmRlciB0aGUgdGVybXMgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieQogKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIgdmVyc2lvbiAyIG9mIHRoZSBMaWNlbnNlLCBvcgogKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCwKICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2YKICogTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZQogKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZSBTb2Z0d2FyZQogKiBGb3VuZGF0aW9uLCBJbmMuLCA1OSBUZW1wbGUgUGxhY2UgLSBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgMDIxMTEtMTMwNywgVVNBLgogKgogKiBDb3B5cmlnaHQgKEMpIElCTSBDb3Jwb3JhdGlvbiwgMjAwNAogKgogKiBBdXRob3I6IE1heCBBc2L2Y2sgPGFtYXhAdXMuaWJtLmNvbT4KICoKICovCgojaW5jbHVkZSA8bGludXgvc2NoZWQuaD4KI2luY2x1ZGUgPGxpbnV4L3NsYWIuaD4KI2luY2x1ZGUgImlibWFzbS5oIgojaW5jbHVkZSAibG93bGV2ZWwuaCIKCi8qCiAqIEFTTSBzZXJ2aWNlIHByb2Nlc3NvciBldmVudCBoYW5kbGluZyByb3V0aW5lcy4KICoKICogRXZlbnRzIGFyZSBzaWduYWxsZWQgdG8gdGhlIGRldmljZSBkcml2ZXJzIHRocm91Z2ggaW50ZXJydXB0cy4KICogVGhleSBoYXZlIHRoZSBmb3JtYXQgb2YgZG90IGNvbW1hbmRzLCB3aXRoIHRoZSB0eXBlIGZpZWxkIHNldCB0bwogKiBzcF9ldmVudC4KICogVGhlIGRyaXZlciBkb2VzIG5vdCBpbnRlcnByZXQgdGhlIGV2ZW50cywgaXQgc2ltcGx5IHN0b3JlcyB0aGVtIGluIGEKICogY2lyY3VsYXIgYnVmZmVyLgogKi8KCnN0YXRpYyB2b2lkIHdha2VfdXBfZXZlbnRfcmVhZGVycyhzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwKQp7CglzdHJ1Y3QgZXZlbnRfcmVhZGVyICpyZWFkZXI7CgoJbGlzdF9mb3JfZWFjaF9lbnRyeShyZWFkZXIsICZzcC0+ZXZlbnRfYnVmZmVyLT5yZWFkZXJzLCBub2RlKQogICAgICAgICAgICAgICAgd2FrZV91cF9pbnRlcnJ1cHRpYmxlKCZyZWFkZXItPndhaXQpOwp9CgovKioKICogcmVjZWl2ZV9ldmVudAogKiBDYWxsZWQgYnkgdGhlIGludGVycnVwdCBoYW5kbGVyIHdoZW4gYSBkb3QgY29tbWFuZCBvZiB0eXBlIHNwX2V2ZW50IGlzCiAqIHJlY2VpdmVkLgogKiBTdG9yZSB0aGUgZXZlbnQgaW4gdGhlIGNpcmN1bGFyIGV2ZW50IGJ1ZmZlciwgd2FrZSB1cCBhbnkgc2xlZXBpbmcKICogZXZlbnQgcmVhZGVycy4KICogVGhlcmUgaXMgbm8gcmVhZGVyIG1hcmtlciBpbiB0aGUgYnVmZmVyLCB0aGVyZWZvcmUgcmVhZGVycyBhcmUKICogcmVzcG9uc2libGUgZm9yIGtlZXBpbmcgdXAgd2l0aCB0aGUgd3JpdGVyLCBvciB0aGV5IHdpbGwgbG9zZSBldmVudHMuCiAqLwp2b2lkIGlibWFzbV9yZWNlaXZlX2V2ZW50KHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3AsIHZvaWQgKmRhdGEsIHVuc2lnbmVkIGludCBkYXRhX3NpemUpCnsKCXN0cnVjdCBldmVudF9idWZmZXIgKmJ1ZmZlciA9IHNwLT5ldmVudF9idWZmZXI7CglzdHJ1Y3QgaWJtYXNtX2V2ZW50ICpldmVudDsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJZGF0YV9zaXplID0gbWluKGRhdGFfc2l6ZSwgSUJNQVNNX0VWRU5UX01BWF9TSVpFKTsKCglzcGluX2xvY2tfaXJxc2F2ZSgmc3AtPmxvY2ssIGZsYWdzKTsKCS8qIGNvcHkgdGhlIGV2ZW50IGludG8gdGhlIG5leHQgc2xvdCBpbiB0aGUgY2lyY3VsYXIgYnVmZmVyICovCglldmVudCA9ICZidWZmZXItPmV2ZW50c1tidWZmZXItPm5leHRfaW5kZXhdOwoJbWVtY3B5X2Zyb21pbyhldmVudC0+ZGF0YSwgZGF0YSwgZGF0YV9zaXplKTsKCWV2ZW50LT5kYXRhX3NpemUgPSBkYXRhX3NpemU7CglldmVudC0+c2VyaWFsX251bWJlciA9IGJ1ZmZlci0+bmV4dF9zZXJpYWxfbnVtYmVyOwoKCS8qIGFkdmFuY2UgaW5kaWNlcyBpbiB0aGUgYnVmZmVyICovCglidWZmZXItPm5leHRfaW5kZXggPSAoYnVmZmVyLT5uZXh0X2luZGV4ICsgMSkgJSBJQk1BU01fTlVNX0VWRU5UUzsKCWJ1ZmZlci0+bmV4dF9zZXJpYWxfbnVtYmVyKys7CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZzcC0+bG9jaywgZmxhZ3MpOwoKCXdha2VfdXBfZXZlbnRfcmVhZGVycyhzcCk7Cn0KCnN0YXRpYyBpbmxpbmUgaW50IGV2ZW50X2F2YWlsYWJsZShzdHJ1Y3QgZXZlbnRfYnVmZmVyICpiLCBzdHJ1Y3QgZXZlbnRfcmVhZGVyICpyKQp7CglyZXR1cm4gKHItPm5leHRfc2VyaWFsX251bWJlciA8IGItPm5leHRfc2VyaWFsX251bWJlcik7Cn0KCi8qKgogKiBnZXRfbmV4dF9ldmVudAogKiBDYWxsZWQgYnkgZXZlbnQgcmVhZGVycyAoaW5pdGlhdGVkIGZyb20gdXNlciBzcGFjZSB0aHJvdWdoIHRoZSBmaWxlCiAqIHN5c3RlbSkuCiAqIFNsZWVwcyB1bnRpbCBhIG5ldyBldmVudCBpcyBhdmFpbGFibGUuCiAqLwppbnQgaWJtYXNtX2dldF9uZXh0X2V2ZW50KHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3AsIHN0cnVjdCBldmVudF9yZWFkZXIgKnJlYWRlcikKewoJc3RydWN0IGV2ZW50X2J1ZmZlciAqYnVmZmVyID0gc3AtPmV2ZW50X2J1ZmZlcjsKCXN0cnVjdCBpYm1hc21fZXZlbnQgKmV2ZW50OwoJdW5zaWduZWQgaW50IGluZGV4OwoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglyZWFkZXItPmNhbmNlbGxlZCA9IDA7CgoJaWYgKHdhaXRfZXZlbnRfaW50ZXJydXB0aWJsZShyZWFkZXItPndhaXQsCgkJCWV2ZW50X2F2YWlsYWJsZShidWZmZXIsIHJlYWRlcikgfHwgcmVhZGVyLT5jYW5jZWxsZWQpKQoJCXJldHVybiAtRVJFU1RBUlRTWVM7CgoJaWYgKCFldmVudF9hdmFpbGFibGUoYnVmZmVyLCByZWFkZXIpKQoJCXJldHVybiAwOwoKCXNwaW5fbG9ja19pcnFzYXZlKCZzcC0+bG9jaywgZmxhZ3MpOwoKCWluZGV4ID0gYnVmZmVyLT5uZXh0X2luZGV4OwoJZXZlbnQgPSAmYnVmZmVyLT5ldmVudHNbaW5kZXhdOwoJd2hpbGUgKGV2ZW50LT5zZXJpYWxfbnVtYmVyIDwgcmVhZGVyLT5uZXh0X3NlcmlhbF9udW1iZXIpIHsKCQlpbmRleCA9IChpbmRleCArIDEpICUgSUJNQVNNX05VTV9FVkVOVFM7CgkJZXZlbnQgPSAmYnVmZmVyLT5ldmVudHNbaW5kZXhdOwoJfQoJbWVtY3B5KHJlYWRlci0+ZGF0YSwgZXZlbnQtPmRhdGEsIGV2ZW50LT5kYXRhX3NpemUpOwoJcmVhZGVyLT5kYXRhX3NpemUgPSBldmVudC0+ZGF0YV9zaXplOwoJcmVhZGVyLT5uZXh0X3NlcmlhbF9udW1iZXIgPSBldmVudC0+c2VyaWFsX251bWJlciArIDE7CgoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmc3AtPmxvY2ssIGZsYWdzKTsKCglyZXR1cm4gZXZlbnQtPmRhdGFfc2l6ZTsKfQoKdm9pZCBpYm1hc21fY2FuY2VsX25leHRfZXZlbnQoc3RydWN0IGV2ZW50X3JlYWRlciAqcmVhZGVyKQp7CiAgICAgICAgcmVhZGVyLT5jYW5jZWxsZWQgPSAxOwogICAgICAgIHdha2VfdXBfaW50ZXJydXB0aWJsZSgmcmVhZGVyLT53YWl0KTsKfQoKdm9pZCBpYm1hc21fZXZlbnRfcmVhZGVyX3JlZ2lzdGVyKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3AsIHN0cnVjdCBldmVudF9yZWFkZXIgKnJlYWRlcikKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglyZWFkZXItPm5leHRfc2VyaWFsX251bWJlciA9IHNwLT5ldmVudF9idWZmZXItPm5leHRfc2VyaWFsX251bWJlcjsKCWluaXRfd2FpdHF1ZXVlX2hlYWQoJnJlYWRlci0+d2FpdCk7CglzcGluX2xvY2tfaXJxc2F2ZSgmc3AtPmxvY2ssIGZsYWdzKTsKCWxpc3RfYWRkKCZyZWFkZXItPm5vZGUsICZzcC0+ZXZlbnRfYnVmZmVyLT5yZWFkZXJzKTsKCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnNwLT5sb2NrLCBmbGFncyk7Cn0KCnZvaWQgaWJtYXNtX2V2ZW50X3JlYWRlcl91bnJlZ2lzdGVyKHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3AsIHN0cnVjdCBldmVudF9yZWFkZXIgKnJlYWRlcikKewoJdW5zaWduZWQgbG9uZyBmbGFnczsKCglzcGluX2xvY2tfaXJxc2F2ZSgmc3AtPmxvY2ssIGZsYWdzKTsKCWxpc3RfZGVsKCZyZWFkZXItPm5vZGUpOwoJc3Bpbl91bmxvY2tfaXJxcmVzdG9yZSgmc3AtPmxvY2ssIGZsYWdzKTsKfQoKaW50IGlibWFzbV9ldmVudF9idWZmZXJfaW5pdChzdHJ1Y3Qgc2VydmljZV9wcm9jZXNzb3IgKnNwKQp7CglzdHJ1Y3QgZXZlbnRfYnVmZmVyICpidWZmZXI7CglzdHJ1Y3QgaWJtYXNtX2V2ZW50ICpldmVudDsKCWludCBpOwoKCWJ1ZmZlciA9IGttYWxsb2Moc2l6ZW9mKHN0cnVjdCBldmVudF9idWZmZXIpLCBHRlBfS0VSTkVMKTsKCWlmICghYnVmZmVyKQoJCXJldHVybiAxOwoKCWJ1ZmZlci0+bmV4dF9pbmRleCA9IDA7CglidWZmZXItPm5leHRfc2VyaWFsX251bWJlciA9IDE7CgoJZXZlbnQgPSBidWZmZXItPmV2ZW50czsKCWZvciAoaT0wOyBpPElCTUFTTV9OVU1fRVZFTlRTOyBpKyssIGV2ZW50KyspCgkJZXZlbnQtPnNlcmlhbF9udW1iZXIgPSAwOwoKCUlOSVRfTElTVF9IRUFEKCZidWZmZXItPnJlYWRlcnMpOwoKCXNwLT5ldmVudF9idWZmZXIgPSBidWZmZXI7CgoJcmV0dXJuIDA7Cn0KCnZvaWQgaWJtYXNtX2V2ZW50X2J1ZmZlcl9leGl0KHN0cnVjdCBzZXJ2aWNlX3Byb2Nlc3NvciAqc3ApCnsKCWtmcmVlKHNwLT5ldmVudF9idWZmZXIpOwp9Cg==