LyoKICogRE9TIGRldmljZXMKICoKICogQ29weXJpZ2h0IDE5OTkgT3ZlIEvldmVuCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBmcmVlIHNvZnR3YXJlOyB5b3UgY2FuIHJlZGlzdHJpYnV0ZSBpdCBhbmQvb3IKICogbW9kaWZ5IGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIExlc3NlciBHZW5lcmFsIFB1YmxpYwogKiBMaWNlbnNlIGFzIHB1Ymxpc2hlZCBieSB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uOyBlaXRoZXIKICogdmVyc2lvbiAyLjEgb2YgdGhlIExpY2Vuc2UsIG9yIChhdCB5b3VyIG9wdGlvbikgYW55IGxhdGVyIHZlcnNpb24uCiAqCiAqIFRoaXMgbGlicmFyeSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLAogKiBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlIEdOVQogKiBMZXNzZXIgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLgogKgogKiBZb3Ugc2hvdWxkIGhhdmUgcmVjZWl2ZWQgYSBjb3B5IG9mIHRoZSBHTlUgTGVzc2VyIEdlbmVyYWwgUHVibGljCiAqIExpY2Vuc2UgYWxvbmcgd2l0aCB0aGlzIGxpYnJhcnk7IGlmIG5vdCwgd3JpdGUgdG8gdGhlIEZyZWUgU29mdHdhcmUKICogRm91bmRhdGlvbiwgSW5jLiwgNTkgVGVtcGxlIFBsYWNlLCBTdWl0ZSAzMzAsIEJvc3RvbiwgTUEgIDAyMTExLTEzMDcgIFVTQQogKi8KCiNpbmNsdWRlIDxzdGRsaWIuaD4KI2luY2x1ZGUgPHN0cmluZy5oPgojaW5jbHVkZSAid2luZS93aW5iYXNlMTYuaCIKI2luY2x1ZGUgImRvc2V4ZS5oIgojaW5jbHVkZSAid2luZS9kZWJ1Zy5oIgoKI2luY2x1ZGUgInBzaHBhY2sxLmgiCgp0eXBlZGVmIHN0cnVjdCB7CiAgQllURSBsam1wMTsKICBSTUNCUFJPQyBzdHJhdGVneTsKICBCWVRFIGxqbXAyOwogIFJNQ0JQUk9DIGludGVycnVwdDsKfSBXSU5FREVWX1RIVU5LOwoKdHlwZWRlZiBzdHJ1Y3QgewogIEJZVEUgc2l6ZTsgLyogbGVuZ3RoIG9mIGhlYWRlciArIGRhdGEgKi8KICBCWVRFIHVuaXQ7IC8qIHVuaXQgKGJsb2NrIGRldmljZXMgb25seSkgKi8KICBCWVRFIGNvbW1hbmQ7CiAgV09SRCBzdGF0dXM7CiAgQllURSByZXNlcnZlZFs4XTsKfSBSRVFVRVNUX0hFQURFUjsKCnR5cGVkZWYgc3RydWN0IHsKICBSRVFVRVNUX0hFQURFUiBoZHI7CiAgQllURSBtZWRpYTsgLyogbWVkaWEgZGVzY3JpcHRvciBmcm9tIEJQQiAqLwogIFNFR1BUUiBidWZmZXI7CiAgV09SRCBjb3VudDsgLyogYnl0ZS9zZWN0b3IgY291bnQgKi8KICBXT1JEIHNlY3RvcjsgLyogc3RhcnRpbmcgc2VjdG9yIChibG9jayBkZXZpY2VzKSAqLwogIERXT1JEIHZvbHVtZTsgLyogdm9sdW1lIElEIChibG9jayBkZXZpY2VzKSAqLwp9IFJFUV9JTzsKCnR5cGVkZWYgc3RydWN0IHsKICBSRVFVRVNUX0hFQURFUiBoZHI7CiAgQllURSBkYXRhOwp9IFJFUV9TQUZFSU5QVVQ7Cgp0eXBlZGVmIHN0cnVjdAp7CiAgICBEV09SRCBuZXh0X2RldjsKICAgIFdPUkQgIGF0dHI7CiAgICBXT1JEICBzdHJhdGVneTsKICAgIFdPUkQgIGludGVycnVwdDsKICAgIGNoYXIgIG5hbWVbOF07Cn0gRE9TX0RFVklDRV9IRUFERVI7CgovKiBXYXJuaW5nOiBuZWVkIHRvIHJldHVybiBMT0wgcHRyIHcvIG9mZnNldCAwICgmcHRyX2ZpcnN0X0RQQikgdG8gcHJvZ3JhbXMgISAqLwp0eXBlZGVmIHN0cnVjdCBfRE9TX0xJU1RPRkxJU1RTCnsKICAgIFdPUkQgIENYX0ludDIxXzVlMDE7ICAgICAgICAvKiAtMjRkIGNvbnRlbnRzIG9mIENYIGZyb20gSU5UIDIxL0FYPTVFMDFoICovCiAgICBXT1JEICBMUlVfY291bnRfRkNCX2NhY2hlOyAgLyogLTIyZCAqLwogICAgV09SRCAgTFJVX2NvdW50X0ZDQl9vcGVuOyAgIC8qIC0yMGQgKi8KICAgIERXT1JEIE9FTV9mdW5jX2hhbmRsZXI7ICAgICAvKiAtMThkIE9FTSBmdW5jdGlvbiBvZiBJTlQgMjEvQUg9RjhoICovCiAgICBXT1JEICBJTlQyMV9vZmZzZXQ7ICAgICAgICAgLyogLTE0ZCBvZmZzZXQgaW4gRE9TIENTIG9mIGNvZGUgdG8gcmV0dXJuIGZyb20gSU5UIDIxIGNhbGwgKi8KICAgIFdPUkQgIHNoYXJpbmdfcmV0cnlfY291bnQ7ICAvKiAtMTJkICovCiAgICBXT1JEICBzaGFyaW5nX3JldHJ5X2RlbGF5OyAgLyogLTEwZCAqLwogICAgRFdPUkQgcHRyX2Rpc2tfYnVmOyAgICAgICAgIC8qIC04ZCBwdHIgdG8gY3VycmVudCBkaXNrIGJ1ZiAqLwogICAgV09SRCAgb2Zmc191bnJlYWRfQ09OOyAgICAgIC8qIC00ZCBwb2ludGVyIGluIERPUyBkYXRhIHNlZ21lbnQgb2YgdW5yZWFkIENPTiBpbnB1dCAqLwogICAgV09SRCAgc2VnX2ZpcnN0X01DQjsgICAgICAgIC8qIC0yZCAqLwogICAgRFdPUkQgcHRyX2ZpcnN0X0RQQjsgICAgICAgIC8qIDAwICovCiAgICBEV09SRCBwdHJfZmlyc3RfU3lzRmlsZVRhYmxlOyAvKiAwNCAqLwogICAgRFdPUkQgcHRyX2Nsb2NrX2Rldl9oZHI7ICAgIC8qIDA4ICovCiAgICBEV09SRCBwdHJfQ09OX2Rldl9oZHI7ICAgICAgLyogMEMgKi8KICAgIFdPUkQgIG1heF9ieXRlX3Blcl9zZWM7ICAgICAvKiAxMCBtYXhpbXVtIGJ5dGVzIHBlciBzZWN0b3Igb2YgYW55IGJsb2NrIGRldmljZSAqLwogICAgRFdPUkQgcHRyX2Rpc2tfYnVmX2luZm87ICAgIC8qIDEyICovCiAgICBEV09SRCBwdHJfYXJyYXlfQ0RTOyAgICAgICAgLyogMTYgY3VycmVudCBkaXJlY3Rvcnkgc3RydWN0dXJlICovCiAgICBEV09SRCBwdHJfc3lzX0ZDQjsgICAgICAgICAgLyogMUEgKi8KICAgIFdPUkQgIG5yX3Byb3RlY3RfRkNCOyAgICAgICAvKiAxRSAqLwogICAgQllURSAgbnJfYmxvY2tfZGV2OyAgICAgICAgIC8qIDIwICovCiAgICBCWVRFICBucl9hdmFpbF9kcml2ZV9sZXR0ZXJzOyAvKiAyMSAqLwogICAgRE9TX0RFVklDRV9IRUFERVIgTlVMX2RldjsgIC8qIDIyICovCiAgICBCWVRFICBucl9kcml2ZXNfSk9JTmVkOyAgICAgLyogMzQgKi8KICAgIFdPUkQgIHB0cl9zcGVjX3ByZ19uYW1lczsgICAvKiAzNSAqLwogICAgRFdPUkQgcHRyX1NFVFZFUl9wcmdfbGlzdDsgIC8qIDM3ICovCiAgICBXT1JEIERPU19ISUdIX0EyMF9mdW5jX29mZnM7LyogM0IgKi8KICAgIFdPUkQgUFNQX2xhc3RfZXhlYzsgICAgICAgICAvKiAzRCBpZiBET1MgaW4gSE1BOiBQU1Agb2YgcHJvZ3JhbSBleGVjdXRlZCBsYXN0OyBpZiBET1MgbG93OiAwMDAwaCAqLwogICAgV09SRCBCVUZGRVJTX3ZhbDsgICAgICAgICAgIC8qIDNGICovCiAgICBXT1JEIEJVRkZFUlNfbnJfbG9va2FoZWFkOyAgLyogNDEgKi8KICAgIEJZVEUgYm9vdF9kcml2ZTsgICAgICAgICAgICAvKiA0MyAqLwogICAgQllURSBmbGFnX0RXT1JEX21vdmVzOyAgICAgIC8qIDQ0IDAxaCBmb3IgMzg2KywgMDBoIG90aGVyd2lzZSAqLwogICAgV09SRCBzaXplX2V4dGVuZGVkX21lbTsgICAgIC8qIDQ1IHNpemUgb2YgZXh0ZW5kZWQgbWVtIGluIEtCICovCiAgICBTRUdQVFIgd2luZV9ybV9sb2w7ICAgICAgICAgLyogLS0gd2luZTogUmVhbCBtb2RlIHBvaW50ZXIgdG8gTE9MICovCiAgICBTRUdQVFIgd2luZV9wbV9sb2w7ICAgICAgICAgLyogLS0gd2luZTogUHJvdGVjdGVkIG1vZGUgcG9pbnRlciB0byBMT0wgKi8KfSBET1NfTElTVE9GTElTVFM7CgojaW5jbHVkZSAicG9wcGFjay5oIgoKI2RlZmluZSBDT05fQlVGRkVSIDEyOAoKZW51bSBzdHJhdGVneSB7IFNZU1RFTV9TVFJBVEVHWV9OVUwsIFNZU1RFTV9TVFJBVEVHWV9DT04sIE5CX1NZU1RFTV9TVFJBVEVHSUVTIH07CgpzdGF0aWMgdm9pZCAqc3RyYXRlZ3lfZGF0YVtOQl9TWVNURU1fU1RSQVRFR0lFU107CgojZGVmaW5lIE5PTkVYVCAoKERXT1JEKS0xKQoKI2RlZmluZSBBVFRSX1NURElOICAgICAweDAwMDEKI2RlZmluZSBBVFRSX1NURE9VVCAgICAweDAwMDIKI2RlZmluZSBBVFRSX05VTCAgICAgICAweDAwMDQKI2RlZmluZSBBVFRSX0NMT0NLICAgICAweDAwMDgKI2RlZmluZSBBVFRSX0ZBU1RDT04gICAweDAwMTAKI2RlZmluZSBBVFRSX1JBVyAgICAgICAweDAwMjAKI2RlZmluZSBBVFRSX05PVEVPRiAgICAweDAwNDAKI2RlZmluZSBBVFRSX0RFVklDRSAgICAweDAwODAKI2RlZmluZSBBVFRSX1JFTU9WQUJMRSAweDA4MDAKI2RlZmluZSBBVFRSX05PTklCTSAgICAweDIwMDAgLyogYmxvY2sgZGV2aWNlcyAqLwojZGVmaW5lIEFUVFJfVU5USUxCVVNZIDB4MjAwMCAvKiBjaGFyIGRldmljZXMgKi8KI2RlZmluZSBBVFRSX0lPQ1RMICAgICAweDQwMDAKI2RlZmluZSBBVFRSX0NIQVIgICAgICAweDgwMDAKCiNkZWZpbmUgQ01EX0lOSVQgICAgICAgMAojZGVmaW5lIENNRF9NRURJQUNIRUNLIDEgLyogYmxvY2sgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9CVUlMREJQQiAgIDIgLyogYmxvY2sgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9JTklPQ1RMICAgIDMKI2RlZmluZSBDTURfSU5QVVQgICAgICA0IC8qIHJlYWQgZGF0YSAqLwojZGVmaW5lIENNRF9TQUZFSU5QVVQgIDUgLyogIm5vbi1kZXN0cnVjdGl2ZSBpbnB1dCBubyB3YWl0IiwgY2hhciBkZXZpY2VzICovCiNkZWZpbmUgQ01EX0lOU1RBVFVTICAgNiAvKiBjaGFyIGRldmljZXMgKi8KI2RlZmluZSBDTURfSU5GTFVTSCAgICA3IC8qIGNoYXIgZGV2aWNlcyAqLwojZGVmaW5lIENNRF9PVVRQVVQgICAgIDggLyogd3JpdGUgZGF0YSAqLwojZGVmaW5lIENNRF9TQUZFT1VUUFVUIDkgLyogd3JpdGUgZGF0YSB3aXRoIHZlcmlmeSAqLwojZGVmaW5lIENNRF9PVVRTVEFUVVMgMTAgLyogY2hhciBkZXZpY2VzICovCiNkZWZpbmUgQ01EX09VVEZMVVNIICAxMSAvKiBjaGFyIGRldmljZXMgKi8KI2RlZmluZSBDTURfT1VUSU9DVEwgIDEyCiNkZWZpbmUgQ01EX0RFVk9QRU4gICAxMwojZGVmaW5lIENNRF9ERVZDTE9TRSAgMTQKI2RlZmluZSBDTURfUkVNT1ZBQkxFIDE1IC8qIGJsb2NrIGRldmljZXMgKi8KI2RlZmluZSBDTURfVU5USUxCVVNZIDE2IC8qIG91dHB1dCB1bnRpbCBidXN5ICovCgojZGVmaW5lIFNUQVRfTUFTSyAgMHgwMEZGCiNkZWZpbmUgU1RBVF9ET05FICAweDAxMDAKI2RlZmluZSBTVEFUX0JVU1kgIDB4MDIwMAojZGVmaW5lIFNUQVRfRVJST1IgMHg4MDAwCgojZGVmaW5lIExKTVAgMHhlYQoKCi8qIHByb3RvdHlwZXMgKi8Kc3RhdGljIHZvaWQgV0lOQVBJIG51bF9zdHJhdGVneShDT05URVhUODYqY3R4KTsKc3RhdGljIHZvaWQgV0lOQVBJIG51bF9pbnRlcnJ1cHQoQ09OVEVYVDg2KmN0eCk7CnN0YXRpYyB2b2lkIFdJTkFQSSBjb25fc3RyYXRlZ3koQ09OVEVYVDg2KmN0eCk7CnN0YXRpYyB2b2lkIFdJTkFQSSBjb25faW50ZXJydXB0KENPTlRFWFQ4NipjdHgpOwoKLyogZGV2aWNlcyAqLwp0eXBlZGVmIHN0cnVjdAp7CiAgICBjaGFyIG5hbWVbOF07CiAgICBXT1JEIGF0dHI7CiAgICBSTUNCUFJPQyBzdHJhdGVneTsKICAgIFJNQ0JQUk9DIGludGVycnVwdDsKfSBXSU5FREVWOwoKc3RhdGljIFdJTkVERVYgZGV2c1tdID0KewogIHsgIk5VTCAgICAgIiwKICAgIEFUVFJfQ0hBUnxBVFRSX05VTHxBVFRSX0RFVklDRSwKICAgIG51bF9zdHJhdGVneSwgbnVsX2ludGVycnVwdCB9LAoKICB7ICJDT04gICAgICIsCiAgICBBVFRSX0NIQVJ8QVRUUl9TVERJTnxBVFRSX1NURE9VVHxBVFRSX0ZBU1RDT058QVRUUl9OT1RFT0Z8QVRUUl9ERVZJQ0UsCiAgICBjb25fc3RyYXRlZ3ksIGNvbl9pbnRlcnJ1cHQgfQp9OwoKI2RlZmluZSBOUl9ERVZTIChzaXplb2YoZGV2cykvc2l6ZW9mKFdJTkVERVYpKQoKLyogRE9TIGRhdGEgc2VnbWVudCAqLwp0eXBlZGVmIHN0cnVjdAp7CiAgICBET1NfTElTVE9GTElTVFMgICAgbG9sOwogICAgRE9TX0RFVklDRV9IRUFERVIgIGRldltOUl9ERVZTLTFdOwogICAgV0lORURFVl9USFVOSyAgICAgIHRodW5rW05SX0RFVlNdOwogICAgUkVRX0lPICAgICAgICAgICAgIHJlcTsKICAgIEJZVEUgICAgICAgICAgICAgICBidWZmZXJbQ09OX0JVRkZFUl07Cgp9IERPU19EQVRBU0VHOwoKI2RlZmluZSBET1NfREFUQVNFR19PRkYoeHh4KSBGSUVMRF9PRkZTRVQoRE9TX0RBVEFTRUcsIHh4eCkKCkRXT1JEIERPU19MT0xTZWc7CgpzdGF0aWMgc3RydWN0IF9ET1NfTElTVE9GTElTVFMgKiBET1NNRU1fTE9MKCkKewogICAgcmV0dXJuIFBUUl9SRUFMX1RPX0xJTihISVdPUkQoRE9TX0xPTFNlZyksMCk7Cn0KCgovKiB0aGUgZGV2aWNlIGltcGxlbWVudGF0aW9ucyAqLwpzdGF0aWMgdm9pZCBkb19scmV0KENPTlRFWFQ4NipjdHgpCnsKICBXT1JEICpzdGFjayA9IENUWF9TRUdfT0ZGX1RPX0xJTihjdHgsIGN0eC0+U2VnU3MsIGN0eC0+RXNwKTsKCiAgY3R4LT5FaXAgICA9ICooc3RhY2srKyk7CiAgY3R4LT5TZWdDcyA9ICooc3RhY2srKyk7CiAgY3R4LT5Fc3AgICs9IDIqc2l6ZW9mKFdPUkQpOwp9CgpzdGF0aWMgdm9pZCBkb19zdHJhdGVneShDT05URVhUODYqY3R4LCBpbnQgaWQsIGludCBleHRyYSkKewogIFJFUVVFU1RfSEVBREVSICpoZHIgPSBDVFhfU0VHX09GRl9UT19MSU4oY3R4LCBjdHgtPlNlZ0VzLCBjdHgtPkVieCk7CiAgdm9pZCAqKmhkcl9wdHIgPSBzdHJhdGVneV9kYXRhW2lkXTsKCiAgaWYgKCFoZHJfcHRyKSB7CiAgICBoZHJfcHRyID0gY2FsbG9jKDEsc2l6ZW9mKHZvaWQgKikrZXh0cmEpOwogICAgc3RyYXRlZ3lfZGF0YVtpZF0gPSBoZHJfcHRyOwogIH0KICAqaGRyX3B0ciA9IGhkcjsKICBkb19scmV0KGN0eCk7Cn0KCnN0YXRpYyBSRVFVRVNUX0hFQURFUiAqIGdldF9oZHIoaW50IGlkLCB2b2lkKipleHRyYSkKewogIHZvaWQgKipoZHJfcHRyID0gc3RyYXRlZ3lfZGF0YVtpZF07CiAgaWYgKGV4dHJhKQogICAgKmV4dHJhID0gaGRyX3B0ciA/ICh2b2lkKikoaGRyX3B0cisxKSA6ICh2b2lkICopTlVMTDsKICByZXR1cm4gaGRyX3B0ciA/ICpoZHJfcHRyIDogKHZvaWQgKilOVUxMOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgbnVsX3N0cmF0ZWd5KENPTlRFWFQ4NipjdHgpCnsKICBkb19zdHJhdGVneShjdHgsIFNZU1RFTV9TVFJBVEVHWV9OVUwsIDApOwp9CgpzdGF0aWMgdm9pZCBXSU5BUEkgbnVsX2ludGVycnVwdChDT05URVhUODYqY3R4KQp7CiAgUkVRVUVTVF9IRUFERVIgKmhkciA9IGdldF9oZHIoU1lTVEVNX1NUUkFURUdZX05VTCwgTlVMTCk7CiAgLyogZWF0IGV2ZXJ5dGhpbmcgYW5kIHJlY3ljbGUgbm90aGluZyAqLwogIHN3aXRjaCAoaGRyLT5jb21tYW5kKSB7CiAgY2FzZSBDTURfSU5QVVQ6CiAgICAoKFJFUV9JTyopaGRyKS0+Y291bnQgPSAwOwogICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgICBicmVhazsKICBjYXNlIENNRF9TQUZFSU5QVVQ6CiAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORXxTVEFUX0JVU1k7CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgfQogIGRvX2xyZXQoY3R4KTsKfQoKc3RhdGljIHZvaWQgV0lOQVBJIGNvbl9zdHJhdGVneShDT05URVhUODYqY3R4KQp7CiAgZG9fc3RyYXRlZ3koY3R4LCBTWVNURU1fU1RSQVRFR1lfQ09OLCBzaXplb2YoaW50KSk7Cn0KCnN0YXRpYyB2b2lkIFdJTkFQSSBjb25faW50ZXJydXB0KENPTlRFWFQ4NipjdHgpCnsKICBpbnQgKnNjYW47CiAgUkVRVUVTVF9IRUFERVIgKmhkciA9IGdldF9oZHIoU1lTVEVNX1NUUkFURUdZX0NPTiwodm9pZCAqKikmc2Nhbik7CiAgQklPU0RBVEEgKmJpb3MgPSBET1NWTV9CaW9zRGF0YSgpOwogIFdPUkQgQ3VyT2ZzID0gYmlvcy0+TmV4dEtiZENoYXJQdHI7CiAgRE9TX0xJU1RPRkxJU1RTICpsb2wgPSBET1NNRU1fTE9MKCk7CiAgRE9TX0RBVEFTRUcgKmRhdGFzZWcgPSAoRE9TX0RBVEFTRUcgKilsb2w7CiAgQllURSAqbGluZWJ1ZmZlciA9IGRhdGFzZWctPmJ1ZmZlcjsKICBCWVRFICpjdXJidWZmZXIgPSAobG9sLT5vZmZzX3VucmVhZF9DT04pID8KICAgICgoKEJZVEUqKWRhdGFzZWcpICsgbG9sLT5vZmZzX3VucmVhZF9DT04pIDogKEJZVEUqKU5VTEw7CiAgRE9TX0RFVklDRV9IRUFERVIgKmNvbiA9IGRhdGFzZWctPmRldjsKICBEV09SRCB3OwoKICBzd2l0Y2ggKGhkci0+Y29tbWFuZCkgewogIGNhc2UgQ01EX0lOUFVUOgogICAgewogICAgICBSRVFfSU8gKmlvID0gKFJFUV9JTyAqKWhkcjsKICAgICAgV09SRCBjb3VudCA9IGlvLT5jb3VudCwgbGVuID0gMDsKICAgICAgQllURSAqYnVmZmVyID0gQ1RYX1NFR19PRkZfVE9fTElOKGN0eCwKCQkJCQlTRUxFQ1RPUk9GKGlvLT5idWZmZXIpLAoJCQkJCShEV09SRClPRkZTRVRPRihpby0+YnVmZmVyKSk7CgogICAgICBoZHItPnN0YXR1cyA9IFNUQVRfQlVTWTsKICAgICAgLyogZmlyc3QsIGNoZWNrIHdoZXRoZXIgd2UgYWxyZWFkeSBoYXZlIGRhdGEgaW4gbGluZSBidWZmZXIgKi8KICAgICAgaWYgKGN1cmJ1ZmZlcikgewoJLyogeWVwLCBjb3B5IGFzIG11Y2ggYXMgd2UgY2FuICovCglCWVRFIGRhdGEgPSAwOwoJd2hpbGUgKChsZW48Y291bnQpICYmIChkYXRhICE9ICdccicpKSB7CgkgIGRhdGEgPSAqY3VyYnVmZmVyKys7CgkgIGJ1ZmZlcltsZW4rK10gPSBkYXRhOwoJfQoJaWYgKGRhdGEgPT0gJ1xyJykgewoJICAvKiBsaW5lIGJ1ZmZlciBlbXB0aWVkICovCgkgIGxvbC0+b2Zmc191bnJlYWRfQ09OID0gMDsKCSAgY3VyYnVmZmVyID0gTlVMTDsKCSAgLyogaWYgd2UncmUgbm90IGluIHJhdyBtb2RlLCBjYWxsIGl0IGEgZGF5ICovCgkgIGlmICghKGNvbi0+YXR0ciAmIEFUVFJfUkFXKSkgewoJICAgIGhkci0+c3RhdHVzID0gU1RBVF9ET05FOwoJICAgIGlvLT5jb3VudCA9IGxlbjsKCSAgICBicmVhazsKCSAgfQoJfSBlbHNlIHsKCSAgLyogc3RpbGwgc29tZSBkYXRhIGxlZnQgKi8KCSAgbG9sLT5vZmZzX3VucmVhZF9DT04gPSBjdXJidWZmZXIgLSAoQllURSopbG9sOwoJICAvKiBidXQgYnVmZmVyIHdhcyBmaWxsZWQsIHdlJ3JlIGRvbmUgKi8KCSAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CgkgIGlvLT5jb3VudCA9IGxlbjsKCSAgYnJlYWs7Cgl9CiAgICAgIH0KCiAgICAgIC8qIGlmIHdlJ3JlIGluIHJhdyBtb2RlLCB3ZSBqdXN0IG5lZWQgdG8gZmlsbCB0aGUgYnVmZmVyICovCiAgICAgIGlmIChjb24tPmF0dHIgJiBBVFRSX1JBVykgewoJd2hpbGUgKGxlbjxjb3VudCkgewoJICBXT1JEIGRhdGE7CgoJICAvKiBkbyB3ZSBoYXZlIGEgd2FpdGluZyBzY2FuY29kZT8gKi8KCSAgaWYgKCpzY2FuKSB7CgkgICAgLyogeWVzLCBzdG9yZSBzY2FuY29kZSBpbiBidWZmZXIgKi8KCSAgICBidWZmZXJbbGVuKytdID0gKnNjYW47CgkgICAgKnNjYW4gPSAwOwoJICAgIGlmIChsZW49PWNvdW50KSBicmVhazsKCSAgfQoKCSAgLyogY2hlY2sgZm9yIG5ldyBrZXlib2FyZCBpbnB1dCAqLwoJICB3aGlsZSAoQ3VyT2ZzID09IGJpb3MtPkZpcnN0S2JkQ2hhclB0cikgewoJICAgIC8qIG5vIGlucHV0IGF2YWlsYWJsZSB5ZXQsIHNvIHdhaXQuLi4gKi8KCSAgICBET1NWTV9XYWl0KCBjdHggKTsKCSAgfQoJICAvKiByZWFkIGZyb20ga2V5Ym9hcmQgcXVldWUgKGNhbGwgaW50MTY/KSAqLwoJICBkYXRhID0gKChXT1JEKiliaW9zKVtDdXJPZnNdOwoJICBDdXJPZnMgKz0gMjsKCSAgaWYgKEN1ck9mcyA+PSBiaW9zLT5LYmRCdWZmZXJFbmQpIEN1ck9mcyA9IGJpb3MtPktiZEJ1ZmZlclN0YXJ0OwoJICBiaW9zLT5OZXh0S2JkQ2hhclB0ciA9IEN1ck9mczsKCSAgLyogaWYgaXQncyBhbiBleHRlbmRlZCBrZXksIHNhdmUgc2NhbmNvZGUgKi8KCSAgaWYgKExPQllURShkYXRhKSA9PSAwKSAqc2NhbiA9IEhJQllURShkYXRhKTsKCSAgLyogc3RvcmUgQVNDSUkgY2hhciBpbiBidWZmZXIgKi8KCSAgYnVmZmVyW2xlbisrXSA9IExPQllURShkYXRhKTsKCX0KICAgICAgfSBlbHNlIHsKCS8qIHdlJ3JlIG5vdCBpbiByYXcgbW9kZSwgc28gd2UgbmVlZCB0byBkbyBsaW5lIGlucHV0Li4uICovCgl3aGlsZSAoVFJVRSkgewoJICBXT1JEIGRhdGE7CgkgIC8qIGNoZWNrIGZvciBuZXcga2V5Ym9hcmQgaW5wdXQgKi8KCSAgd2hpbGUgKEN1ck9mcyA9PSBiaW9zLT5GaXJzdEtiZENoYXJQdHIpIHsKCSAgICAvKiBubyBpbnB1dCBhdmFpbGFibGUgeWV0LCBzbyB3YWl0Li4uICovCgkgICAgRE9TVk1fV2FpdCggY3R4ICk7CgkgIH0KCSAgLyogcmVhZCBmcm9tIGtleWJvYXJkIHF1ZXVlIChjYWxsIGludDE2PykgKi8KCSAgZGF0YSA9ICgoV09SRCopYmlvcylbQ3VyT2ZzXTsKCSAgQ3VyT2ZzICs9IDI7CgkgIGlmIChDdXJPZnMgPj0gYmlvcy0+S2JkQnVmZmVyRW5kKSBDdXJPZnMgPSBiaW9zLT5LYmRCdWZmZXJTdGFydDsKCSAgYmlvcy0+TmV4dEtiZENoYXJQdHIgPSBDdXJPZnM7CgoJICBpZiAoTE9CWVRFKGRhdGEpID09ICdccicpIHsKCSAgICAvKiBpdCdzIHRoZSByZXR1cm4ga2V5LCB3ZSdyZSBkb25lICovCgkgICAgbGluZWJ1ZmZlcltsZW4rK10gPSBMT0JZVEUoZGF0YSk7CgkgICAgYnJlYWs7CgkgIH0KCSAgZWxzZSBpZiAoTE9CWVRFKGRhdGEpID49ICcgJykgewoJICAgIC8qIGEgY2hhcmFjdGVyICovCgkgICAgaWYgKChsZW4rMSk8Q09OX0JVRkZFUikgewoJICAgICAgbGluZWJ1ZmZlcltsZW5dID0gTE9CWVRFKGRhdGEpOwoJICAgICAgV3JpdGVGaWxlKEdldFN0ZEhhbmRsZShTVERfT1VUUFVUX0hBTkRMRSksICZsaW5lYnVmZmVyW2xlbisrXSwgMSwgJncsIE5VTEwpOwoJICAgIH0KCSAgICAvKiBlbHNlIGJlZXAsIGJ1dCBJIGRvbid0IGxpa2Ugbm9pc2UgKi8KCSAgfQoJICBlbHNlIHN3aXRjaCAoTE9CWVRFKGRhdGEpKSB7CgkgIGNhc2UgJ1xiJzoKCSAgICBpZiAobGVuPjApIHsKCSAgICAgIGxlbi0tOwoJICAgICAgV3JpdGVGaWxlKEdldFN0ZEhhbmRsZShTVERfT1VUUFVUX0hBTkRMRSksICJcYiBcYiIsIDMsICZ3LCBOVUxMKTsKCSAgICB9CgkgICAgYnJlYWs7CgkgIH0KCX0KCWlmIChsZW4gPiBjb3VudCkgewoJICAvKiBzYXZlIHJlc3Qgb2YgbGluZSBmb3IgbGF0ZXIgKi8KCSAgbG9sLT5vZmZzX3VucmVhZF9DT04gPSBsaW5lYnVmZmVyIC0gKEJZVEUqKWxvbCArIGNvdW50OwoJICBsZW4gPSBjb3VudDsKCX0KCW1lbWNweShidWZmZXIsIGxpbmVidWZmZXIsIGxlbik7CiAgICAgIH0KICAgICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgICAgIGlvLT5jb3VudCA9IGxlbjsKICAgIH0KICAgIGJyZWFrOwogIGNhc2UgQ01EX1NBRkVJTlBVVDoKICAgIGlmIChjdXJidWZmZXIpIHsKICAgICAgLyogc29tZSBsaW5lIGlucHV0IHdhaXRpbmcgKi8KICAgICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgICAgICgoUkVRX1NBRkVJTlBVVCopaGRyKS0+ZGF0YSA9ICpjdXJidWZmZXI7CiAgICB9CiAgICBlbHNlIGlmIChjb24tPmF0dHIgJiBBVFRSX1JBVykgewogICAgICBpZiAoQ3VyT2ZzID09IGJpb3MtPkZpcnN0S2JkQ2hhclB0cikgewoJLyogbm8gaW5wdXQgKi8KCWhkci0+c3RhdHVzID0gU1RBVF9ET05FfFNUQVRfQlVTWTsKICAgICAgfSBlbHNlIHsKCS8qIHNvbWUga2V5Ym9hcmQgaW5wdXQgd2FpdGluZyAqLwoJaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CgkoKFJFUV9TQUZFSU5QVVQqKWhkciktPmRhdGEgPSAoKEJZVEUqKWJpb3MpW0N1ck9mc107CiAgICAgIH0KICAgIH0gZWxzZSB7CiAgICAgIC8qIG5vIGxpbmUgaW5wdXQgKi8KICAgICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkV8U1RBVF9CVVNZOwogICAgfQogICAgYnJlYWs7CiAgY2FzZSBDTURfSU5TVEFUVVM6CiAgICBpZiAoY3VyYnVmZmVyKSB7CiAgICAgIC8qIHdlIGhhdmUgZGF0YSAqLwogICAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKICAgIH0KICAgIGVsc2UgaWYgKGNvbi0+YXR0ciAmIEFUVFJfUkFXKSB7CiAgICAgIGlmIChDdXJPZnMgPT0gYmlvcy0+Rmlyc3RLYmRDaGFyUHRyKSB7CgkvKiBubyBpbnB1dCAqLwoJaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkV8U1RBVF9CVVNZOwogICAgICB9IGVsc2UgewoJLyogc29tZSBrZXlib2FyZCBpbnB1dCB3YWl0aW5nICovCgloZHItPnN0YXR1cyA9IFNUQVRfRE9ORTsKICAgICAgfQogICAgfSBlbHNlIHsKICAgICAgLyogbm8gbGluZSBpbnB1dCAqLwogICAgICBoZHItPnN0YXR1cyA9IFNUQVRfRE9ORXxTVEFUX0JVU1k7CiAgICB9CgogICAgYnJlYWs7CiAgY2FzZSBDTURfSU5GTFVTSDoKICAgIC8qIGZsdXNoIGxpbmUgYW5kIGtleWJvYXJkIHF1ZXVlICovCiAgICBsb2wtPm9mZnNfdW5yZWFkX0NPTiA9IDA7CiAgICBiaW9zLT5OZXh0S2JkQ2hhclB0ciA9IGJpb3MtPkZpcnN0S2JkQ2hhclB0cjsKICAgIGJyZWFrOwogIGNhc2UgQ01EX09VVFBVVDoKICBjYXNlIENNRF9TQUZFT1VUUFVUOgogICAgewogICAgICBSRVFfSU8gKmlvID0gKFJFUV9JTyAqKWhkcjsKICAgICAgQllURSAqYnVmZmVyID0gQ1RYX1NFR19PRkZfVE9fTElOKGN0eCwKCQkJCQlTRUxFQ1RPUk9GKGlvLT5idWZmZXIpLAoJCQkJCShEV09SRClPRkZTRVRPRihpby0+YnVmZmVyKSk7CiAgICAgIERXT1JEIHJlc3VsdCA9IDA7CiAgICAgIFdyaXRlRmlsZShHZXRTdGRIYW5kbGUoU1REX09VVFBVVF9IQU5ETEUpLCBidWZmZXIsIGlvLT5jb3VudCwgJnJlc3VsdCwgTlVMTCk7CiAgICAgIGlvLT5jb3VudCA9IHJlc3VsdDsKICAgICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgICB9CiAgICBicmVhazsKICBkZWZhdWx0OgogICAgaGRyLT5zdGF0dXMgPSBTVEFUX0RPTkU7CiAgfQogIGRvX2xyZXQoY3R4KTsKfQoKc3RhdGljIHZvaWQgSW5pdExpc3RPZkxpc3RzKERPU19MSVNUT0ZMSVNUUyAqRE9TX0xPTCkKewovKgpPdXRwdXQgb2YgRE9TIDYuMjI6CgowMTMzOjAwMjAgICAgICAgICAgICAgICAgICAgIDZBIDEzLTMzIDAxIENDIDAwIDMzIDAxIDU5IDAwICAgICAgICAgai4zLi4uMy5ZLgowMTMzOjAwMzAgIDcwIDAwIDAwIDAwIDcyIDAyIDAwIDAyLTZEIDAwIDMzIDAxIDAwIDAwIDJFIDA1ICAgcC4uLnIuLi5tLjMuLi4uLgowMTMzOjAwNDAgIDAwIDAwIEZDIDA0IDAwIDAwIDAzIDA4LTkyIDIxIDExIEUwIDA0IDgwIEM2IDBEICAgLi4uLi4uLi4uIS4uLi4uLgowMTMzOjAwNTAgIENDIDBEIDRFIDU1IDRDIDIwIDIwIDIwLTIwIDIwIDAwIDAwIDAwIDAwIDAwIDAwICAgLi5OVUwgICAgIC4uLi4uLgowMTMzOjAwNjAgIDAwIDRCIEJBIEMxIDA2IDE0IDAwIDAwLTAwIDAzIDAxIDAwIDA0IDcwIENFIEZGICAgLksuLi4uLi4uLi4uLnAuLgowMTMzOjAwNzAgIEZGIDAwIDAwIDAwIDAwIDAwIDAwIDAwLTAwIDAxIDAwIDAwIDBEIDA1IDAwIDAwICAgLi4uLi4uLi4uLi4uLi4uLgowMTMzOjAwODAgIDAwIEZGIEZGIDAwIDAwIDAwIDAwIEZFLTAwIDAwIEY4IDAzIEZGIDlGIDcwIDAyICAgLi4uLi4uLi4uLi4uLi5wLgowMTMzOjAwOTAgIEQwIDQ0IEM4IEZEIEQ0IDQ0IEM4IEZELUQ0IDQ0IEM4IEZEIEQwIDQ0IEM4IEZEICAgLkQuLi5ELi4uRC4uLkQuLgowMTMzOjAwQTAgIEQwIDQ0IEM4IEZEIEQwIDQ0ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLkQuLi5ECiovCiAgRE9TX0xPTC0+Q1hfSW50MjFfNWUwMQkJPSAweDA7CiAgRE9TX0xPTC0+TFJVX2NvdW50X0ZDQl9jYWNoZQk9IDB4MDsKICBET1NfTE9MLT5MUlVfY291bnRfRkNCX29wZW4JCT0gMHgwOwogIERPU19MT0wtPk9FTV9mdW5jX2hhbmRsZXIJCT0gLTE7IC8qIG5vdCBhdmFpbGFibGUgKi8KICBET1NfTE9MLT5JTlQyMV9vZmZzZXQJCT0gMHgwOwogIERPU19MT0wtPnNoYXJpbmdfcmV0cnlfY291bnQJPSAzOwogIERPU19MT0wtPnNoYXJpbmdfcmV0cnlfZGVsYXkJPSAxOwogIERPU19MT0wtPnB0cl9kaXNrX2J1ZgkJPSAweDA7CiAgRE9TX0xPTC0+b2Zmc191bnJlYWRfQ09OCQk9IDB4MDsKICBET1NfTE9MLT5zZWdfZmlyc3RfTUNCCQk9IDB4MDsKICBET1NfTE9MLT5wdHJfZmlyc3RfRFBCCQk9IDB4MDsKICBET1NfTE9MLT5wdHJfZmlyc3RfU3lzRmlsZVRhYmxlCT0gMHgwOwogIERPU19MT0wtPnB0cl9jbG9ja19kZXZfaGRyCQk9IDB4MDsKICBET1NfTE9MLT5wdHJfQ09OX2Rldl9oZHIJCT0gMHgwOwogIERPU19MT0wtPm1heF9ieXRlX3Blcl9zZWMJCT0gNTEyOwogIERPU19MT0wtPnB0cl9kaXNrX2J1Zl9pbmZvCQk9IDB4MDsKICBET1NfTE9MLT5wdHJfYXJyYXlfQ0RTCQk9IDB4MDsKICBET1NfTE9MLT5wdHJfc3lzX0ZDQgkJPSAweDA7CiAgRE9TX0xPTC0+bnJfcHJvdGVjdF9GQ0IJCT0gMHgwOwogIERPU19MT0wtPm5yX2Jsb2NrX2RldgkJPSAweDA7CiAgRE9TX0xPTC0+bnJfYXZhaWxfZHJpdmVfbGV0dGVycwk9IDI2OyAvKiBBIC0gWiAqLwogIERPU19MT0wtPm5yX2RyaXZlc19KT0lOZWQJCT0gMHgwOwogIERPU19MT0wtPnB0cl9zcGVjX3ByZ19uYW1lcwkJPSAweDA7CiAgRE9TX0xPTC0+cHRyX1NFVFZFUl9wcmdfbGlzdAk9IDB4MDsgLyogbm8gU0VUVkVSIGxpc3QgKi8KICBET1NfTE9MLT5ET1NfSElHSF9BMjBfZnVuY19vZmZzCT0gMHgwOwogIERPU19MT0wtPlBTUF9sYXN0X2V4ZWMJCT0gMHgwOwogIERPU19MT0wtPkJVRkZFUlNfdmFsCQk9IDk5OyAvKiBtYXhpbXVtOiA5OSAqLwogIERPU19MT0wtPkJVRkZFUlNfbnJfbG9va2FoZWFkCT0gODsgLyogbWF4aW11bTogOCAqLwogIERPU19MT0wtPmJvb3RfZHJpdmUJCQk9IDM7IC8qIEM6ICovCiAgRE9TX0xPTC0+ZmxhZ19EV09SRF9tb3ZlcwkJPSAweDAxOyAvKiBpMzg2KyAqLwogIERPU19MT0wtPnNpemVfZXh0ZW5kZWRfbWVtCQk9IDB4ZjAwMDsgLyogdmVyeSBoaWdoIHZhbHVlICovCn0KCnZvaWQgRE9TREVWX0luc3RhbGxET1NEZXZpY2VzKHZvaWQpCnsKICBET1NfREFUQVNFRyAqZGF0YXNlZzsKICBXT1JEIHNlZzsKICBXT1JEIHNlbGVjdG9yOwogIHVuc2lnbmVkIGludCBuOwoKICAvKiBhbGxvY2F0ZSBET1MgZGF0YSBzZWdtZW50IG9yIHNvbWV0aGluZyAqLwogIGRhdGFzZWcgPSBET1NWTV9BbGxvY0RhdGFVTUIoIHNpemVvZihET1NfREFUQVNFRyksICZzZWcsICZzZWxlY3RvciApOwoKICBET1NfTE9MU2VnID0gTUFLRVNFR1BUUiggc2VnLCAwICk7CiAgRE9TTUVNX0xPTCgpLT53aW5lX3JtX2xvbCA9IAogICAgICBNQUtFU0VHUFRSKCBzZWcsIEZJRUxEX09GRlNFVChET1NfTElTVE9GTElTVFMsIHB0cl9maXJzdF9EUEIpICk7CiAgRE9TTUVNX0xPTCgpLT53aW5lX3BtX2xvbCA9IAogICAgICBNQUtFU0VHUFRSKCBzZWxlY3RvciwgRklFTERfT0ZGU0VUKERPU19MSVNUT0ZMSVNUUywgcHRyX2ZpcnN0X0RQQikgKTsKCiAgLyogaW5pdGlhbGl6ZSB0aGUgbWFnbmlmaWNlbnQgTGlzdCBPZiBMaXN0cyAqLwogIEluaXRMaXN0T2ZMaXN0cygmZGF0YXNlZy0+bG9sKTsKCiAgLyogU2V0IHVwIGZpcnN0IGRldmljZSAoTlVMKSAqLwogIGRhdGFzZWctPmxvbC5OVUxfZGV2Lm5leHRfZGV2ICA9IE1BS0VTRUdQVFIoc2VnLCBET1NfREFUQVNFR19PRkYoZGV2WzBdKSk7CiAgZGF0YXNlZy0+bG9sLk5VTF9kZXYuYXR0ciAgICAgID0gZGV2c1swXS5hdHRyOwogIGRhdGFzZWctPmxvbC5OVUxfZGV2LnN0cmF0ZWd5ICA9IERPU19EQVRBU0VHX09GRih0aHVua1swXS5sam1wMSk7CiAgZGF0YXNlZy0+bG9sLk5VTF9kZXYuaW50ZXJydXB0ID0gRE9TX0RBVEFTRUdfT0ZGKHRodW5rWzBdLmxqbXAyKTsKICBtZW1jcHkoZGF0YXNlZy0+bG9sLk5VTF9kZXYubmFtZSwgZGV2c1swXS5uYW1lLCA4KTsKCiAgLyogU2V0IHVwIHRoZSByZW1haW5pbmcgZGV2aWNlcyAqLwogIGZvciAobiA9IDE7IG4gPCBOUl9ERVZTOyBuKyspCiAgewogICAgZGF0YXNlZy0+ZGV2W24tMV0ubmV4dF9kZXYgID0gKG4rMSkgPT0gTlJfREVWUyA/IE5PTkVYVCA6CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBNQUtFU0VHUFRSKHNlZywgRE9TX0RBVEFTRUdfT0ZGKGRldltuXSkpOwogICAgZGF0YXNlZy0+ZGV2W24tMV0uYXR0ciAgICAgID0gZGV2c1tuXS5hdHRyOwogICAgZGF0YXNlZy0+ZGV2W24tMV0uc3RyYXRlZ3kgID0gRE9TX0RBVEFTRUdfT0ZGKHRodW5rW25dLmxqbXAxKTsKICAgIGRhdGFzZWctPmRldltuLTFdLmludGVycnVwdCA9IERPU19EQVRBU0VHX09GRih0aHVua1tuXS5sam1wMik7CiAgICBtZW1jcHkoZGF0YXNlZy0+ZGV2W24tMV0ubmFtZSwgZGV2c1tuXS5uYW1lLCA4KTsKICB9CgogIC8qIFNldCB1cCB0aHVua3MgKi8KICBmb3IgKG4gPSAwOyBuIDwgTlJfREVWUzsgbisrKQogIHsKICAgIGRhdGFzZWctPnRodW5rW25dLmxqbXAxICAgICA9IExKTVA7CiAgICBkYXRhc2VnLT50aHVua1tuXS5zdHJhdGVneSAgPSAoUk1DQlBST0MpRFBNSV9BbGxvY0ludGVybmFsUk1DQihkZXZzW25dLnN0cmF0ZWd5KTsKICAgIGRhdGFzZWctPnRodW5rW25dLmxqbXAyICAgICA9IExKTVA7CiAgICBkYXRhc2VnLT50aHVua1tuXS5pbnRlcnJ1cHQgPSAoUk1DQlBST0MpRFBNSV9BbGxvY0ludGVybmFsUk1DQihkZXZzW25dLmludGVycnVwdCk7CiAgfQoKICAvKiBDT04gaXMgZGV2aWNlIDEgKi8KICBkYXRhc2VnLT5sb2wucHRyX0NPTl9kZXZfaGRyID0gTUFLRVNFR1BUUihzZWcsIERPU19EQVRBU0VHX09GRihkZXZbMF0pKTsKfQoKRFdPUkQgRE9TREVWX0NvbnNvbGUodm9pZCkKewogIHJldHVybiBET1NNRU1fTE9MKCktPnB0cl9DT05fZGV2X2hkcjsKfQoKRFdPUkQgRE9TREVWX0ZpbmRDaGFyRGV2aWNlKGNoYXIqbmFtZSkKewogIFNFR1BUUiBjdXJfcHRyID0gTUFLRVNFR1BUUihISVdPUkQoRE9TX0xPTFNlZyksIEZJRUxEX09GRlNFVChET1NfTElTVE9GTElTVFMsTlVMX2RldikpOwogIERPU19ERVZJQ0VfSEVBREVSICpjdXIgPSBQVFJfUkVBTF9UT19MSU4oU0VMRUNUT1JPRihjdXJfcHRyKSxPRkZTRVRPRihjdXJfcHRyKSk7CiAgY2hhciBkbmFtZVs4XTsKICBpbnQgY250OwoKICAvKiBnZXQgZmlyc3QgOCBjaGFyYWN0ZXJzICovCiAgc3RybmNweShkbmFtZSxuYW1lLDgpOwogIC8qIGlmIGxlc3MgdGhhbiA4IGNoYXJhY3RlcnMsIHBhZCB3aXRoIHNwYWNlcyAqLwogIGZvciAoY250PTA7IGNudDw4OyBjbnQrKykKICAgIGlmICghZG5hbWVbY250XSkgZG5hbWVbY250XT0nICc7CgogIC8qIHNlYXJjaCBmb3IgY2hhciBkZXZpY2VzIHdpdGggdGhlIHJpZ2h0IG5hbWUgKi8KICB3aGlsZSAoY3VyICYmCgkgKCghKGN1ci0+YXR0ciAmIEFUVFJfQ0hBUikpIHx8CgkgIG1lbWNtcChjdXItPm5hbWUsZG5hbWUsOCkpKSB7CiAgICBjdXJfcHRyID0gY3VyLT5uZXh0X2RldjsKICAgIGlmIChjdXJfcHRyID09IE5PTkVYVCkgY3VyPU5VTEw7CiAgICBlbHNlIGN1ciA9IFBUUl9SRUFMX1RPX0xJTihTRUxFQ1RPUk9GKGN1cl9wdHIpLE9GRlNFVE9GKGN1cl9wdHIpKTsKICB9CiAgcmV0dXJuIGN1cl9wdHI7Cn0KCnN0YXRpYyB2b2lkIERPU0RFVl9Eb1JlcSh2b2lkKnJlcSwgRFdPUkQgZGV2KQp7CiAgUkVRVUVTVF9IRUFERVIgKmhkciA9IChSRVFVRVNUX0hFQURFUiAqKXJlcTsKICBET1NfREVWSUNFX0hFQURFUiAqZGhkcjsKICBDT05URVhUODYgY3R4OwogIGNoYXIgKnBoZHI7CgogIGRoZHIgPSBQVFJfUkVBTF9UT19MSU4oU0VMRUNUT1JPRihkZXYpLE9GRlNFVE9GKGRldikpOwogIHBoZHIgPSAoKGNoYXIqKURPU01FTV9MT0woKSkgKyBET1NfREFUQVNFR19PRkYocmVxKTsKCiAgLyogY29weSByZXF1ZXN0IHRvIHJlcXVlc3Qgc2NyYXRjaCBhcmVhICovCiAgbWVtY3B5KHBoZHIsIHJlcSwgaGRyLT5zaXplKTsKCiAgLyogcHJlcGFyZSB0byBjYWxsIGRldmljZSBkcml2ZXIgKi8KICBtZW1zZXQoJmN0eCwgMCwgc2l6ZW9mKGN0eCkpOwogIGN0eC5FRmxhZ3MgfD0gVjg2X0ZMQUc7CgogIC8qIEVTOkJYIHBvaW50cyB0byByZXF1ZXN0IGZvciBzdHJhdGVneSByb3V0aW5lICovCiAgY3R4LlNlZ0VzID0gSElXT1JEKERPU19MT0xTZWcpOwogIGN0eC5FYnggICA9IERPU19EQVRBU0VHX09GRihyZXEpOwoKICAvKiBjYWxsIHN0cmF0ZWd5IHJvdXRpbmUgKi8KICBjdHguU2VnQ3MgPSBTRUxFQ1RPUk9GKGRldik7CiAgY3R4LkVpcCAgID0gZGhkci0+c3RyYXRlZ3k7CiAgRFBNSV9DYWxsUk1Qcm9jKCZjdHgsIDAsIDAsIDApOwoKICAvKiBjYWxsIGludGVycnVwdCByb3V0aW5lICovCiAgY3R4LlNlZ0NzID0gU0VMRUNUT1JPRihkZXYpOwogIGN0eC5FaXAgICA9IGRoZHItPmludGVycnVwdDsKICBEUE1JX0NhbGxSTVByb2MoJmN0eCwgMCwgMCwgMCk7CgogIC8qIGNvbXBsZXRlZCwgY29weSByZXF1ZXN0IGJhY2sgKi8KICBtZW1jcHkocmVxLCBwaGRyLCBoZHItPnNpemUpOwoKICBpZiAoaGRyLT5zdGF0dXMgJiBTVEFUX0VSUk9SKSB7CiAgICBzd2l0Y2ggKGhkci0+c3RhdHVzICYgU1RBVF9NQVNLKSB7CiAgICBjYXNlIDB4MEY6IC8qIGludmFsaWQgZGlzayBjaGFuZ2UgKi8KICAgICAgLyogdGhpcyBlcnJvciBzZWVtcyB0byBmaXQgdGhlIGJpbGwgKi8KICAgICAgU2V0TGFzdEVycm9yKEVSUk9SX05PVF9TQU1FX0RFVklDRSk7CiAgICAgIGJyZWFrOwogICAgZGVmYXVsdDoKICAgICAgU2V0TGFzdEVycm9yKChoZHItPnN0YXR1cyAmIFNUQVRfTUFTSykgKyAweDEzKTsKICAgICAgYnJlYWs7CiAgICB9CiAgfQp9CgpzdGF0aWMgaW50IERPU0RFVl9JTyh1bnNpZ25lZCBjbWQsIERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuKQp7CiAgUkVRX0lPIHJlcTsKCiAgcmVxLmhkci5zaXplPXNpemVvZihyZXEpOwogIHJlcS5oZHIudW5pdD0wOyAvKiBub3QgZGVhbGluZyB3aXRoIGJsb2NrIGRldmljZXMgeWV0ICovCiAgcmVxLmhkci5jb21tYW5kPWNtZDsKICByZXEuaGRyLnN0YXR1cz1TVEFUX0JVU1k7CiAgcmVxLm1lZGlhPTA7IC8qIG5vdCBkZWFsaW5nIHdpdGggYmxvY2sgZGV2aWNlcyB5ZXQgKi8KICByZXEuYnVmZmVyPWJ1ZjsKICByZXEuY291bnQ9YnVmbGVuOwogIHJlcS5zZWN0b3I9MDsgLyogYmxvY2sgZGV2aWNlcyAqLwogIHJlcS52b2x1bWU9MDsgLyogYmxvY2sgZGV2aWNlcyAqLwoKICBET1NERVZfRG9SZXEoJnJlcSwgZGV2KTsKCiAgcmV0dXJuIHJlcS5jb3VudDsKfQoKaW50IERPU0RFVl9QZWVrKERXT1JEIGRldiwgQllURSpkYXRhKQp7CiAgUkVRX1NBRkVJTlBVVCByZXE7CgogIHJlcS5oZHIuc2l6ZT1zaXplb2YocmVxKTsKICByZXEuaGRyLnVuaXQ9MDsgLyogbm90IGRlYWxpbmcgd2l0aCBibG9jayBkZXZpY2VzIHlldCAqLwogIHJlcS5oZHIuY29tbWFuZD1DTURfU0FGRUlOUFVUOwogIHJlcS5oZHIuc3RhdHVzPVNUQVRfQlVTWTsKICByZXEuZGF0YT0wOwoKICBET1NERVZfRG9SZXEoJnJlcSwgZGV2KTsKCiAgaWYgKHJlcS5oZHIuc3RhdHVzICYgU1RBVF9CVVNZKSByZXR1cm4gMDsKCiAgKmRhdGEgPSByZXEuZGF0YTsKICByZXR1cm4gMTsKfQoKaW50IERPU0RFVl9SZWFkKERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuKQp7CiAgcmV0dXJuIERPU0RFVl9JTyhDTURfSU5QVVQsIGRldiwgYnVmLCBidWZsZW4pOwp9CgppbnQgRE9TREVWX1dyaXRlKERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuLCBpbnQgdmVyaWZ5KQp7CiAgcmV0dXJuIERPU0RFVl9JTyh2ZXJpZnk/Q01EX1NBRkVPVVRQVVQ6Q01EX09VVFBVVCwgZGV2LCBidWYsIGJ1Zmxlbik7Cn0KCmludCBET1NERVZfSW9jdGxSZWFkKERXT1JEIGRldiwgRFdPUkQgYnVmLCBpbnQgYnVmbGVuKQp7CiAgcmV0dXJuIERPU0RFVl9JTyhDTURfSU5JT0NUTCwgZGV2LCBidWYsIGJ1Zmxlbik7Cn0KCmludCBET1NERVZfSW9jdGxXcml0ZShEV09SRCBkZXYsIERXT1JEIGJ1ZiwgaW50IGJ1ZmxlbikKewogIHJldHVybiBET1NERVZfSU8oQ01EX09VVElPQ1RMLCBkZXYsIGJ1ZiwgYnVmbGVuKTsKfQoKdm9pZCBET1NERVZfU2V0U2hhcmluZ1JldHJ5KFdPUkQgZGVsYXksIFdPUkQgY291bnQpCnsKICAgIERPU01FTV9MT0woKS0+c2hhcmluZ19yZXRyeV9kZWxheSA9IGRlbGF5OwogICAgaWYgKGNvdW50KSBET1NNRU1fTE9MKCktPnNoYXJpbmdfcmV0cnlfY291bnQgPSBjb3VudDsKfQoKU0VHUFRSIERPU0RFVl9HZXRMT0woQk9PTCB2ODYpCnsKICAgIGlmICh2ODYpIHJldHVybiBET1NNRU1fTE9MKCktPndpbmVfcm1fbG9sOwogICAgZWxzZSByZXR1cm4gRE9TTUVNX0xPTCgpLT53aW5lX3BtX2xvbDsKfQo=