LyoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICogICAgIHBhc3N0aHJvdWdoLmMgLS0gRW11MTBrMSBkaWdpdGFsIHBhc3N0aHJvdWdoCiAqICAgICBDb3B5cmlnaHQgKEMpIDIwMDEgIEp1aGEgWXJq9mzkIDxqeXJqb2xhQGNjLmh1dC5maT4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioKICoKICogICAgIERhdGUgICAgICAgICAgICAgICAgIEF1dGhvciAgICAgICAgICBTdW1tYXJ5IG9mIGNoYW5nZXMKICogICAgIC0tLS0gICAgICAgICAgICAgICAgIC0tLS0tLSAgICAgICAgICAtLS0tLS0tLS0tLS0tLS0tLS0KICogICAgIE1heSAxNSwgMjAwMQkgICAgSnVoYSBZcmr2bOQJICAgIGJhc2UgY29kZSByZWxlYXNlCiAqCiAqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqCiAqCiAqICAgICBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqICAgICBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcwogKiAgICAgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogICAgIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiAgICAgVGhpcyBwcm9ncmFtIGlzIGRpc3RyaWJ1dGVkIGluIHRoZSBob3BlIHRoYXQgaXQgd2lsbCBiZSB1c2VmdWwsCiAqICAgICBidXQgV0lUSE9VVCBBTlkgV0FSUkFOVFk7IHdpdGhvdXQgZXZlbiB0aGUgaW1wbGllZCB3YXJyYW50eSBvZgogKiAgICAgTUVSQ0hBTlRBQklMSVRZIG9yIEZJVE5FU1MgRk9SIEEgUEFSVElDVUxBUiBQVVJQT1NFLiAgU2VlIHRoZQogKiAgICAgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgZm9yIG1vcmUgZGV0YWlscy4KICoKICogICAgIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYwogKiAgICAgTGljZW5zZSBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbTsgaWYgbm90LCB3cml0ZSB0byB0aGUgRnJlZQogKiAgICAgU29mdHdhcmUgRm91bmRhdGlvbiwgSW5jLiwgNjc1IE1hc3MgQXZlLCBDYW1icmlkZ2UsIE1BIDAyMTM5LAogKiAgICAgVVNBLgogKgogKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKi8KICAgICAgICAgICAgICAgICAgICAgICAKI2luY2x1ZGUgPGxpbnV4L21vZHVsZS5oPgojaW5jbHVkZSA8bGludXgvcG9sbC5oPgojaW5jbHVkZSA8bGludXgvc2xhYi5oPgojaW5jbHVkZSA8bGludXgvYml0b3BzLmg+CiNpbmNsdWRlIDxhc20vaW8uaD4KI2luY2x1ZGUgPGxpbnV4L3NjaGVkLmg+CiNpbmNsdWRlIDxsaW51eC9zbXBfbG9jay5oPgoKI2luY2x1ZGUgImh3YWNjZXNzLmgiCiNpbmNsdWRlICJjYXJkd28uaCIKI2luY2x1ZGUgImNhcmR3aS5oIgojaW5jbHVkZSAicmVjbWdyLmgiCiNpbmNsdWRlICJpcnFtZ3IuaCIKI2luY2x1ZGUgImF1ZGlvLmgiCiNpbmNsdWRlICI4MDEwLmgiCgpzdGF0aWMgdm9pZCBwdF9wdXRzYW1wbGVzKHN0cnVjdCBwdF9kYXRhICpwdCwgdTE2ICpwdHIsIHUxNiBsZWZ0LCB1MTYgcmlnaHQpCnsKCXVuc2lnbmVkIGludCBpZHg7CgoJcHRyW3B0LT5jb3B5cHRyXSA9IGxlZnQ7CglpZHggPSBwdC0+Y29weXB0ciArIFBUX1NBTVBMRVMvMjsKCWlkeCAlPSBQVF9TQU1QTEVTOwoJcHRyW2lkeF0gPSByaWdodDsKfQoKc3RhdGljIGlubGluZSBpbnQgcHRfY2FuX3dyaXRlKHN0cnVjdCBwdF9kYXRhICpwdCkKewoJcmV0dXJuIHB0LT5ibG9ja3NfY29waWVkIDwgcHQtPmJsb2Nrc19wbGF5ZWQgKyA4Owp9CgpzdGF0aWMgaW50IHB0X3dhaXRfZm9yX3dyaXRlKHN0cnVjdCBlbXUxMGsxX3dhdmVkZXZpY2UgKndhdmVkZXYsIGludCBub25ibG9jaykKewoJc3RydWN0IGVtdTEwazFfY2FyZCAqY2FyZCA9IHdhdmVkZXYtPmNhcmQ7CglzdHJ1Y3QgcHRfZGF0YSAqcHQgPSAmY2FyZC0+cHQ7CgoJaWYgKG5vbmJsb2NrICYmICFwdF9jYW5fd3JpdGUocHQpKQoJCXJldHVybiAtRUFHQUlOOwoJd2hpbGUgKCFwdF9jYW5fd3JpdGUocHQpICYmIHB0LT5zdGF0ZSAhPSBQVF9TVEFURV9JTkFDVElWRSkgewoJCWludGVycnVwdGlibGVfc2xlZXBfb24oJnB0LT53YWl0KTsKCQlpZiAoc2lnbmFsX3BlbmRpbmcoY3VycmVudCkpCgkJCXJldHVybiAtRVJFU1RBUlRTWVM7Cgl9CglpZiAocHQtPnN0YXRlID09IFBUX1NUQVRFX0lOQUNUSVZFKQoJCXJldHVybiAtRUFHQUlOOwoJCglyZXR1cm4gMDsKfQoKc3RhdGljIGludCBwdF9wdXRibG9jayhzdHJ1Y3QgZW11MTBrMV93YXZlZGV2aWNlICp3YXZlX2RldiwgdTE2ICpibG9jaywgaW50IG5vbmJsb2NrKQp7CglzdHJ1Y3Qgd29pbnN0ICp3b2luc3QgPSB3YXZlX2Rldi0+d29pbnN0OwoJc3RydWN0IGVtdTEwazFfY2FyZCAqY2FyZCA9IHdhdmVfZGV2LT5jYXJkOwoJc3RydWN0IHB0X2RhdGEgKnB0ID0gJmNhcmQtPnB0OwoJdTE2ICpwdHIgPSAodTE2ICopIGNhcmQtPnRhbmttZW0uYWRkcjsKCWludCBpID0gMCwgcjsKCXVuc2lnbmVkIGxvbmcgZmxhZ3M7CgoJciA9IHB0X3dhaXRfZm9yX3dyaXRlKHdhdmVfZGV2LCBub25ibG9jayk7CglpZiAociA8IDApCgkJcmV0dXJuIHI7CglzcGluX2xvY2tfaXJxc2F2ZSgmY2FyZC0+cHQubG9jaywgZmxhZ3MpOwoJd2hpbGUgKGkgPCBQVF9CTE9DS1NBTVBMRVMpIHsKCQlwdF9wdXRzYW1wbGVzKHB0LCBwdHIsIGJsb2NrWzIqaV0sIGJsb2NrWzIqaSsxXSk7CgkJaWYgKHB0LT5jb3B5cHRyID09IDApCgkJCXB0LT5jb3B5cHRyID0gUFRfU0FNUExFUzsKCQlwdC0+Y29weXB0ci0tOwoJCWkrKzsKCX0KCXdvaW5zdC0+dG90YWxfY29waWVkICs9IFBUX0JMT0NLU0laRTsKCXB0LT5ibG9ja3NfY29waWVkKys7CglpZiAocHQtPmJsb2Nrc19jb3BpZWQgPj0gNCAmJiBwdC0+c3RhdGUgIT0gUFRfU1RBVEVfUExBWUlORykgewoJCURQRigyLCAiYWN0aXZhdGluZyBkaWdpdGFsIHBhc3MtdGhyb3VnaCBwbGF5YmFja1xuIik7CgkJc2JsaXZlX3dyaXRlcHRyKGNhcmQsIEdQUl9CQVNFICsgcHQtPmVuYWJsZV9ncHIsIDAsIDEpOwoJCXB0LT5zdGF0ZSA9IFBUX1NUQVRFX1BMQVlJTkc7Cgl9CglzcGluX3VubG9ja19pcnFyZXN0b3JlKCZjYXJkLT5wdC5sb2NrLCBmbGFncyk7CglyZXR1cm4gMDsKfQoKaW50IGVtdTEwazFfcHRfc2V0dXAoc3RydWN0IGVtdTEwazFfd2F2ZWRldmljZSAqd2F2ZV9kZXYpCnsKCXUzMiBiaXRzOwoJc3RydWN0IGVtdTEwazFfY2FyZCAqY2FyZCA9IHdhdmVfZGV2LT5jYXJkOwoJc3RydWN0IHB0X2RhdGEgKnB0ID0gJmNhcmQtPnB0OwoJaW50IGk7CgoJZm9yIChpID0gMDsgaSA8IDM7IGkrKykgewoJCXB0LT5vbGRfc3Bjc1tpXSA9IHNibGl2ZV9yZWFkcHRyKGNhcmQsIFNQQ1MwICsgaSwgMCk7CgkJaWYgKHB0LT5zcGNzX3RvX3VzZSAmICgxIDw8IGkpKSB7CgkJCURQRCgyLCAidXNpbmcgUy9QRElGIHBvcnQgJWRcbiIsIGkpOwoJCQliaXRzID0gU1BDU19DTEtBQ0NZXzEwMDBQUE0gfCBTUENTX1NBTVBMRVJBVEVfNDggfAoJCQkJU1BDU19DSEFOTkVMTlVNX0xFRlQgfCBTUENTX1NPVVJDRU5VTV9VTlNQRUMgfCBTUENTX0dFTkVSQVRJT05TVEFUVVMgfAoJCQkJMHgwMDAwMTIwMCB8IFNQQ1NfRU1QSEFTSVNfTk9ORSB8IFNQQ1NfQ09QWVJJR0hUOwoJCQlpZiAocHQtPmFjM2RhdGEpCgkJCQliaXRzIHw9IFNQQ1NfTk9UQVVESU9EQVRBOwoJCQlzYmxpdmVfd3JpdGVwdHIoY2FyZCwgU1BDUzAgKyBpLCAwLCBiaXRzKTsKCQl9Cgl9CglyZXR1cm4gMDsKfQoKc3NpemVfdCBlbXUxMGsxX3B0X3dyaXRlKHN0cnVjdCBmaWxlICpmaWxlLCBjb25zdCBjaGFyIF9fdXNlciAqYnVmZmVyLCBzaXplX3QgY291bnQpCnsKCXN0cnVjdCBlbXUxMGsxX3dhdmVkZXZpY2UgKndhdmVfZGV2ID0gKHN0cnVjdCBlbXUxMGsxX3dhdmVkZXZpY2UgKikgZmlsZS0+cHJpdmF0ZV9kYXRhOwoJc3RydWN0IGVtdTEwazFfY2FyZCAqY2FyZCA9IHdhdmVfZGV2LT5jYXJkOwoJc3RydWN0IHB0X2RhdGEgKnB0ID0gJmNhcmQtPnB0OwoJaW50IG5vbmJsb2NrLCBpLCByLCBibG9ja3MsIGJsb2Nrc19jb3BpZWQsIGJ5dGVzX2NvcGllZCA9IDA7CgoJRFBEKDMsICJlbXUxMGsxX3B0X3dyaXRlKCk6ICVkIGJ5dGVzXG4iLCBjb3VudCk7CgkKCW5vbmJsb2NrID0gZmlsZS0+Zl9mbGFncyAmIE9fTk9OQkxPQ0s7CgkKCWlmIChjYXJkLT50YW5rbWVtLnNpemUgPCBQVF9TQU1QTEVTKjIpCgkJcmV0dXJuIC1FRkFVTFQ7CglpZiAocHQtPnN0YXRlID09IFBUX1NUQVRFX0lOQUNUSVZFKSB7CgkJRFBGKDIsICJidWZwdHIgaW5pdFxuIik7CgkJcHQtPnBsYXlwdHIgPSBQVF9TQU1QTEVTLTE7CgkJcHQtPmNvcHlwdHIgPSBQVF9JTklUUFRSOwoJCXB0LT5ibG9ja3NfcGxheWVkID0gcHQtPmJsb2Nrc19jb3BpZWQgPSAwOwoJCW1lbXNldChjYXJkLT50YW5rbWVtLmFkZHIsIDAsIGNhcmQtPnRhbmttZW0uc2l6ZSk7CgkJcHQtPnN0YXRlID0gUFRfU1RBVEVfQUNUSVZBVEVEOwoJCXB0LT5idWYgPSBrbWFsbG9jKFBUX0JMT0NLU0laRSwgR0ZQX0tFUk5FTCk7CgkJcHQtPnByZXBlbmRfc2l6ZSA9IDA7CgkJaWYgKHB0LT5idWYgPT0gTlVMTCkKCQkJcmV0dXJuIC1FTk9NRU07CgkJZW11MTBrMV9wdF9zZXR1cCh3YXZlX2Rldik7Cgl9CglpZiAocHQtPnByZXBlbmRfc2l6ZSkgewoJCWludCBuZWVkZWQgPSBQVF9CTE9DS1NJWkUgLSBwdC0+cHJlcGVuZF9zaXplOwoKCQlEUEQoMywgInByZXBlbmQgc2l6ZSAlZCwgcHJlcGVuZGluZyAlZCBieXRlc1xuIiwgcHQtPnByZXBlbmRfc2l6ZSwgbmVlZGVkKTsKCQlpZiAoY291bnQgPCBuZWVkZWQpIHsKCQkJaWYgKGNvcHlfZnJvbV91c2VyKHB0LT5idWYgKyBwdC0+cHJlcGVuZF9zaXplLAoJCQkJCSAgIGJ1ZmZlciwgY291bnQpKQoJCQkJcmV0dXJuIC1FRkFVTFQ7CgkJCXB0LT5wcmVwZW5kX3NpemUgKz0gY291bnQ7CgkJCURQRCgzLCAicHJlcGVuZCBzaXplIG5vdyAlZFxuIiwgcHQtPnByZXBlbmRfc2l6ZSk7CgkJCXJldHVybiBjb3VudDsKCQl9CgkJaWYgKGNvcHlfZnJvbV91c2VyKHB0LT5idWYgKyBwdC0+cHJlcGVuZF9zaXplLCBidWZmZXIsIG5lZWRlZCkpCgkJCXJldHVybiAtRUZBVUxUOwoJCXIgPSBwdF9wdXRibG9jayh3YXZlX2RldiwgKHUxNiAqKSBwdC0+YnVmLCBub25ibG9jayk7CgkJaWYgKHIpCgkJCXJldHVybiByOwoJCWJ5dGVzX2NvcGllZCArPSBuZWVkZWQ7CgkJcHQtPnByZXBlbmRfc2l6ZSA9IDA7Cgl9CglibG9ja3MgPSAoY291bnQtYnl0ZXNfY29waWVkKS9QVF9CTE9DS1NJWkU7CglibG9ja3NfY29waWVkID0gMDsKCXdoaWxlIChibG9ja3MgPiAwKSB7CgkJdTE2IF9fdXNlciAqYnVmcHRyID0gKHUxNiBfX3VzZXIgKikgYnVmZmVyICsgKGJ5dGVzX2NvcGllZC8yKTsKCQlpZiAoY29weV9mcm9tX3VzZXIocHQtPmJ1ZiwgYnVmcHRyLCBQVF9CTE9DS1NJWkUpKQoJCQlyZXR1cm4gLUVGQVVMVDsKCQlyID0gcHRfcHV0YmxvY2sod2F2ZV9kZXYsICh1MTYgKilwdC0+YnVmLCBub25ibG9jayk7CgkJaWYgKHIpIHsKCQkJaWYgKGJ5dGVzX2NvcGllZCkKCQkJCXJldHVybiBieXRlc19jb3BpZWQ7CgkJCWVsc2UKCQkJCXJldHVybiByOwoJCX0KCQlieXRlc19jb3BpZWQgKz0gUFRfQkxPQ0tTSVpFOwoJCWJsb2Nrcy0tOwoJCWJsb2Nrc19jb3BpZWQrKzsKCX0KCWkgPSBjb3VudCAtIGJ5dGVzX2NvcGllZDsKCWlmIChpKSB7CgkJcHQtPnByZXBlbmRfc2l6ZSA9IGk7CgkJaWYgKGNvcHlfZnJvbV91c2VyKHB0LT5idWYsIGJ1ZmZlciArIGJ5dGVzX2NvcGllZCwgaSkpCgkJCXJldHVybiAtRUZBVUxUOwoJCWJ5dGVzX2NvcGllZCArPSBpOwoJCURQRCgzLCAiZmlsbGluZyBwcmVwZW5kIGJ1ZmZlciB3aXRoICVkIGJ5dGVzIiwgaSk7Cgl9CglyZXR1cm4gYnl0ZXNfY29waWVkOwp9Cgp2b2lkIGVtdTEwazFfcHRfc3RvcChzdHJ1Y3QgZW11MTBrMV9jYXJkICpjYXJkKQp7CglzdHJ1Y3QgcHRfZGF0YSAqcHQgPSAmY2FyZC0+cHQ7CglpbnQgaTsKCglpZiAocHQtPnN0YXRlICE9IFBUX1NUQVRFX0lOQUNUSVZFKSB7CgkJRFBGKDIsICJkaWdpdGFsIHBhc3MtdGhyb3VnaCBzdG9wcGVkXG4iKTsKCQlzYmxpdmVfd3JpdGVwdHIoY2FyZCwgKGNhcmQtPmlzX2F1ZGlneSA/IEFfR1BSX0JBU0UgOiBHUFJfQkFTRSkgKyBwdC0+ZW5hYmxlX2dwciwgMCwgMCk7CgkJZm9yIChpID0gMDsgaSA8IDM7IGkrKykgewogICAgICAgICAgICAgICAgICAgICAgICBpZiAocHQtPnNwY3NfdG9fdXNlICYgKDEgPDwgaSkpCgkJCQlzYmxpdmVfd3JpdGVwdHIoY2FyZCwgU1BDUzAgKyBpLCAwLCBwdC0+b2xkX3NwY3NbaV0pOwoJCX0KCQlwdC0+c3RhdGUgPSBQVF9TVEFURV9JTkFDVElWRTsKCQlrZnJlZShwdC0+YnVmKTsKCX0KfQoKdm9pZCBlbXUxMGsxX3B0X3dhdmVvdXRfdXBkYXRlKHN0cnVjdCBlbXUxMGsxX3dhdmVkZXZpY2UgKndhdmVfZGV2KQp7CglzdHJ1Y3Qgd29pbnN0ICp3b2luc3QgPSB3YXZlX2Rldi0+d29pbnN0OwoJc3RydWN0IHB0X2RhdGEgKnB0ID0gJndhdmVfZGV2LT5jYXJkLT5wdDsKCXUzMiBwb3M7CgoJaWYgKHB0LT5zdGF0ZSA9PSBQVF9TVEFURV9QTEFZSU5HICYmIHB0LT5wb3NfZ3ByID49IDApIHsKCQlwb3MgPSBzYmxpdmVfcmVhZHB0cih3YXZlX2Rldi0+Y2FyZCwgR1BSX0JBU0UgKyBwdC0+cG9zX2dwciwgMCk7CgkJaWYgKHBvcyA+IFBUX0JMT0NLU0FNUExFUykKCQkJcG9zID0gUFRfQkxPQ0tTQU1QTEVTOwoJCXBvcyA9IDQgKiAoUFRfQkxPQ0tTQU1QTEVTIC0gcG9zKTsKCX0gZWxzZQoJCXBvcyA9IDA7Cgl3b2luc3QtPnRvdGFsX3BsYXllZCA9IHB0LT5ibG9ja3NfcGxheWVkICogd29pbnN0LT5idWZmZXIuZnJhZ21lbnRfc2l6ZSArIHBvczsKCXdvaW5zdC0+YnVmZmVyLmh3X3BvcyA9IHBvczsKfQo=