LyoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKgogKgogKiBGaWxlbmFtZTogICAgICBpcmxhcF9mcmFtZS5jCiAqIFZlcnNpb246ICAgICAgIDEuMAogKiBEZXNjcmlwdGlvbjogICBCdWlsZCBhbmQgdHJhbnNtaXQgSXJMQVAgZnJhbWVzCiAqIFN0YXR1czogICAgICAgIFN0YWJsZQogKiBBdXRob3I6ICAgICAgICBEYWcgQnJhdHRsaSA8ZGFnYkBjcy51aXQubm8+CiAqIENyZWF0ZWQgYXQ6ICAgIFR1ZSBBdWcgMTkgMTA6Mjc6MjYgMTk5NwogKiBNb2RpZmllZCBhdDogICBXZWQgSmFuICA1IDA4OjU5OjA0IDIwMDAKICogTW9kaWZpZWQgYnk6ICAgRGFnIEJyYXR0bGkgPGRhZ2JAY3MudWl0Lm5vPgogKgogKiAgICAgQ29weXJpZ2h0IChjKSAxOTk4LTIwMDAgRGFnIEJyYXR0bGkgPGRhZ2JAY3MudWl0Lm5vPiwKICogICAgIEFsbCBSaWdodHMgUmVzZXJ2ZWQuCiAqICAgICBDb3B5cmlnaHQgKGMpIDIwMDAtMjAwMyBKZWFuIFRvdXJyaWxoZXMgPGp0QGhwbC5ocC5jb20+CiAqCiAqICAgICBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTsgeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yCiAqICAgICBtb2RpZnkgaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcwogKiAgICAgcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb247IGVpdGhlciB2ZXJzaW9uIDIgb2YKICogICAgIHRoZSBMaWNlbnNlLCBvciAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLgogKgogKiAgICAgTmVpdGhlciBEYWcgQnJhdHRsaSBub3IgVW5pdmVyc2l0eSBvZiBUcm9tc/ggYWRtaXQgbGlhYmlsaXR5IG5vcgogKiAgICAgcHJvdmlkZSB3YXJyYW50eSBmb3IgYW55IG9mIHRoaXMgc29mdHdhcmUuIFRoaXMgbWF0ZXJpYWwgaXMKICogICAgIHByb3ZpZGVkICJBUy1JUyIgYW5kIGF0IG5vIGNoYXJnZS4KICoKICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqLwoKI2luY2x1ZGUgPGxpbnV4L3NrYnVmZi5oPgojaW5jbHVkZSA8bGludXgvaWYuaD4KI2luY2x1ZGUgPGxpbnV4L2lmX2V0aGVyLmg+CiNpbmNsdWRlIDxsaW51eC9uZXRkZXZpY2UuaD4KI2luY2x1ZGUgPGxpbnV4L2lyZGEuaD4KCiNpbmNsdWRlIDxuZXQvcGt0X3NjaGVkLmg+CiNpbmNsdWRlIDxuZXQvc29jay5oPgoKI2luY2x1ZGUgPGFzbS9ieXRlb3JkZXIuaD4KCiNpbmNsdWRlIDxuZXQvaXJkYS9pcmRhLmg+CiNpbmNsdWRlIDxuZXQvaXJkYS9pcmRhX2RldmljZS5oPgojaW5jbHVkZSA8bmV0L2lyZGEvaXJsYXAuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL3dyYXBwZXIuaD4KI2luY2x1ZGUgPG5ldC9pcmRhL3RpbWVyLmg+CiNpbmNsdWRlIDxuZXQvaXJkYS9pcmxhcF9mcmFtZS5oPgojaW5jbHVkZSA8bmV0L2lyZGEvcW9zLmg+CgpzdGF0aWMgdm9pZCBpcmxhcF9zZW5kX2lfZnJhbWUoc3RydWN0IGlybGFwX2NiICpzZWxmLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiLAoJCQkgICAgICAgaW50IGNvbW1hbmQpOwoKLyoKICogRnVuY3Rpb24gaXJsYXBfaW5zZXJ0X2luZm8gKHNlbGYsIHNrYikKICoKICogICAgSW5zZXJ0IG1pbmltdW0gdHVybmFyb3VuZCB0aW1lIGFuZCBzcGVlZCBpbmZvcm1hdGlvbiBpbnRvIHRoZSBza2IuIFdlCiAqICAgIG5lZWQgdG8gZG8gdGhpcyBzaW5jZSBpdCdzIHBlciBwYWNrZXQgcmVsZXZhbnQgaW5mb3JtYXRpb24uIFNhZmUgdG8KICogICAgaGF2ZSB0aGlzIGZ1bmN0aW9uIGlubGluZWQgc2luY2UgaXQncyBvbmx5IGNhbGxlZCBmcm9tIG9uZSBwbGFjZQogKi8Kc3RhdGljIGlubGluZSB2b2lkIGlybGFwX2luc2VydF9pbmZvKHN0cnVjdCBpcmxhcF9jYiAqc2VsZiwKCQkJCSAgICAgc3RydWN0IHNrX2J1ZmYgKnNrYikKewoJc3RydWN0IGlyZGFfc2tiX2NiICpjYiA9IChzdHJ1Y3QgaXJkYV9za2JfY2IgKikgc2tiLT5jYjsKCgkvKgoJICogSW5zZXJ0IE1UVCAobWluLiB0dXJuIHRpbWUpIGFuZCBzcGVlZCBpbnRvIHNrYiwgc28gdGhhdCB0aGUKCSAqIGRldmljZSBkcml2ZXIga25vd3Mgd2hpY2ggc2V0dGluZ3MgdG8gdXNlCgkgKi8KCWNiLT5tYWdpYyA9IExBUF9NQUdJQzsKCWNiLT5tdHQgPSBzZWxmLT5tdHRfcmVxdWlyZWQ7CgljYi0+bmV4dF9zcGVlZCA9IHNlbGYtPnNwZWVkOwoKCS8qIFJlc2V0ICovCglzZWxmLT5tdHRfcmVxdWlyZWQgPSAwOwoKCS8qCgkgKiBEZWxheSBlcXVhbHMgbmVnb3RpYXRlZCBCT0ZzIGNvdW50LCBwbHVzIHRoZSBudW1iZXIgb2YgQk9GcyB0bwoJICogZm9yY2UgdGhlIG5lZ290aWF0ZWQgbWluaW11bSB0dXJuYXJvdW5kIHRpbWUKCSAqLwoJY2ItPnhib2ZzID0gc2VsZi0+Ym9mc19jb3VudDsKCWNiLT5uZXh0X3hib2ZzID0gc2VsZi0+bmV4dF9ib2ZzOwoJY2ItPnhib2ZzX2RlbGF5ID0gc2VsZi0+eGJvZnNfZGVsYXk7CgoJLyogUmVzZXQgWEJPRidzIGRlbGF5ICh1c2VkIG9ubHkgZm9yIGdldHRpbmcgbWluIHR1cm4gdGltZSkgKi8KCXNlbGYtPnhib2ZzX2RlbGF5ID0gMDsKCS8qIFB1dCB0aGUgY29ycmVjdCB4Ym9mcyB2YWx1ZSBmb3IgdGhlIG5leHQgcGFja2V0ICovCglzZWxmLT5ib2ZzX2NvdW50ID0gc2VsZi0+bmV4dF9ib2ZzOwp9CgovKgogKiBGdW5jdGlvbiBpcmxhcF9xdWV1ZV94bWl0IChzZWxmLCBza2IpCiAqCiAqICAgIEEgbGl0dGxlIHdyYXBwZXIgZm9yIGRldl9xdWV1ZV94bWl0LCBzbyB3ZSBjYW4gaW5zZXJ0IHNvbWUgY29tbW9uCiAqICAgIGNvZGUgaW50byBpdC4KICovCnZvaWQgaXJsYXBfcXVldWVfeG1pdChzdHJ1Y3QgaXJsYXBfY2IgKnNlbGYsIHN0cnVjdCBza19idWZmICpza2IpCnsKCS8qIFNvbWUgY29tbW9uIGluaXQgc3R1ZmYgKi8KCXNrYi0+ZGV2ID0gc2VsZi0+bmV0ZGV2OwoJc2tiX3Jlc2V0X21hY19oZWFkZXIoc2tiKTsKCXNrYl9yZXNldF9uZXR3b3JrX2hlYWRlcihza2IpOwoJc2tiX3Jlc2V0X3RyYW5zcG9ydF9oZWFkZXIoc2tiKTsKCXNrYi0+cHJvdG9jb2wgPSBodG9ucyhFVEhfUF9JUkRBKTsKCXNrYi0+cHJpb3JpdHkgPSBUQ19QUklPX0JFU1RFRkZPUlQ7CgoJaXJsYXBfaW5zZXJ0X2luZm8oc2VsZiwgc2tiKTsKCglkZXZfcXVldWVfeG1pdChza2IpOwp9CgovKgogKiBGdW5jdGlvbiBpcmxhcF9zZW5kX3Nucm1fY21kICh2b2lkKQogKgogKiAgICBUcmFuc21pdHMgYSBjb25uZWN0IFNOUk0gY29tbWFuZCBmcmFtZQogKi8Kdm9pZCBpcmxhcF9zZW5kX3Nucm1fZnJhbWUoc3RydWN0IGlybGFwX2NiICpzZWxmLCBzdHJ1Y3QgcW9zX2luZm8gKnFvcykKewoJc3RydWN0IHNrX2J1ZmYgKnR4X3NrYjsKCXN0cnVjdCBzbnJtX2ZyYW1lICpmcmFtZTsKCWludCByZXQ7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IExBUF9NQUdJQywgcmV0dXJuOyk7CgoJLyogQWxsb2NhdGUgZnJhbWUgKi8KCXR4X3NrYiA9IGFsbG9jX3NrYihzaXplb2Yoc3RydWN0IHNucm1fZnJhbWUpICsKCQkJICAgSVJMQVBfTkVHT0NJQVRJT05fUEFSQU1TX0xFTiwKCQkJICAgR0ZQX0FUT01JQyk7CglpZiAoIXR4X3NrYikKCQlyZXR1cm47CgoJZnJhbWUgPSAoc3RydWN0IHNucm1fZnJhbWUgKikgc2tiX3B1dCh0eF9za2IsIDIpOwoKCS8qIEluc2VydCBjb25uZWN0aW9uIGFkZHJlc3MgZmllbGQgKi8KCWlmIChxb3MpCgkJZnJhbWUtPmNhZGRyID0gQ01EX0ZSQU1FIHwgQ0JST0FEQ0FTVDsKCWVsc2UKCQlmcmFtZS0+Y2FkZHIgPSBDTURfRlJBTUUgfCBzZWxmLT5jYWRkcjsKCgkvKiBJbnNlcnQgY29udHJvbCBmaWVsZCAqLwoJZnJhbWUtPmNvbnRyb2wgPSBTTlJNX0NNRCB8IFBGX0JJVDsKCgkvKgoJICogIElmIHdlIGFyZSBlc3RhYmxpc2hpbmcgYSBjb25uZWN0aW9uIHRoZW4gaW5zZXJ0IFFvUyBwYXJhbWVydGVycwoJICovCglpZiAocW9zKSB7CgkJc2tiX3B1dCh0eF9za2IsIDkpOyAvKiAyNSBsZWZ0ICovCgkJZnJhbWUtPnNhZGRyID0gY3B1X3RvX2xlMzIoc2VsZi0+c2FkZHIpOwoJCWZyYW1lLT5kYWRkciA9IGNwdV90b19sZTMyKHNlbGYtPmRhZGRyKTsKCgkJZnJhbWUtPm5jYWRkciA9IHNlbGYtPmNhZGRyOwoKCQlyZXQgPSBpcmxhcF9pbnNlcnRfcW9zX25lZ290aWF0aW9uX3BhcmFtcyhzZWxmLCB0eF9za2IpOwoJCWlmIChyZXQgPCAwKSB7CgkJCWRldl9rZnJlZV9za2IodHhfc2tiKTsKCQkJcmV0dXJuOwoJCX0KCX0KCWlybGFwX3F1ZXVlX3htaXQoc2VsZiwgdHhfc2tiKTsKfQoKLyoKICogRnVuY3Rpb24gaXJsYXBfcmVjdl9zbnJtX2NtZCAoc2tiLCBpbmZvKQogKgogKiAgICBSZWNlaXZlZCBTTlJNIChTZXQgTm9ybWFsIFJlc3BvbnNlIE1vZGUpIGNvbW1hbmQgZnJhbWUKICoKICovCnN0YXRpYyB2b2lkIGlybGFwX3JlY3Zfc25ybV9jbWQoc3RydWN0IGlybGFwX2NiICpzZWxmLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiLAoJCQkJc3RydWN0IGlybGFwX2luZm8gKmluZm8pCnsKCXN0cnVjdCBzbnJtX2ZyYW1lICpmcmFtZTsKCglpZiAocHNrYl9tYXlfcHVsbChza2Isc2l6ZW9mKHN0cnVjdCBzbnJtX2ZyYW1lKSkpIHsKCQlmcmFtZSA9IChzdHJ1Y3Qgc25ybV9mcmFtZSAqKSBza2ItPmRhdGE7CgoJCS8qIENvcHkgdGhlIG5ldyBjb25uZWN0aW9uIGFkZHJlc3MgaWdub3JpbmcgdGhlIEMvUiBiaXQgKi8KCQlpbmZvLT5jYWRkciA9IGZyYW1lLT5uY2FkZHIgJiAweEZFOwoKCQkvKiBDaGVjayBpZiB0aGUgbmV3IGNvbm5lY3Rpb24gYWRkcmVzcyBpcyB2YWxpZCAqLwoJCWlmICgoaW5mby0+Y2FkZHIgPT0gMHgwMCkgfHwgKGluZm8tPmNhZGRyID09IDB4ZmUpKSB7CgkJCUlSREFfREVCVUcoMywgIiVzKCksIGludmFsaWQgY29ubmVjdGlvbiBhZGRyZXNzIVxuIiwKCQkJCSAgIF9fRlVOQ1RJT05fXyk7CgkJCXJldHVybjsKCQl9CgoJCS8qIENvcHkgcGVlciBkZXZpY2UgYWRkcmVzcyAqLwoJCWluZm8tPmRhZGRyID0gbGUzMl90b19jcHUoZnJhbWUtPnNhZGRyKTsKCQlpbmZvLT5zYWRkciA9IGxlMzJfdG9fY3B1KGZyYW1lLT5kYWRkcik7CgoJCS8qIE9ubHkgYWNjZXB0IGlmIGFkZHJlc3NlZCBkaXJlY3RseSB0byB1cyAqLwoJCWlmIChpbmZvLT5zYWRkciAhPSBzZWxmLT5zYWRkcikgewoJCQlJUkRBX0RFQlVHKDIsICIlcygpLCBub3QgYWRkcmVzc2VkIHRvIHVzIVxuIiwKCQkJCSAgIF9fRlVOQ1RJT05fXyk7CgkJCXJldHVybjsKCQl9CgkJaXJsYXBfZG9fZXZlbnQoc2VsZiwgUkVDVl9TTlJNX0NNRCwgc2tiLCBpbmZvKTsKCX0gZWxzZSB7CgkJLyogU2lnbmFsIHRoYXQgdGhpcyBTTlJNIGZyYW1lIGRvZXMgbm90IGNvbnRhaW4gYW5kIEktZmllbGQgKi8KCQlpcmxhcF9kb19ldmVudChzZWxmLCBSRUNWX1NOUk1fQ01ELCBza2IsIE5VTEwpOwoJfQp9CgovKgogKiBGdW5jdGlvbiBpcmxhcF9zZW5kX3VhX3Jlc3BvbnNlX2ZyYW1lIChxb3MpCiAqCiAqICAgIFNlbmQgVUEgKFVubnVtYmVyZWQgQWNrbm93bGVkZ2VtZW50KSBmcmFtZQogKgogKi8Kdm9pZCBpcmxhcF9zZW5kX3VhX3Jlc3BvbnNlX2ZyYW1lKHN0cnVjdCBpcmxhcF9jYiAqc2VsZiwgc3RydWN0IHFvc19pbmZvICpxb3MpCnsKCXN0cnVjdCBza19idWZmICp0eF9za2I7CglzdHJ1Y3QgdWFfZnJhbWUgKmZyYW1lOwoJaW50IHJldDsKCglJUkRBX0RFQlVHKDIsICIlcygpIDwlbGQ+XG4iLCBfX0ZVTkNUSU9OX18sIGppZmZpZXMpOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBMQVBfTUFHSUMsIHJldHVybjspOwoKCS8qIEFsbG9jYXRlIGZyYW1lICovCgl0eF9za2IgPSBhbGxvY19za2Ioc2l6ZW9mKHN0cnVjdCB1YV9mcmFtZSkgKwoJCQkgICBJUkxBUF9ORUdPQ0lBVElPTl9QQVJBTVNfTEVOLAoJCQkgICBHRlBfQVRPTUlDKTsKCWlmICghdHhfc2tiKQoJCXJldHVybjsKCglmcmFtZSA9IChzdHJ1Y3QgdWFfZnJhbWUgKikgc2tiX3B1dCh0eF9za2IsIDEwKTsKCgkvKiBCdWlsZCBVQSByZXNwb25zZSAqLwoJZnJhbWUtPmNhZGRyID0gc2VsZi0+Y2FkZHI7CglmcmFtZS0+Y29udHJvbCA9IFVBX1JTUCB8IFBGX0JJVDsKCglmcmFtZS0+c2FkZHIgPSBjcHVfdG9fbGUzMihzZWxmLT5zYWRkcik7CglmcmFtZS0+ZGFkZHIgPSBjcHVfdG9fbGUzMihzZWxmLT5kYWRkcik7CgoJLyogU2hvdWxkIHdlIHNlbmQgUW9TIG5lZ290aWF0aW9uIHBhcmFtZXRlcnM/ICovCglpZiAocW9zKSB7CgkJcmV0ID0gaXJsYXBfaW5zZXJ0X3Fvc19uZWdvdGlhdGlvbl9wYXJhbXMoc2VsZiwgdHhfc2tiKTsKCQlpZiAocmV0IDwgMCkgewoJCQlkZXZfa2ZyZWVfc2tiKHR4X3NrYik7CgkJCXJldHVybjsKCQl9Cgl9CgoJaXJsYXBfcXVldWVfeG1pdChzZWxmLCB0eF9za2IpOwp9CgoKLyoKICogRnVuY3Rpb24gaXJsYXBfc2VuZF9kbV9mcmFtZSAodm9pZCkKICoKICogICAgU2VuZCBkaXNjb25uZWN0ZWQgbW9kZSAoRE0pIGZyYW1lCiAqCiAqLwp2b2lkIGlybGFwX3NlbmRfZG1fZnJhbWUoIHN0cnVjdCBpcmxhcF9jYiAqc2VsZikKewoJc3RydWN0IHNrX2J1ZmYgKnR4X3NrYiA9IE5VTEw7CglzdHJ1Y3QgZG1fZnJhbWUgKmZyYW1lOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBMQVBfTUFHSUMsIHJldHVybjspOwoKCXR4X3NrYiA9IGFsbG9jX3NrYihzaXplb2Yoc3RydWN0IGRtX2ZyYW1lKSwgR0ZQX0FUT01JQyk7CglpZiAoIXR4X3NrYikKCQlyZXR1cm47CgoJZnJhbWUgPSAoc3RydWN0IGRtX2ZyYW1lICopc2tiX3B1dCh0eF9za2IsIDIpOwoKCWlmIChzZWxmLT5zdGF0ZSA9PSBMQVBfTkRNKQoJCWZyYW1lLT5jYWRkciA9IENCUk9BRENBU1Q7CgllbHNlCgkJZnJhbWUtPmNhZGRyID0gc2VsZi0+Y2FkZHI7CgoJZnJhbWUtPmNvbnRyb2wgPSBETV9SU1AgfCBQRl9CSVQ7CgoJaXJsYXBfcXVldWVfeG1pdChzZWxmLCB0eF9za2IpOwp9CgovKgogKiBGdW5jdGlvbiBpcmxhcF9zZW5kX2Rpc2NfZnJhbWUgKHZvaWQpCiAqCiAqICAgIFNlbmQgZGlzY29ubmVjdCAoRElTQykgZnJhbWUKICoKICovCnZvaWQgaXJsYXBfc2VuZF9kaXNjX2ZyYW1lKHN0cnVjdCBpcmxhcF9jYiAqc2VsZikKewoJc3RydWN0IHNrX2J1ZmYgKnR4X3NrYiA9IE5VTEw7CglzdHJ1Y3QgZGlzY19mcmFtZSAqZnJhbWU7CgoJSVJEQV9ERUJVRygzLCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gTEFQX01BR0lDLCByZXR1cm47KTsKCgl0eF9za2IgPSBhbGxvY19za2Ioc2l6ZW9mKHN0cnVjdCBkaXNjX2ZyYW1lKSwgR0ZQX0FUT01JQyk7CglpZiAoIXR4X3NrYikKCQlyZXR1cm47CgoJZnJhbWUgPSAoc3RydWN0IGRpc2NfZnJhbWUgKilza2JfcHV0KHR4X3NrYiwgMik7CgoJZnJhbWUtPmNhZGRyID0gc2VsZi0+Y2FkZHIgfCBDTURfRlJBTUU7CglmcmFtZS0+Y29udHJvbCA9IERJU0NfQ01EIHwgUEZfQklUOwoKCWlybGFwX3F1ZXVlX3htaXQoc2VsZiwgdHhfc2tiKTsKfQoKLyoKICogRnVuY3Rpb24gaXJsYXBfc2VuZF9kaXNjb3ZlcnlfeGlkX2ZyYW1lIChTLCBzLCBjb21tYW5kKQogKgogKiAgICBCdWlsZCBhbmQgdHJhbnNtaXQgYSBYSUQgKGVYY2hhbmdlIHN0YXRpb24gSURlbnRpZmllcikgZGlzY292ZXJ5CiAqICAgIGZyYW1lLgogKi8Kdm9pZCBpcmxhcF9zZW5kX2Rpc2NvdmVyeV94aWRfZnJhbWUoc3RydWN0IGlybGFwX2NiICpzZWxmLCBpbnQgUywgX191OCBzLAoJCQkJICAgIF9fdTggY29tbWFuZCwgZGlzY292ZXJ5X3QgKmRpc2NvdmVyeSkKewoJc3RydWN0IHNrX2J1ZmYgKnR4X3NrYiA9IE5VTEw7CglzdHJ1Y3QgeGlkX2ZyYW1lICpmcmFtZTsKCV9fdTMyIGJjYXN0ID0gQlJPQURDQVNUOwoJX191OCAqaW5mbzsKCglJUkRBX0RFQlVHKDQsICIlcygpLCBzPSVkLCBTPSVkLCBjb21tYW5kPSVkXG4iLCBfX0ZVTkNUSU9OX18sCgkJICAgcywgUywgY29tbWFuZCk7CgoJSVJEQV9BU1NFUlQoc2VsZiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNlbGYtPm1hZ2ljID09IExBUF9NQUdJQywgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChkaXNjb3ZlcnkgIT0gTlVMTCwgcmV0dXJuOyk7CgoJdHhfc2tiID0gYWxsb2Nfc2tiKHNpemVvZihzdHJ1Y3QgeGlkX2ZyYW1lKSArIElSTEFQX0RJU0NPVkVSWV9JTkZPX0xFTiwKCQkJICAgR0ZQX0FUT01JQyk7CglpZiAoIXR4X3NrYikKCQlyZXR1cm47CgoJc2tiX3B1dCh0eF9za2IsIDE0KTsKCWZyYW1lID0gKHN0cnVjdCB4aWRfZnJhbWUgKikgdHhfc2tiLT5kYXRhOwoKCWlmIChjb21tYW5kKSB7CgkJZnJhbWUtPmNhZGRyID0gQ0JST0FEQ0FTVCB8IENNRF9GUkFNRTsKCQlmcmFtZS0+Y29udHJvbCA9ICBYSURfQ01EIHwgUEZfQklUOwoJfSBlbHNlIHsKCQlmcmFtZS0+Y2FkZHIgPSBDQlJPQURDQVNUOwoJCWZyYW1lLT5jb250cm9sID0gIFhJRF9SU1AgfCBQRl9CSVQ7Cgl9CglmcmFtZS0+aWRlbnQgPSBYSURfRk9STUFUOwoKCWZyYW1lLT5zYWRkciA9IGNwdV90b19sZTMyKHNlbGYtPnNhZGRyKTsKCglpZiAoY29tbWFuZCkKCQlmcmFtZS0+ZGFkZHIgPSBjcHVfdG9fbGUzMihiY2FzdCk7CgllbHNlCgkJZnJhbWUtPmRhZGRyID0gY3B1X3RvX2xlMzIoZGlzY292ZXJ5LT5kYXRhLmRhZGRyKTsKCglzd2l0Y2ggKFMpIHsKCWNhc2UgMToKCQlmcmFtZS0+ZmxhZ3MgPSAweDAwOwoJCWJyZWFrOwoJY2FzZSA2OgoJCWZyYW1lLT5mbGFncyA9IDB4MDE7CgkJYnJlYWs7CgljYXNlIDg6CgkJZnJhbWUtPmZsYWdzID0gMHgwMjsKCQlicmVhazsKCWNhc2UgMTY6CgkJZnJhbWUtPmZsYWdzID0gMHgwMzsKCQlicmVhazsKCWRlZmF1bHQ6CgkJZnJhbWUtPmZsYWdzID0gMHgwMjsKCQlicmVhazsKCX0KCglmcmFtZS0+c2xvdG5yID0gczsKCWZyYW1lLT52ZXJzaW9uID0gMHgwMDsKCgkvKgoJICogIFByb3ZpZGUgaW5mbyBmb3IgZmluYWwgc2xvdCBvbmx5IGluIGNvbW1hbmRzLCBhbmQgZm9yIGFsbAoJICogIHJlc3BvbnNlcy4gU2VuZCB0aGUgc2Vjb25kIGJ5dGUgb2YgdGhlIGhpbnQgb25seSBpZiB0aGUKCSAqICBFWFRFTlNJT04gYml0IGlzIHNldCBpbiB0aGUgZmlyc3QgYnl0ZS4KCSAqLwoJaWYgKCFjb21tYW5kIHx8IChmcmFtZS0+c2xvdG5yID09IDB4ZmYpKSB7CgkJaW50IGxlbjsKCgkJaWYgKGRpc2NvdmVyeS0+ZGF0YS5oaW50c1swXSAmIEhJTlRfRVhURU5TSU9OKSB7CgkJCWluZm8gPSBza2JfcHV0KHR4X3NrYiwgMik7CgkJCWluZm9bMF0gPSBkaXNjb3ZlcnktPmRhdGEuaGludHNbMF07CgkJCWluZm9bMV0gPSBkaXNjb3ZlcnktPmRhdGEuaGludHNbMV07CgkJfSBlbHNlIHsKCQkJaW5mbyA9IHNrYl9wdXQodHhfc2tiLCAxKTsKCQkJaW5mb1swXSA9IGRpc2NvdmVyeS0+ZGF0YS5oaW50c1swXTsKCQl9CgkJaW5mbyA9IHNrYl9wdXQodHhfc2tiLCAxKTsKCQlpbmZvWzBdID0gZGlzY292ZXJ5LT5kYXRhLmNoYXJzZXQ7CgoJCWxlbiA9IElSREFfTUlOKGRpc2NvdmVyeS0+bmFtZV9sZW4sIHNrYl90YWlscm9vbSh0eF9za2IpKTsKCQlpbmZvID0gc2tiX3B1dCh0eF9za2IsIGxlbik7CgkJbWVtY3B5KGluZm8sIGRpc2NvdmVyeS0+ZGF0YS5pbmZvLCBsZW4pOwoJfQoJaXJsYXBfcXVldWVfeG1pdChzZWxmLCB0eF9za2IpOwp9CgovKgogKiBGdW5jdGlvbiBpcmxhcF9yZWN2X2Rpc2NvdmVyeV94aWRfcnNwIChza2IsIGluZm8pCiAqCiAqICAgIFJlY2VpdmVkIGEgWElEIGRpc2NvdmVyeSByZXNwb25zZQogKgogKi8Kc3RhdGljIHZvaWQgaXJsYXBfcmVjdl9kaXNjb3ZlcnlfeGlkX3JzcChzdHJ1Y3QgaXJsYXBfY2IgKnNlbGYsCgkJCQkJIHN0cnVjdCBza19idWZmICpza2IsCgkJCQkJIHN0cnVjdCBpcmxhcF9pbmZvICppbmZvKQp7CglzdHJ1Y3QgeGlkX2ZyYW1lICp4aWQ7CglkaXNjb3ZlcnlfdCAqZGlzY292ZXJ5ID0gTlVMTDsKCV9fdTggKmRpc2NvdmVyeV9pbmZvOwoJY2hhciAqdGV4dDsKCglJUkRBX0RFQlVHKDQsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18pOwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBMQVBfTUFHSUMsIHJldHVybjspOwoKCWlmICghcHNrYl9tYXlfcHVsbChza2IsIHNpemVvZihzdHJ1Y3QgeGlkX2ZyYW1lKSkpIHsKCQlJUkRBX0VSUk9SKCIlczogZnJhbWUgdG9vIHNob3J0IVxuIiwgX19GVU5DVElPTl9fKTsKCQlyZXR1cm47Cgl9CgoJeGlkID0gKHN0cnVjdCB4aWRfZnJhbWUgKikgc2tiLT5kYXRhOwoKCWluZm8tPmRhZGRyID0gbGUzMl90b19jcHUoeGlkLT5zYWRkcik7CglpbmZvLT5zYWRkciA9IGxlMzJfdG9fY3B1KHhpZC0+ZGFkZHIpOwoKCS8qIE1ha2Ugc3VyZSBmcmFtZSBpcyBhZGRyZXNzZWQgdG8gdXMgKi8KCWlmICgoaW5mby0+c2FkZHIgIT0gc2VsZi0+c2FkZHIpICYmIChpbmZvLT5zYWRkciAhPSBCUk9BRENBU1QpKSB7CgkJSVJEQV9ERUJVRygwLCAiJXMoKSwgZnJhbWUgaXMgbm90IGFkZHJlc3NlZCB0byB1cyFcbiIsCgkJCSAgIF9fRlVOQ1RJT05fXyk7CgkJcmV0dXJuOwoJfQoKCWlmICgoZGlzY292ZXJ5ID0ga3phbGxvYyhzaXplb2YoZGlzY292ZXJ5X3QpLCBHRlBfQVRPTUlDKSkgPT0gTlVMTCkgewoJCUlSREFfV0FSTklORygiJXM6IGttYWxsb2MgZmFpbGVkIVxuIiwgX19GVU5DVElPTl9fKTsKCQlyZXR1cm47Cgl9CgoJZGlzY292ZXJ5LT5kYXRhLmRhZGRyID0gaW5mby0+ZGFkZHI7CglkaXNjb3ZlcnktPmRhdGEuc2FkZHIgPSBzZWxmLT5zYWRkcjsKCWRpc2NvdmVyeS0+dGltZXN0YW1wID0gamlmZmllczsKCglJUkRBX0RFQlVHKDQsICIlcygpLCBkYWRkcj0lMDh4XG4iLCBfX0ZVTkNUSU9OX18sCgkJICAgZGlzY292ZXJ5LT5kYXRhLmRhZGRyKTsKCglkaXNjb3ZlcnlfaW5mbyA9IHNrYl9wdWxsKHNrYiwgc2l6ZW9mKHN0cnVjdCB4aWRfZnJhbWUpKTsKCgkvKiBHZXQgaW5mbyByZXR1cm5lZCBmcm9tIHBlZXIgKi8KCWRpc2NvdmVyeS0+ZGF0YS5oaW50c1swXSA9IGRpc2NvdmVyeV9pbmZvWzBdOwoJaWYgKGRpc2NvdmVyeV9pbmZvWzBdICYgSElOVF9FWFRFTlNJT04pIHsKCQlJUkRBX0RFQlVHKDQsICJFWFRFTlNJT05cbiIpOwoJCWRpc2NvdmVyeS0+ZGF0YS5oaW50c1sxXSA9IGRpc2NvdmVyeV9pbmZvWzFdOwoJCWRpc2NvdmVyeS0+ZGF0YS5jaGFyc2V0ID0gZGlzY292ZXJ5X2luZm9bMl07CgkJdGV4dCA9IChjaGFyICopICZkaXNjb3ZlcnlfaW5mb1szXTsKCX0gZWxzZSB7CgkJZGlzY292ZXJ5LT5kYXRhLmhpbnRzWzFdID0gMDsKCQlkaXNjb3ZlcnktPmRhdGEuY2hhcnNldCA9IGRpc2NvdmVyeV9pbmZvWzFdOwoJCXRleHQgPSAoY2hhciAqKSAmZGlzY292ZXJ5X2luZm9bMl07Cgl9CgkvKgoJICogIFRlcm1pbmF0ZSBpbmZvIHN0cmluZywgc2hvdWxkIGJlIHNhZmUgc2luY2UgdGhpcyBpcyB3aGVyZSB0aGUKCSAqICBGQ1MgYnl0ZXMgcmVzaWRlcy4KCSAqLwoJc2tiLT5kYXRhW3NrYi0+bGVuXSA9ICdcMCc7CglzdHJuY3B5KGRpc2NvdmVyeS0+ZGF0YS5pbmZvLCB0ZXh0LCBOSUNLTkFNRV9NQVhfTEVOKTsKCWRpc2NvdmVyeS0+bmFtZV9sZW4gPSBzdHJsZW4oZGlzY292ZXJ5LT5kYXRhLmluZm8pOwoKCWluZm8tPmRpc2NvdmVyeSA9IGRpc2NvdmVyeTsKCglpcmxhcF9kb19ldmVudChzZWxmLCBSRUNWX0RJU0NPVkVSWV9YSURfUlNQLCBza2IsIGluZm8pOwp9CgovKgogKiBGdW5jdGlvbiBpcmxhcF9yZWN2X2Rpc2NvdmVyeV94aWRfY21kIChza2IsIGluZm8pCiAqCiAqICAgIFJlY2VpdmVkIGEgWElEIGRpc2NvdmVyeSBjb21tYW5kCiAqCiAqLwpzdGF0aWMgdm9pZCBpcmxhcF9yZWN2X2Rpc2NvdmVyeV94aWRfY21kKHN0cnVjdCBpcmxhcF9jYiAqc2VsZiwKCQkJCQkgc3RydWN0IHNrX2J1ZmYgKnNrYiwKCQkJCQkgc3RydWN0IGlybGFwX2luZm8gKmluZm8pCnsKCXN0cnVjdCB4aWRfZnJhbWUgKnhpZDsKCWRpc2NvdmVyeV90ICpkaXNjb3ZlcnkgPSBOVUxMOwoJX191OCAqZGlzY292ZXJ5X2luZm87CgljaGFyICp0ZXh0OwoKCWlmICghcHNrYl9tYXlfcHVsbChza2IsIHNpemVvZihzdHJ1Y3QgeGlkX2ZyYW1lKSkpIHsKCQlJUkRBX0VSUk9SKCIlczogZnJhbWUgdG9vIHNob3J0IVxuIiwgX19GVU5DVElPTl9fKTsKCQlyZXR1cm47Cgl9CgoJeGlkID0gKHN0cnVjdCB4aWRfZnJhbWUgKikgc2tiLT5kYXRhOwoKCWluZm8tPmRhZGRyID0gbGUzMl90b19jcHUoeGlkLT5zYWRkcik7CglpbmZvLT5zYWRkciA9IGxlMzJfdG9fY3B1KHhpZC0+ZGFkZHIpOwoKCS8qIE1ha2Ugc3VyZSBmcmFtZSBpcyBhZGRyZXNzZWQgdG8gdXMgKi8KCWlmICgoaW5mby0+c2FkZHIgIT0gc2VsZi0+c2FkZHIpICYmIChpbmZvLT5zYWRkciAhPSBCUk9BRENBU1QpKSB7CgkJSVJEQV9ERUJVRygwLCAiJXMoKSwgZnJhbWUgaXMgbm90IGFkZHJlc3NlZCB0byB1cyFcbiIsCgkJCSAgIF9fRlVOQ1RJT05fXyk7CgkJcmV0dXJuOwoJfQoKCXN3aXRjaCAoeGlkLT5mbGFncyAmIDB4MDMpIHsKCWNhc2UgMHgwMDoKCQlpbmZvLT5TID0gMTsKCQlicmVhazsKCWNhc2UgMHgwMToKCQlpbmZvLT5TID0gNjsKCQlicmVhazsKCWNhc2UgMHgwMjoKCQlpbmZvLT5TID0gODsKCQlicmVhazsKCWNhc2UgMHgwMzoKCQlpbmZvLT5TID0gMTY7CgkJYnJlYWs7CglkZWZhdWx0OgoJCS8qIEVycm9yISEgKi8KCQlyZXR1cm47Cgl9CglpbmZvLT5zID0geGlkLT5zbG90bnI7CgoJZGlzY292ZXJ5X2luZm8gPSBza2JfcHVsbChza2IsIHNpemVvZihzdHJ1Y3QgeGlkX2ZyYW1lKSk7CgoJLyoKCSAqICBDaGVjayBpZiBsYXN0IGZyYW1lCgkgKi8KCWlmIChpbmZvLT5zID09IDB4ZmYpIHsKCQkvKiBDaGVjayBpZiB0aGluZ3MgYXJlIHNhbmUgYXQgdGhpcyBwb2ludC4uLiAqLwoJCWlmKChkaXNjb3ZlcnlfaW5mbyA9PSBOVUxMKSB8fAoJCSAgICFwc2tiX21heV9wdWxsKHNrYiwgMykpIHsKCQkJSVJEQV9FUlJPUigiJXM6IGRpc2NvdmVyeSBmcmFtZSB0b28gc2hvcnQhXG4iLAoJCQkJICAgX19GVU5DVElPTl9fKTsKCQkJcmV0dXJuOwoJCX0KCgkJLyoKCQkgKiAgV2Ugbm93IGhhdmUgc29tZSBkaXNjb3ZlcnkgaW5mbyB0byBkZWxpdmVyIQoJCSAqLwoJCWRpc2NvdmVyeSA9IGttYWxsb2Moc2l6ZW9mKGRpc2NvdmVyeV90KSwgR0ZQX0FUT01JQyk7CgkJaWYgKCFkaXNjb3ZlcnkpIHsKCQkJSVJEQV9XQVJOSU5HKCIlczogdW5hYmxlIHRvIG1hbGxvYyFcbiIsIF9fRlVOQ1RJT05fXyk7CgkJCXJldHVybjsKCQl9CgoJCWRpc2NvdmVyeS0+ZGF0YS5kYWRkciA9IGluZm8tPmRhZGRyOwoJCWRpc2NvdmVyeS0+ZGF0YS5zYWRkciA9IHNlbGYtPnNhZGRyOwoJCWRpc2NvdmVyeS0+dGltZXN0YW1wID0gamlmZmllczsKCgkJZGlzY292ZXJ5LT5kYXRhLmhpbnRzWzBdID0gZGlzY292ZXJ5X2luZm9bMF07CgkJaWYgKGRpc2NvdmVyeV9pbmZvWzBdICYgSElOVF9FWFRFTlNJT04pIHsKCQkJZGlzY292ZXJ5LT5kYXRhLmhpbnRzWzFdID0gZGlzY292ZXJ5X2luZm9bMV07CgkJCWRpc2NvdmVyeS0+ZGF0YS5jaGFyc2V0ID0gZGlzY292ZXJ5X2luZm9bMl07CgkJCXRleHQgPSAoY2hhciAqKSAmZGlzY292ZXJ5X2luZm9bM107CgkJfSBlbHNlIHsKCQkJZGlzY292ZXJ5LT5kYXRhLmhpbnRzWzFdID0gMDsKCQkJZGlzY292ZXJ5LT5kYXRhLmNoYXJzZXQgPSBkaXNjb3ZlcnlfaW5mb1sxXTsKCQkJdGV4dCA9IChjaGFyICopICZkaXNjb3ZlcnlfaW5mb1syXTsKCQl9CgkJLyoKCQkgKiAgVGVybWluYXRlIHN0cmluZywgc2hvdWxkIGJlIHNhZmUgc2luY2UgdGhpcyBpcyB3aGVyZSB0aGUKCQkgKiAgRkNTIGJ5dGVzIHJlc2lkZXMuCgkJICovCgkJc2tiLT5kYXRhW3NrYi0+bGVuXSA9ICdcMCc7CgkJc3RybmNweShkaXNjb3ZlcnktPmRhdGEuaW5mbywgdGV4dCwgTklDS05BTUVfTUFYX0xFTik7CgkJZGlzY292ZXJ5LT5uYW1lX2xlbiA9IHN0cmxlbihkaXNjb3ZlcnktPmRhdGEuaW5mbyk7CgoJCWluZm8tPmRpc2NvdmVyeSA9IGRpc2NvdmVyeTsKCX0gZWxzZQoJCWluZm8tPmRpc2NvdmVyeSA9IE5VTEw7CgoJaXJsYXBfZG9fZXZlbnQoc2VsZiwgUkVDVl9ESVNDT1ZFUllfWElEX0NNRCwgc2tiLCBpbmZvKTsKfQoKLyoKICogRnVuY3Rpb24gaXJsYXBfc2VuZF9ycl9mcmFtZSAoc2VsZiwgY29tbWFuZCkKICoKICogICAgQnVpbGQgYW5kIHRyYW5zbWl0IFJSIChSZWNlaXZlIFJlYWR5KSBmcmFtZS4gTm90aWNlIHRoYXQgaXQgaXMgY3VycmVudGx5CiAqICAgIG9ubHkgcG9zc2libGUgdG8gc2VuZCBSUiBmcmFtZXMgd2l0aCB0aGUgcG9sbCBiaXQgc2V0LgogKi8Kdm9pZCBpcmxhcF9zZW5kX3JyX2ZyYW1lKHN0cnVjdCBpcmxhcF9jYiAqc2VsZiwgaW50IGNvbW1hbmQpCnsKCXN0cnVjdCBza19idWZmICp0eF9za2I7CglzdHJ1Y3QgcnJfZnJhbWUgKmZyYW1lOwoKCXR4X3NrYiA9IGFsbG9jX3NrYihzaXplb2Yoc3RydWN0IHJyX2ZyYW1lKSwgR0ZQX0FUT01JQyk7CglpZiAoIXR4X3NrYikKCQlyZXR1cm47CgoJZnJhbWUgPSAoc3RydWN0IHJyX2ZyYW1lICopc2tiX3B1dCh0eF9za2IsIDIpOwoKCWZyYW1lLT5jYWRkciA9IHNlbGYtPmNhZGRyOwoJZnJhbWUtPmNhZGRyIHw9IChjb21tYW5kKSA/IENNRF9GUkFNRSA6IDA7CgoJZnJhbWUtPmNvbnRyb2wgPSBSUiB8IFBGX0JJVCB8IChzZWxmLT52ciA8PCA1KTsKCglpcmxhcF9xdWV1ZV94bWl0KHNlbGYsIHR4X3NrYik7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlybGFwX3NlbmRfcmRfZnJhbWUgKHNlbGYpCiAqCiAqICAgIFJlcXVlc3QgZGlzY29ubmVjdC4gVXNlZCBieSBhIHNlY29uZGFyeSBzdGF0aW9uIHRvIHJlcXVlc3QgdGhlCiAqICAgIGRpc2Nvbm5lY3Rpb24gb2YgdGhlIGxpbmsuCiAqLwp2b2lkIGlybGFwX3NlbmRfcmRfZnJhbWUoc3RydWN0IGlybGFwX2NiICpzZWxmKQp7CglzdHJ1Y3Qgc2tfYnVmZiAqdHhfc2tiOwoJc3RydWN0IHJkX2ZyYW1lICpmcmFtZTsKCgl0eF9za2IgPSBhbGxvY19za2Ioc2l6ZW9mKHN0cnVjdCByZF9mcmFtZSksIEdGUF9BVE9NSUMpOwoJaWYgKCF0eF9za2IpCgkJcmV0dXJuOwoKCWZyYW1lID0gKHN0cnVjdCByZF9mcmFtZSAqKXNrYl9wdXQodHhfc2tiLCAyKTsKCglmcmFtZS0+Y2FkZHIgPSBzZWxmLT5jYWRkcjsKCWZyYW1lLT5jYWRkciA9IFJEX1JTUCB8IFBGX0JJVDsKCglpcmxhcF9xdWV1ZV94bWl0KHNlbGYsIHR4X3NrYik7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlybGFwX3JlY3ZfcnJfZnJhbWUgKHNrYiwgaW5mbykKICoKICogICAgUmVjZWl2ZWQgUlIgKFJlY2VpdmUgUmVhZHkpIGZyYW1lIGZyb20gcGVlciBzdGF0aW9uLCBubyBoYXJtIGluCiAqICAgIG1ha2luZyBpdCBpbmxpbmUgc2luY2UgaXRzIGNhbGxlZCBvbmx5IGZyb20gb25lIHNpbmdsZSBwbGFjZQogKiAgICAoaXJsYXBfZHJpdmVyX3JjdikuCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgaXJsYXBfcmVjdl9ycl9mcmFtZShzdHJ1Y3QgaXJsYXBfY2IgKnNlbGYsCgkJCQkgICAgICAgc3RydWN0IHNrX2J1ZmYgKnNrYiwKCQkJCSAgICAgICBzdHJ1Y3QgaXJsYXBfaW5mbyAqaW5mbywgaW50IGNvbW1hbmQpCnsKCWluZm8tPm5yID0gc2tiLT5kYXRhWzFdID4+IDU7CgoJLyogQ2hlY2sgaWYgdGhpcyBpcyBhIGNvbW1hbmQgb3IgYSByZXNwb25zZSBmcmFtZSAqLwoJaWYgKGNvbW1hbmQpCgkJaXJsYXBfZG9fZXZlbnQoc2VsZiwgUkVDVl9SUl9DTUQsIHNrYiwgaW5mbyk7CgllbHNlCgkJaXJsYXBfZG9fZXZlbnQoc2VsZiwgUkVDVl9SUl9SU1AsIHNrYiwgaW5mbyk7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlybGFwX3JlY3Zfcm5yX2ZyYW1lIChzZWxmLCBza2IsIGluZm8pCiAqCiAqICAgIFJlY2VpdmVkIFJOUiAoUmVjZWl2ZSBOb3QgUmVhZHkpIGZyYW1lIGZyb20gcGVlciBzdGF0aW9uCiAqCiAqLwpzdGF0aWMgdm9pZCBpcmxhcF9yZWN2X3Jucl9mcmFtZShzdHJ1Y3QgaXJsYXBfY2IgKnNlbGYsIHN0cnVjdCBza19idWZmICpza2IsCgkJCQkgc3RydWN0IGlybGFwX2luZm8gKmluZm8sIGludCBjb21tYW5kKQp7CglpbmZvLT5uciA9IHNrYi0+ZGF0YVsxXSA+PiA1OwoKCUlSREFfREVCVUcoNCwgIiVzKCksIG5yPSVkLCAlbGRcbiIsIF9fRlVOQ1RJT05fXywgaW5mby0+bnIsIGppZmZpZXMpOwoKCWlmIChjb21tYW5kKQoJCWlybGFwX2RvX2V2ZW50KHNlbGYsIFJFQ1ZfUk5SX0NNRCwgc2tiLCBpbmZvKTsKCWVsc2UKCQlpcmxhcF9kb19ldmVudChzZWxmLCBSRUNWX1JOUl9SU1AsIHNrYiwgaW5mbyk7Cn0KCnN0YXRpYyB2b2lkIGlybGFwX3JlY3ZfcmVqX2ZyYW1lKHN0cnVjdCBpcmxhcF9jYiAqc2VsZiwgc3RydWN0IHNrX2J1ZmYgKnNrYiwKCQkJCSBzdHJ1Y3QgaXJsYXBfaW5mbyAqaW5mbywgaW50IGNvbW1hbmQpCnsKCUlSREFfREVCVUcoMCwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJaW5mby0+bnIgPSBza2ItPmRhdGFbMV0gPj4gNTsKCgkvKiBDaGVjayBpZiB0aGlzIGlzIGEgY29tbWFuZCBvciBhIHJlc3BvbnNlIGZyYW1lICovCglpZiAoY29tbWFuZCkKCQlpcmxhcF9kb19ldmVudChzZWxmLCBSRUNWX1JFSl9DTUQsIHNrYiwgaW5mbyk7CgllbHNlCgkJaXJsYXBfZG9fZXZlbnQoc2VsZiwgUkVDVl9SRUpfUlNQLCBza2IsIGluZm8pOwp9CgpzdGF0aWMgdm9pZCBpcmxhcF9yZWN2X3NyZWpfZnJhbWUoc3RydWN0IGlybGFwX2NiICpzZWxmLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiLAoJCQkJICBzdHJ1Y3QgaXJsYXBfaW5mbyAqaW5mbywgaW50IGNvbW1hbmQpCnsKCUlSREFfREVCVUcoMCwgIiVzKClcbiIsIF9fRlVOQ1RJT05fXyk7CgoJaW5mby0+bnIgPSBza2ItPmRhdGFbMV0gPj4gNTsKCgkvKiBDaGVjayBpZiB0aGlzIGlzIGEgY29tbWFuZCBvciBhIHJlc3BvbnNlIGZyYW1lICovCglpZiAoY29tbWFuZCkKCQlpcmxhcF9kb19ldmVudChzZWxmLCBSRUNWX1NSRUpfQ01ELCBza2IsIGluZm8pOwoJZWxzZQoJCWlybGFwX2RvX2V2ZW50KHNlbGYsIFJFQ1ZfU1JFSl9SU1AsIHNrYiwgaW5mbyk7Cn0KCnN0YXRpYyB2b2lkIGlybGFwX3JlY3ZfZGlzY19mcmFtZShzdHJ1Y3QgaXJsYXBfY2IgKnNlbGYsIHN0cnVjdCBza19idWZmICpza2IsCgkJCQkgIHN0cnVjdCBpcmxhcF9pbmZvICppbmZvLCBpbnQgY29tbWFuZCkKewoJSVJEQV9ERUJVRygyLCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCgkvKiBDaGVjayBpZiB0aGlzIGlzIGEgY29tbWFuZCBvciBhIHJlc3BvbnNlIGZyYW1lICovCglpZiAoY29tbWFuZCkKCQlpcmxhcF9kb19ldmVudChzZWxmLCBSRUNWX0RJU0NfQ01ELCBza2IsIGluZm8pOwoJZWxzZQoJCWlybGFwX2RvX2V2ZW50KHNlbGYsIFJFQ1ZfUkRfUlNQLCBza2IsIGluZm8pOwp9CgovKgogKiBGdW5jdGlvbiBpcmxhcF9yZWN2X3VhX2ZyYW1lIChza2IsIGZyYW1lKQogKgogKiAgICBSZWNlaXZlZCBVQSAoVW5udW1iZXJlZCBBY2tub3dsZWRnZW1lbnQpIGZyYW1lCiAqCiAqLwpzdGF0aWMgaW5saW5lIHZvaWQgaXJsYXBfcmVjdl91YV9mcmFtZShzdHJ1Y3QgaXJsYXBfY2IgKnNlbGYsCgkJCQkgICAgICAgc3RydWN0IHNrX2J1ZmYgKnNrYiwKCQkJCSAgICAgICBzdHJ1Y3QgaXJsYXBfaW5mbyAqaW5mbykKewoJaXJsYXBfZG9fZXZlbnQoc2VsZiwgUkVDVl9VQV9SU1AsIHNrYiwgaW5mbyk7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlybGFwX3NlbmRfZGF0YV9wcmltYXJ5KHNlbGYsIHNrYikKICoKICogICAgU2VuZCBJLWZyYW1lcyBhcyB0aGUgcHJpbWFyeSBzdGF0aW9uIGJ1dCB3aXRob3V0IHRoZSBwb2xsIGJpdCBzZXQKICoKICovCnZvaWQgaXJsYXBfc2VuZF9kYXRhX3ByaW1hcnkoc3RydWN0IGlybGFwX2NiICpzZWxmLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CglzdHJ1Y3Qgc2tfYnVmZiAqdHhfc2tiOwoKCWlmIChza2ItPmRhdGFbMV0gPT0gSV9GUkFNRSkgewoKCQkvKgoJCSAqICBJbnNlcnQgZnJhbWUgc2VxdWVuY2UgbnVtYmVyIChWcykgaW4gY29udHJvbCBmaWVsZCBiZWZvcmUKCQkgKiAgaW5zZXJ0aW5nIGludG8gdHJhbnNtaXQgd2luZG93IHF1ZXVlLgoJCSAqLwoJCXNrYi0+ZGF0YVsxXSA9IElfRlJBTUUgfCAoc2VsZi0+dnMgPDwgMSk7CgoJCS8qCgkJICogIEluc2VydCBmcmFtZSBpbiBzdG9yZSwgaW4gY2FzZSBvZiByZXRyYW5zbWlzc2lvbnMKCQkgKiAgSW5jcmVhc2Ugc2tiIHJlZmVyZW5jZSBjb3VudCwgc2VlIGlybGFwX2RvX2V2ZW50KCkKCQkgKi8KCQlza2JfZ2V0KHNrYik7CgkJc2tiX3F1ZXVlX3RhaWwoJnNlbGYtPnd4X2xpc3QsIHNrYik7CgoJCS8qIENvcHkgYnVmZmVyICovCgkJdHhfc2tiID0gc2tiX2Nsb25lKHNrYiwgR0ZQX0FUT01JQyk7CgkJaWYgKHR4X3NrYiA9PSBOVUxMKSB7CgkJCXJldHVybjsKCQl9CgoJCXNlbGYtPnZzID0gKHNlbGYtPnZzICsgMSkgJSA4OwoJCXNlbGYtPmFja19yZXF1aXJlZCA9IEZBTFNFOwoJCXNlbGYtPndpbmRvdyAtPSAxOwoKCQlpcmxhcF9zZW5kX2lfZnJhbWUoIHNlbGYsIHR4X3NrYiwgQ01EX0ZSQU1FKTsKCX0gZWxzZSB7CgkJSVJEQV9ERUJVRyg0LCAiJXMoKSwgc2VuZGluZyB1bnJlbGlhYmxlIGZyYW1lXG4iLCBfX0ZVTkNUSU9OX18pOwoJCWlybGFwX3NlbmRfdWlfZnJhbWUoc2VsZiwgc2tiX2dldChza2IpLCBzZWxmLT5jYWRkciwgQ01EX0ZSQU1FKTsKCQlzZWxmLT53aW5kb3cgLT0gMTsKCX0KfQovKgogKiBGdW5jdGlvbiBpcmxhcF9zZW5kX2RhdGFfcHJpbWFyeV9wb2xsIChzZWxmLCBza2IpCiAqCiAqICAgIFNlbmQgSShuZm9ybWF0aW9uKSBmcmFtZSBhcyBwcmltYXJ5IHdpdGggcG9sbCBiaXQgc2V0CiAqLwp2b2lkIGlybGFwX3NlbmRfZGF0YV9wcmltYXJ5X3BvbGwoc3RydWN0IGlybGFwX2NiICpzZWxmLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CglzdHJ1Y3Qgc2tfYnVmZiAqdHhfc2tiOwoJaW50IHRyYW5zbWlzc2lvbl90aW1lOwoKCS8qIFN0b3AgUCB0aW1lciAqLwoJZGVsX3RpbWVyKCZzZWxmLT5wb2xsX3RpbWVyKTsKCgkvKiBJcyB0aGlzIHJlbGlhYmxlIG9yIHVucmVsaWFibGUgZGF0YT8gKi8KCWlmIChza2ItPmRhdGFbMV0gPT0gSV9GUkFNRSkgewoKCQkvKgoJCSAqICBJbnNlcnQgZnJhbWUgc2VxdWVuY2UgbnVtYmVyIChWcykgaW4gY29udHJvbCBmaWVsZCBiZWZvcmUKCQkgKiAgaW5zZXJ0aW5nIGludG8gdHJhbnNtaXQgd2luZG93IHF1ZXVlLgoJCSAqLwoJCXNrYi0+ZGF0YVsxXSA9IElfRlJBTUUgfCAoc2VsZi0+dnMgPDwgMSk7CgoJCS8qCgkJICogIEluc2VydCBmcmFtZSBpbiBzdG9yZSwgaW4gY2FzZSBvZiByZXRyYW5zbWlzc2lvbnMKCQkgKiAgSW5jcmVhc2Ugc2tiIHJlZmVyZW5jZSBjb3VudCwgc2VlIGlybGFwX2RvX2V2ZW50KCkKCQkgKi8KCQlza2JfZ2V0KHNrYik7CgkJc2tiX3F1ZXVlX3RhaWwoJnNlbGYtPnd4X2xpc3QsIHNrYik7CgoJCS8qIENvcHkgYnVmZmVyICovCgkJdHhfc2tiID0gc2tiX2Nsb25lKHNrYiwgR0ZQX0FUT01JQyk7CgkJaWYgKHR4X3NrYiA9PSBOVUxMKSB7CgkJCXJldHVybjsKCQl9CgoJCS8qCgkJICogIFNldCBwb2xsIGJpdCBpZiBuZWNlc3NhcnkuIFdlIGRvIHRoaXMgdG8gdGhlIGNvcGllZAoJCSAqICBza2IsIHNpbmNlIHJldHJhbnNtaXR0ZWQgbmVlZCB0byBzZXQgb3IgY2xlYXIgdGhlIHBvbGwKCQkgKiAgYml0IGRlcGVuZGluZyBvbiB3aGVuIHRoZXkgYXJlIHNlbnQuCgkJICovCgkJdHhfc2tiLT5kYXRhWzFdIHw9IFBGX0JJVDsKCgkJc2VsZi0+dnMgPSAoc2VsZi0+dnMgKyAxKSAlIDg7CgkJc2VsZi0+YWNrX3JlcXVpcmVkID0gRkFMU0U7CgoJCWlybGFwX3NlbmRfaV9mcmFtZShzZWxmLCB0eF9za2IsIENNRF9GUkFNRSk7Cgl9IGVsc2UgewoJCUlSREFfREVCVUcoNCwgIiVzKCksIHNlbmRpbmcgdW5yZWxpYWJsZSBmcmFtZVxuIiwgX19GVU5DVElPTl9fKTsKCgkJaWYgKHNlbGYtPmFja19yZXF1aXJlZCkgewoJCQlpcmxhcF9zZW5kX3VpX2ZyYW1lKHNlbGYsIHNrYl9nZXQoc2tiKSwgc2VsZi0+Y2FkZHIsIENNRF9GUkFNRSk7CgkJCWlybGFwX3NlbmRfcnJfZnJhbWUoc2VsZiwgQ01EX0ZSQU1FKTsKCQkJc2VsZi0+YWNrX3JlcXVpcmVkID0gRkFMU0U7CgkJfSBlbHNlIHsKCQkJc2tiLT5kYXRhWzFdIHw9IFBGX0JJVDsKCQkJaXJsYXBfc2VuZF91aV9mcmFtZShzZWxmLCBza2JfZ2V0KHNrYiksIHNlbGYtPmNhZGRyLCBDTURfRlJBTUUpOwoJCX0KCX0KCgkvKiBIb3cgbXVjaCB0aW1lIHdlIHRvb2sgZm9yIHRyYW5zbWlzc2lvbiBvZiBhbGwgZnJhbWVzLgoJICogV2UgZG9uJ3Qga25vdywgc28gbGV0IGFzc3VtZSB3ZSB1c2VkIHRoZSBmdWxsIHdpbmRvdy4gSmVhbiBJSSAqLwoJdHJhbnNtaXNzaW9uX3RpbWUgPSBzZWxmLT5maW5hbF90aW1lb3V0OwoKCS8qIFJlc2V0IHBhcmFtZXRlciBzbyB0aGF0IHdlIGNhbiBmaWxsIG5leHQgd2luZG93ICovCglzZWxmLT53aW5kb3cgPSBzZWxmLT53aW5kb3dfc2l6ZTsKCiNpZmRlZiBDT05GSUdfSVJEQV9EWU5BTUlDX1dJTkRPVwoJLyogUmVtb3ZlIHdoYXQgd2UgaGF2ZSBub3QgdXNlZC4gSnVzdCBkbyBhIHByb3JhdGEgb2YgdGhlCgkgKiBieXRlcyBsZWZ0IGluIHdpbmRvdyB0byB3aW5kb3cgY2FwYWNpdHkuCgkgKiBTZWUgbWF4X2xpbmVfY2FwYWNpdGllc1tdW10gaW4gcW9zLmMgZm9yIGRldGFpbHMuIEplYW4gSUkgKi8KCXRyYW5zbWlzc2lvbl90aW1lIC09IChzZWxmLT5maW5hbF90aW1lb3V0ICogc2VsZi0+Ynl0ZXNfbGVmdAoJCQkgICAgICAvIHNlbGYtPmxpbmVfY2FwYWNpdHkpOwoJSVJEQV9ERUJVRyg0LCAiJXMoKSBhZGp1c3RpbmcgdHJhbnNtaXNzaW9uX3RpbWUgOiBmdD0lZCwgYmw9JWQsIGxjPSVkIC0+IHR0PSVkXG4iLCBfX0ZVTkNUSU9OX18sIHNlbGYtPmZpbmFsX3RpbWVvdXQsIHNlbGYtPmJ5dGVzX2xlZnQsIHNlbGYtPmxpbmVfY2FwYWNpdHksIHRyYW5zbWlzc2lvbl90aW1lKTsKCgkvKiBXZSBhcmUgYWxsb3dlZCB0byB0cmFuc21pdCBhIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIGFnYWluLiAqLwoJc2VsZi0+Ynl0ZXNfbGVmdCA9IHNlbGYtPmxpbmVfY2FwYWNpdHk7CiNlbmRpZiAvKiBDT05GSUdfSVJEQV9EWU5BTUlDX1dJTkRPVyAqLwoKCS8qCgkgKiBUaGUgbmV0d29yayBsYXllciBoYXMgYSBpbnRlcm1lZGlhdGUgYnVmZmVyIGJldHdlZW4gSXJMQVAKCSAqIGFuZCB0aGUgSXJEQSBkcml2ZXIgd2hpY2ggY2FuIGNvbnRhaW4gOCBmcmFtZXMuIFNvLCBldmVuCgkgKiB0aG91Z2ggSXJMQVAgaXMgY3VycmVudGx5IHNlbmRpbmcgdGhlICpsYXN0KiBmcmFtZSBvZiB0aGUKCSAqIHR4LXdpbmRvdywgdGhlIGRyaXZlciBtb3N0IGxpa2VseSBoYXMgb25seSBqdXN0IHN0YXJ0ZWQKCSAqIHNlbmRpbmcgdGhlICpmaXJzdCogZnJhbWUgb2YgdGhlIHNhbWUgdHgtd2luZG93LgoJICogSS5lLiB3ZSBhcmUgYWx3YXlzIGF0IHRoZSB2ZXJ5IGJlZ2luaW5nIG9mIG9yIFR4IHdpbmRvdy4KCSAqIE5vdywgd2UgYXJlIHN1cHBvc2VkIHRvIHNldCB0aGUgZmluYWwgdGltZXIgZnJvbSB0aGUgZW5kCgkgKiBvZiBvdXIgdHgtd2luZG93IHRvIGxldCB0aGUgb3RoZXIgcGVlciByZXBseS4gU28sIHdlIG5lZWQKCSAqIHRvIGFkZCBleHRyYSB0aW1lIHRvIGNvbXBlbnNhdGUgZm9yIHRoZSBmYWN0IHRoYXQgd2UKCSAqIGFyZSByZWFsbHkgYXQgdGhlIHN0YXJ0IG9mIHR4LXdpbmRvdywgb3RoZXJ3aXNlIHRoZSBmaW5hbCB0aW1lcgoJICogbWlnaHQgZXhwaXJlIGJlZm9yZSBoZSBjYW4gYW5zd2VyLi4uCgkgKiBKZWFuIElJCgkgKi8KCWlybGFwX3N0YXJ0X2ZpbmFsX3RpbWVyKHNlbGYsIHNlbGYtPmZpbmFsX3RpbWVvdXQgKyB0cmFuc21pc3Npb25fdGltZSk7CgoJLyoKCSAqIFRoZSBjbGV2ZXIgYW1vbmdzdCB5b3UgbWlnaHQgYXNrIHdoeSB3ZSBkbyB0aGlzIGFkanVzdGVtZW50CgkgKiBvbmx5IGhlcmUsIGFuZCBub3QgaW4gYWxsIHRoZSBvdGhlciBjYXNlcyBpbiBpcmxhcF9ldmVudC5jLgoJICogSW4gYWxsIHRob3NlIG90aGVyIGNhc2UsIHdlIG9ubHkgc2VuZCBhIHZlcnkgc2hvcnQgbWFuYWdlbWVudAoJICogZnJhbWUgKGZldyBieXRlcyksIHNvIHRoZSBhZGp1c3RlbWVudCB3b3VsZCBiZSBsb3N0IGluIHRoZQoJICogbm9pc2UuLi4KCSAqIFRoZSBleGNlcHRpb24gb2YgY291cnNlIGlzIGlybGFwX3Jlc2VuZF9yZWplY3RlZF9mcmFtZSgpLgoJICogSmVhbiBJSSAqLwp9CgovKgogKiBGdW5jdGlvbiBpcmxhcF9zZW5kX2RhdGFfc2Vjb25kYXJ5X2ZpbmFsIChzZWxmLCBza2IpCiAqCiAqICAgIFNlbmQgSShuZm9ybWF0aW9uKSBmcmFtZSBhcyBzZWNvbmRhcnkgd2l0aCBmaW5hbCBiaXQgc2V0CiAqCiAqLwp2b2lkIGlybGFwX3NlbmRfZGF0YV9zZWNvbmRhcnlfZmluYWwoc3RydWN0IGlybGFwX2NiICpzZWxmLAoJCQkJICAgICBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CglzdHJ1Y3Qgc2tfYnVmZiAqdHhfc2tiID0gTlVMTDsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gTEFQX01BR0lDLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNrYiAhPSBOVUxMLCByZXR1cm47KTsKCgkvKiBJcyB0aGlzIHJlbGlhYmxlIG9yIHVucmVsaWFibGUgZGF0YT8gKi8KCWlmIChza2ItPmRhdGFbMV0gPT0gSV9GUkFNRSkgewoKCQkvKgoJCSAqICBJbnNlcnQgZnJhbWUgc2VxdWVuY2UgbnVtYmVyIChWcykgaW4gY29udHJvbCBmaWVsZCBiZWZvcmUKCQkgKiAgaW5zZXJ0aW5nIGludG8gdHJhbnNtaXQgd2luZG93IHF1ZXVlLgoJCSAqLwoJCXNrYi0+ZGF0YVsxXSA9IElfRlJBTUUgfCAoc2VsZi0+dnMgPDwgMSk7CgoJCS8qCgkJICogIEluc2VydCBmcmFtZSBpbiBzdG9yZSwgaW4gY2FzZSBvZiByZXRyYW5zbWlzc2lvbnMKCQkgKiAgSW5jcmVhc2Ugc2tiIHJlZmVyZW5jZSBjb3VudCwgc2VlIGlybGFwX2RvX2V2ZW50KCkKCQkgKi8KCQlza2JfZ2V0KHNrYik7CgkJc2tiX3F1ZXVlX3RhaWwoJnNlbGYtPnd4X2xpc3QsIHNrYik7CgoJCXR4X3NrYiA9IHNrYl9jbG9uZShza2IsIEdGUF9BVE9NSUMpOwoJCWlmICh0eF9za2IgPT0gTlVMTCkgewoJCQlyZXR1cm47CgkJfQoKCQl0eF9za2ItPmRhdGFbMV0gfD0gUEZfQklUOwoKCQlzZWxmLT52cyA9IChzZWxmLT52cyArIDEpICUgODsKCQlzZWxmLT5hY2tfcmVxdWlyZWQgPSBGQUxTRTsKCgkJaXJsYXBfc2VuZF9pX2ZyYW1lKHNlbGYsIHR4X3NrYiwgUlNQX0ZSQU1FKTsKCX0gZWxzZSB7CgkJaWYgKHNlbGYtPmFja19yZXF1aXJlZCkgewoJCQlpcmxhcF9zZW5kX3VpX2ZyYW1lKHNlbGYsIHNrYl9nZXQoc2tiKSwgc2VsZi0+Y2FkZHIsIFJTUF9GUkFNRSk7CgkJCWlybGFwX3NlbmRfcnJfZnJhbWUoc2VsZiwgUlNQX0ZSQU1FKTsKCQkJc2VsZi0+YWNrX3JlcXVpcmVkID0gRkFMU0U7CgkJfSBlbHNlIHsKCQkJc2tiLT5kYXRhWzFdIHw9IFBGX0JJVDsKCQkJaXJsYXBfc2VuZF91aV9mcmFtZShzZWxmLCBza2JfZ2V0KHNrYiksIHNlbGYtPmNhZGRyLCBSU1BfRlJBTUUpOwoJCX0KCX0KCglzZWxmLT53aW5kb3cgPSBzZWxmLT53aW5kb3dfc2l6ZTsKI2lmZGVmIENPTkZJR19JUkRBX0RZTkFNSUNfV0lORE9XCgkvKiBXZSBhcmUgYWxsb3dlZCB0byB0cmFuc21pdCBhIG1heGltdW0gbnVtYmVyIG9mIGJ5dGVzIGFnYWluLiAqLwoJc2VsZi0+Ynl0ZXNfbGVmdCA9IHNlbGYtPmxpbmVfY2FwYWNpdHk7CiNlbmRpZiAvKiBDT05GSUdfSVJEQV9EWU5BTUlDX1dJTkRPVyAqLwoKCWlybGFwX3N0YXJ0X3dkX3RpbWVyKHNlbGYsIHNlbGYtPndkX3RpbWVvdXQpOwp9CgovKgogKiBGdW5jdGlvbiBpcmxhcF9zZW5kX2RhdGFfc2Vjb25kYXJ5IChzZWxmLCBza2IpCiAqCiAqICAgIFNlbmQgSShuZm9ybWF0aW9uKSBmcmFtZSBhcyBzZWNvbmRhcnkgd2l0aG91dCBmaW5hbCBiaXQgc2V0CiAqCiAqLwp2b2lkIGlybGFwX3NlbmRfZGF0YV9zZWNvbmRhcnkoc3RydWN0IGlybGFwX2NiICpzZWxmLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiKQp7CglzdHJ1Y3Qgc2tfYnVmZiAqdHhfc2tiID0gTlVMTDsKCgkvKiBJcyB0aGlzIHJlbGlhYmxlIG9yIHVucmVsaWFibGUgZGF0YT8gKi8KCWlmIChza2ItPmRhdGFbMV0gPT0gSV9GUkFNRSkgewoKCQkvKgoJCSAqICBJbnNlcnQgZnJhbWUgc2VxdWVuY2UgbnVtYmVyIChWcykgaW4gY29udHJvbCBmaWVsZCBiZWZvcmUKCQkgKiAgaW5zZXJ0aW5nIGludG8gdHJhbnNtaXQgd2luZG93IHF1ZXVlLgoJCSAqLwoJCXNrYi0+ZGF0YVsxXSA9IElfRlJBTUUgfCAoc2VsZi0+dnMgPDwgMSk7CgoJCS8qCgkJICogIEluc2VydCBmcmFtZSBpbiBzdG9yZSwgaW4gY2FzZSBvZiByZXRyYW5zbWlzc2lvbnMKCQkgKiAgSW5jcmVhc2Ugc2tiIHJlZmVyZW5jZSBjb3VudCwgc2VlIGlybGFwX2RvX2V2ZW50KCkKCQkgKi8KCQlza2JfZ2V0KHNrYik7CgkJc2tiX3F1ZXVlX3RhaWwoJnNlbGYtPnd4X2xpc3QsIHNrYik7CgoJCXR4X3NrYiA9IHNrYl9jbG9uZShza2IsIEdGUF9BVE9NSUMpOwoJCWlmICh0eF9za2IgPT0gTlVMTCkgewoJCQlyZXR1cm47CgkJfQoKCQlzZWxmLT52cyA9IChzZWxmLT52cyArIDEpICUgODsKCQlzZWxmLT5hY2tfcmVxdWlyZWQgPSBGQUxTRTsKCQlzZWxmLT53aW5kb3cgLT0gMTsKCgkJaXJsYXBfc2VuZF9pX2ZyYW1lKHNlbGYsIHR4X3NrYiwgUlNQX0ZSQU1FKTsKCX0gZWxzZSB7CgkJaXJsYXBfc2VuZF91aV9mcmFtZShzZWxmLCBza2JfZ2V0KHNrYiksIHNlbGYtPmNhZGRyLCBSU1BfRlJBTUUpOwoJCXNlbGYtPndpbmRvdyAtPSAxOwoJfQp9CgovKgogKiBGdW5jdGlvbiBpcmxhcF9yZXNlbmRfcmVqZWN0ZWRfZnJhbWVzIChucikKICoKICogICAgUmVzZW5kIGZyYW1lcyB3aGljaCBoYXMgbm90IGJlZW4gYWNrbm93bGVkZ2VkLiBTaG91bGQgYmUgc2FmZSB0bwogKiAgICB0cmF2ZXJzZSB0aGUgbGlzdCB3aXRob3V0IGxvY2tpbmcgaXQgc2luY2UgdGhpcyBmdW5jdGlvbiB3aWxsIG9ubHkgYmUKICogICAgY2FsbGVkIGZyb20gaW50ZXJydXB0IGNvbnRleHQgKEJIKQogKi8Kdm9pZCBpcmxhcF9yZXNlbmRfcmVqZWN0ZWRfZnJhbWVzKHN0cnVjdCBpcmxhcF9jYiAqc2VsZiwgaW50IGNvbW1hbmQpCnsKCXN0cnVjdCBza19idWZmICp0eF9za2I7CglzdHJ1Y3Qgc2tfYnVmZiAqc2tiOwoJaW50IGNvdW50OwoKCUlSREFfQVNTRVJUKHNlbGYgIT0gTlVMTCwgcmV0dXJuOyk7CglJUkRBX0FTU0VSVChzZWxmLT5tYWdpYyA9PSBMQVBfTUFHSUMsIHJldHVybjspOwoKCS8qIEluaXRpYWxpemUgdmFyaWFibGVzICovCgljb3VudCA9IHNrYl9xdWV1ZV9sZW4oJnNlbGYtPnd4X2xpc3QpOwoKCS8qICBSZXNlbmQgdW5hY2tub3dsZWRnZWQgZnJhbWUocykgKi8KCXNrYiA9IHNrYl9wZWVrKCZzZWxmLT53eF9saXN0KTsKCXdoaWxlIChza2IgIT0gTlVMTCkgewoJCWlybGFwX3dhaXRfbWluX3R1cm5fYXJvdW5kKHNlbGYsICZzZWxmLT5xb3NfdHgpOwoKCQkvKiBXZSBjb3B5IHRoZSBza2IgdG8gYmUgcmV0cmFuc21pdHRlZCBzaW5jZSB3ZSB3aWxsIGhhdmUgdG8KCQkgKiBtb2RpZnkgaXQuIENsb25pbmcgd2lsbCBjb25mdXNlIHBhY2tldCBzbmlmZmVycwoJCSAqLwoJCS8qIHR4X3NrYiA9IHNrYl9jbG9uZSggc2tiLCBHRlBfQVRPTUlDKTsgKi8KCQl0eF9za2IgPSBza2JfY29weShza2IsIEdGUF9BVE9NSUMpOwoJCWlmICghdHhfc2tiKSB7CgkJCUlSREFfREVCVUcoMCwgIiVzKCksIHVuYWJsZSB0byBjb3B5XG4iLCBfX0ZVTkNUSU9OX18pOwoJCQlyZXR1cm47CgkJfQoKCQkvKiBDbGVhciBvbGQgTnIgZmllbGQgKyBwb2xsIGJpdCAqLwoJCXR4X3NrYi0+ZGF0YVsxXSAmPSAweDBmOwoKCQkvKgoJCSAqICBTZXQgcG9sbCBiaXQgb24gdGhlIGxhc3QgZnJhbWUgcmV0cmFuc21pdHRlZAoJCSAqLwoJCWlmIChjb3VudC0tID09IDEpCgkJCXR4X3NrYi0+ZGF0YVsxXSB8PSBQRl9CSVQ7IC8qIFNldCBwL2YgYml0ICovCgkJZWxzZQoJCQl0eF9za2ItPmRhdGFbMV0gJj0gflBGX0JJVDsgLyogQ2xlYXIgcC9mIGJpdCAqLwoKCQlpcmxhcF9zZW5kX2lfZnJhbWUoc2VsZiwgdHhfc2tiLCBjb21tYW5kKTsKCgkJLyoKCQkgKiAgSWYgb3VyIHNrYiBpcyB0aGUgbGFzdCBidWZmZXIgaW4gdGhlIGxpc3QsIHRoZW4KCQkgKiAgd2UgYXJlIGZpbmlzaGVkLCBpZiBub3QsIG1vdmUgdG8gdGhlIG5leHQgc2stYnVmZmVyCgkJICovCgkJaWYgKHNrYiA9PSBza2JfcGVla190YWlsKCZzZWxmLT53eF9saXN0KSkKCQkJc2tiID0gTlVMTDsKCQllbHNlCgkJCXNrYiA9IHNrYi0+bmV4dDsKCX0KI2lmIDAgLyogTm90IHlldCAqLwoJLyoKCSAqICBXZSBjYW4gbm93IGZpbGwgdGhlIHdpbmRvdyB3aXRoIGFkZGl0aW9uYWwgZGF0YSBmcmFtZXMKCSAqLwoJd2hpbGUgKCFza2JfcXVldWVfZW1wdHkoJnNlbGYtPnR4cSkpIHsKCgkJSVJEQV9ERUJVRygwLCAiJXMoKSwgc2VuZGluZyBhZGRpdGlvbmFsIGZyYW1lcyFcbiIsIF9fRlVOQ1RJT05fXyk7CgkJaWYgKHNlbGYtPndpbmRvdyA+IDApIHsKCQkJc2tiID0gc2tiX2RlcXVldWUoICZzZWxmLT50eHEpOwoJCQlJUkRBX0FTU0VSVChza2IgIT0gTlVMTCwgcmV0dXJuOyk7CgoJCQkvKgoJCQkgKiAgSWYgc2VuZCB3aW5kb3cgPiAxIHRoZW4gc2VuZCBmcmFtZSB3aXRoIHBmCgkJCSAqICBiaXQgY2xlYXJlZAoJCQkgKi8KCQkJaWYgKChzZWxmLT53aW5kb3cgPiAxKSAmJgoJCQkgICAgIXNrYl9xdWV1ZV9lbXB0eSgmc2VsZi0+dHhxKSkgewoJCQkJaXJsYXBfc2VuZF9kYXRhX3ByaW1hcnkoc2VsZiwgc2tiKTsKCQkJfSBlbHNlIHsKCQkJCWlybGFwX3NlbmRfZGF0YV9wcmltYXJ5X3BvbGwoc2VsZiwgc2tiKTsKCQkJfQoJCQlrZnJlZV9za2Ioc2tiKTsKCQl9Cgl9CiNlbmRpZgp9Cgp2b2lkIGlybGFwX3Jlc2VuZF9yZWplY3RlZF9mcmFtZShzdHJ1Y3QgaXJsYXBfY2IgKnNlbGYsIGludCBjb21tYW5kKQp7CglzdHJ1Y3Qgc2tfYnVmZiAqdHhfc2tiOwoJc3RydWN0IHNrX2J1ZmYgKnNrYjsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gTEFQX01BR0lDLCByZXR1cm47KTsKCgkvKiAgUmVzZW5kIHVuYWNrbm93bGVkZ2VkIGZyYW1lKHMpICovCglza2IgPSBza2JfcGVlaygmc2VsZi0+d3hfbGlzdCk7CglpZiAoc2tiICE9IE5VTEwpIHsKCQlpcmxhcF93YWl0X21pbl90dXJuX2Fyb3VuZChzZWxmLCAmc2VsZi0+cW9zX3R4KTsKCgkJLyogV2UgY29weSB0aGUgc2tiIHRvIGJlIHJldHJhbnNtaXR0ZWQgc2luY2Ugd2Ugd2lsbCBoYXZlIHRvCgkJICogbW9kaWZ5IGl0LiBDbG9uaW5nIHdpbGwgY29uZnVzZSBwYWNrZXQgc25pZmZlcnMKCQkgKi8KCQkvKiB0eF9za2IgPSBza2JfY2xvbmUoIHNrYiwgR0ZQX0FUT01JQyk7ICovCgkJdHhfc2tiID0gc2tiX2NvcHkoc2tiLCBHRlBfQVRPTUlDKTsKCQlpZiAoIXR4X3NrYikgewoJCQlJUkRBX0RFQlVHKDAsICIlcygpLCB1bmFibGUgdG8gY29weVxuIiwgX19GVU5DVElPTl9fKTsKCQkJcmV0dXJuOwoJCX0KCgkJLyogQ2xlYXIgb2xkIE5yIGZpZWxkICsgcG9sbCBiaXQgKi8KCQl0eF9za2ItPmRhdGFbMV0gJj0gMHgwZjsKCgkJLyogIFNldCBwb2xsL2ZpbmFsIGJpdCAqLwoJCXR4X3NrYi0+ZGF0YVsxXSB8PSBQRl9CSVQ7IC8qIFNldCBwL2YgYml0ICovCgoJCWlybGFwX3NlbmRfaV9mcmFtZShzZWxmLCB0eF9za2IsIGNvbW1hbmQpOwoJfQp9CgovKgogKiBGdW5jdGlvbiBpcmxhcF9zZW5kX3VpX2ZyYW1lIChzZWxmLCBza2IsIGNvbW1hbmQpCiAqCiAqICAgIENvbnRydWN0IGFuZCB0cmFuc21pdCBhbiBVbm51bWJlcmVkIEluZm9ybWF0aW9uIChVSSkgZnJhbWUKICoKICovCnZvaWQgaXJsYXBfc2VuZF91aV9mcmFtZShzdHJ1Y3QgaXJsYXBfY2IgKnNlbGYsIHN0cnVjdCBza19idWZmICpza2IsCgkJCSBfX3U4IGNhZGRyLCBpbnQgY29tbWFuZCkKewoJSVJEQV9ERUJVRyg0LCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gTEFQX01BR0lDLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNrYiAhPSBOVUxMLCByZXR1cm47KTsKCgkvKiBJbnNlcnQgY29ubmVjdGlvbiBhZGRyZXNzICovCglza2ItPmRhdGFbMF0gPSBjYWRkciB8ICgoY29tbWFuZCkgPyBDTURfRlJBTUUgOiAwKTsKCglpcmxhcF9xdWV1ZV94bWl0KHNlbGYsIHNrYik7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlybGFwX3NlbmRfaV9mcmFtZSAoc2tiKQogKgogKiAgICBDb250cnVjdCBhbmQgdHJhbnNtaXQgSW5mb3JtYXRpb24gKEkpIGZyYW1lCiAqLwpzdGF0aWMgdm9pZCBpcmxhcF9zZW5kX2lfZnJhbWUoc3RydWN0IGlybGFwX2NiICpzZWxmLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiLAoJCQkgICAgICAgaW50IGNvbW1hbmQpCnsKCS8qIEluc2VydCBjb25uZWN0aW9uIGFkZHJlc3MgKi8KCXNrYi0+ZGF0YVswXSA9IHNlbGYtPmNhZGRyOwoJc2tiLT5kYXRhWzBdIHw9IChjb21tYW5kKSA/IENNRF9GUkFNRSA6IDA7CgoJLyogSW5zZXJ0IG5leHQgdG8gcmVjZWl2ZSAoVnIpICovCglza2ItPmRhdGFbMV0gfD0gKHNlbGYtPnZyIDw8IDUpOyAgLyogaW5zZXJ0IG5yICovCgoJaXJsYXBfcXVldWVfeG1pdChzZWxmLCBza2IpOwp9CgovKgogKiBGdW5jdGlvbiBpcmxhcF9yZWN2X2lfZnJhbWUgKHNrYiwgZnJhbWUpCiAqCiAqICAgIFJlY2VpdmUgYW5kIHBhcnNlIGFuIEkgKEluZm9ybWF0aW9uKSBmcmFtZSwgbm8gaGFybSBpbiBtYWtpbmcgaXQgaW5saW5lCiAqICAgIHNpbmNlIGl0J3MgY2FsbGVkIG9ubHkgZnJvbSBvbmUgc2luZ2xlIHBsYWNlIChpcmxhcF9kcml2ZXJfcmN2KS4KICovCnN0YXRpYyBpbmxpbmUgdm9pZCBpcmxhcF9yZWN2X2lfZnJhbWUoc3RydWN0IGlybGFwX2NiICpzZWxmLAoJCQkJICAgICAgc3RydWN0IHNrX2J1ZmYgKnNrYiwKCQkJCSAgICAgIHN0cnVjdCBpcmxhcF9pbmZvICppbmZvLCBpbnQgY29tbWFuZCkKewoJaW5mby0+bnIgPSBza2ItPmRhdGFbMV0gPj4gNTsgICAgICAgICAgLyogTmV4dCB0byByZWNlaXZlICovCglpbmZvLT5wZiA9IHNrYi0+ZGF0YVsxXSAmIFBGX0JJVDsgICAgICAvKiBGaW5hbCBiaXQgKi8KCWluZm8tPm5zID0gKHNrYi0+ZGF0YVsxXSA+PiAxKSAmIDB4MDc7IC8qIE5leHQgdG8gc2VuZCAqLwoKCS8qIENoZWNrIGlmIHRoaXMgaXMgYSBjb21tYW5kIG9yIGEgcmVzcG9uc2UgZnJhbWUgKi8KCWlmIChjb21tYW5kKQoJCWlybGFwX2RvX2V2ZW50KHNlbGYsIFJFQ1ZfSV9DTUQsIHNrYiwgaW5mbyk7CgllbHNlCgkJaXJsYXBfZG9fZXZlbnQoc2VsZiwgUkVDVl9JX1JTUCwgc2tiLCBpbmZvKTsKfQoKLyoKICogRnVuY3Rpb24gaXJsYXBfcmVjdl91aV9mcmFtZSAoc2VsZiwgc2tiLCBpbmZvKQogKgogKiAgICBSZWNlaXZlIGFuZCBwYXJzZSBhbiBVbm51bWJlcmVkIEluZm9ybWF0aW9uIChVSSkgZnJhbWUKICoKICovCnN0YXRpYyB2b2lkIGlybGFwX3JlY3ZfdWlfZnJhbWUoc3RydWN0IGlybGFwX2NiICpzZWxmLCBzdHJ1Y3Qgc2tfYnVmZiAqc2tiLAoJCQkJc3RydWN0IGlybGFwX2luZm8gKmluZm8pCnsKCUlSREFfREVCVUcoIDQsICIlcygpXG4iLCBfX0ZVTkNUSU9OX18pOwoKCWluZm8tPnBmID0gc2tiLT5kYXRhWzFdICYgUEZfQklUOyAgICAgIC8qIEZpbmFsIGJpdCAqLwoKCWlybGFwX2RvX2V2ZW50KHNlbGYsIFJFQ1ZfVUlfRlJBTUUsIHNrYiwgaW5mbyk7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlybGFwX3JlY3ZfZnJtcl9mcmFtZSAoc2tiLCBmcmFtZSkKICoKICogICAgUmVjZWl2ZWQgRnJhbWUgUmVqZWN0IHJlc3BvbnNlLgogKgogKi8Kc3RhdGljIHZvaWQgaXJsYXBfcmVjdl9mcm1yX2ZyYW1lKHN0cnVjdCBpcmxhcF9jYiAqc2VsZiwgc3RydWN0IHNrX2J1ZmYgKnNrYiwKCQkJCSAgc3RydWN0IGlybGFwX2luZm8gKmluZm8pCnsKCV9fdTggKmZyYW1lOwoJaW50IHcsIHgsIHksIHo7CgoJSVJEQV9ERUJVRygwLCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglJUkRBX0FTU0VSVChzZWxmICE9IE5VTEwsIHJldHVybjspOwoJSVJEQV9BU1NFUlQoc2VsZi0+bWFnaWMgPT0gTEFQX01BR0lDLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKHNrYiAhPSBOVUxMLCByZXR1cm47KTsKCUlSREFfQVNTRVJUKGluZm8gIT0gTlVMTCwgcmV0dXJuOyk7CgoJaWYgKCFwc2tiX21heV9wdWxsKHNrYiwgNCkpIHsKCQlJUkRBX0VSUk9SKCIlczogZnJhbWUgdG9vIHNob3J0IVxuIiwgX19GVU5DVElPTl9fKTsKCQlyZXR1cm47Cgl9CgoJZnJhbWUgPSBza2ItPmRhdGE7CgoJaW5mby0+bnIgPSBmcmFtZVsyXSA+PiA1OyAgICAgICAgICAvKiBOZXh0IHRvIHJlY2VpdmUgKi8KCWluZm8tPnBmID0gZnJhbWVbMl0gJiBQRl9CSVQ7ICAgICAgLyogRmluYWwgYml0ICovCglpbmZvLT5ucyA9IChmcmFtZVsyXSA+PiAxKSAmIDB4MDc7IC8qIE5leHQgdG8gc2VuZCAqLwoKCXcgPSBmcmFtZVszXSAmIDB4MDE7Cgl4ID0gZnJhbWVbM10gJiAweDAyOwoJeSA9IGZyYW1lWzNdICYgMHgwNDsKCXogPSBmcmFtZVszXSAmIDB4MDg7CgoJaWYgKHcpIHsKCQlJUkRBX0RFQlVHKDAsICJSZWplY3RlZCBjb250cm9sIGZpZWxkIGlzIHVuZGVmaW5lZCBvciBub3QgIgoJCSAgICAgICJpbXBsZW1lbnRlZC5cbiIpOwoJfQoJaWYgKHgpIHsKCQlJUkRBX0RFQlVHKDAsICJSZWplY3RlZCBjb250cm9sIGZpZWxkIHdhcyBpbnZhbGlkIGJlY2F1c2UgaXQgIgoJCSAgICAgICJjb250YWluZWQgYSBub24gcGVybWl0dGVkIEkgZmllbGQuXG4iKTsKCX0KCWlmICh5KSB7CgkJSVJEQV9ERUJVRygwLCAiUmVjZWl2ZWQgSSBmaWVsZCBleGNlZWRlZCB0aGUgbWF4aW11bSBuZWdvdGlhdGVkICIKCQkgICAgICAiZm9yIHRoZSBleGlzdGluZyBjb25uZWN0aW9uIG9yIGV4Y2VlZGVkIHRoZSBtYXhpbXVtICIKCQkgICAgICAidGhpcyBzdGF0aW9uIHN1cHBvcnRzIGlmIG5vIGNvbm5lY3Rpb24gZXhpc3RzLlxuIik7Cgl9CglpZiAoeikgewoJCUlSREFfREVCVUcoMCwgIlJlamVjdGVkIGNvbnRyb2wgZmllbGQgY29udHJvbCBmaWVsZCBjb250YWluZWQgYW4gIgoJCSAgICAgICJpbnZhbGlkIE5yIGNvdW50LlxuIik7Cgl9CglpcmxhcF9kb19ldmVudChzZWxmLCBSRUNWX0ZSTVJfUlNQLCBza2IsIGluZm8pOwp9CgovKgogKiBGdW5jdGlvbiBpcmxhcF9zZW5kX3Rlc3RfZnJhbWUgKHNlbGYsIGRhZGRyKQogKgogKiAgICBTZW5kIGEgdGVzdCBmcmFtZSByZXNwb25zZQogKgogKi8Kdm9pZCBpcmxhcF9zZW5kX3Rlc3RfZnJhbWUoc3RydWN0IGlybGFwX2NiICpzZWxmLCBfX3U4IGNhZGRyLCBfX3UzMiBkYWRkciwKCQkJICAgc3RydWN0IHNrX2J1ZmYgKmNtZCkKewoJc3RydWN0IHNrX2J1ZmYgKnR4X3NrYjsKCXN0cnVjdCB0ZXN0X2ZyYW1lICpmcmFtZTsKCV9fdTggKmluZm87CgoJdHhfc2tiID0gYWxsb2Nfc2tiKGNtZC0+bGVuICsgc2l6ZW9mKHN0cnVjdCB0ZXN0X2ZyYW1lKSwgR0ZQX0FUT01JQyk7CglpZiAoIXR4X3NrYikKCQlyZXR1cm47CgoJLyogQnJvYWRjYXN0IGZyYW1lcyBtdXN0IGluY2x1ZGUgc2FkZHIgYW5kIGRhZGRyIGZpZWxkcyAqLwoJaWYgKGNhZGRyID09IENCUk9BRENBU1QpIHsKCQlmcmFtZSA9IChzdHJ1Y3QgdGVzdF9mcmFtZSAqKQoJCQlza2JfcHV0KHR4X3NrYiwgc2l6ZW9mKHN0cnVjdCB0ZXN0X2ZyYW1lKSk7CgoJCS8qIEluc2VydCB0aGUgc3dhcHBlZCBhZGRyZXNzZXMgKi8KCQlmcmFtZS0+c2FkZHIgPSBjcHVfdG9fbGUzMihzZWxmLT5zYWRkcik7CgkJZnJhbWUtPmRhZGRyID0gY3B1X3RvX2xlMzIoZGFkZHIpOwoJfSBlbHNlCgkJZnJhbWUgPSAoc3RydWN0IHRlc3RfZnJhbWUgKikgc2tiX3B1dCh0eF9za2IsIExBUF9BRERSX0hFQURFUiArIExBUF9DVFJMX0hFQURFUik7CgoJZnJhbWUtPmNhZGRyID0gY2FkZHI7CglmcmFtZS0+Y29udHJvbCA9IFRFU1RfUlNQIHwgUEZfQklUOwoKCS8qIENvcHkgaW5mbyAqLwoJaW5mbyA9IHNrYl9wdXQodHhfc2tiLCBjbWQtPmxlbik7CgltZW1jcHkoaW5mbywgY21kLT5kYXRhLCBjbWQtPmxlbik7CgoJLyogUmV0dXJuIHRvIHNlbmRlciAqLwoJaXJsYXBfd2FpdF9taW5fdHVybl9hcm91bmQoc2VsZiwgJnNlbGYtPnFvc190eCk7CglpcmxhcF9xdWV1ZV94bWl0KHNlbGYsIHR4X3NrYik7Cn0KCi8qCiAqIEZ1bmN0aW9uIGlybGFwX3JlY3ZfdGVzdF9mcmFtZSAoc2VsZiwgc2tiKQogKgogKiAgICBSZWNlaXZlIGEgdGVzdCBmcmFtZQogKgogKi8Kc3RhdGljIHZvaWQgaXJsYXBfcmVjdl90ZXN0X2ZyYW1lKHN0cnVjdCBpcmxhcF9jYiAqc2VsZiwgc3RydWN0IHNrX2J1ZmYgKnNrYiwKCQkJCSAgc3RydWN0IGlybGFwX2luZm8gKmluZm8sIGludCBjb21tYW5kKQp7CglzdHJ1Y3QgdGVzdF9mcmFtZSAqZnJhbWU7CgoJSVJEQV9ERUJVRygyLCAiJXMoKVxuIiwgX19GVU5DVElPTl9fKTsKCglpZiAoIXBza2JfbWF5X3B1bGwoc2tiLCBzaXplb2YoKmZyYW1lKSkpIHsKCQlJUkRBX0VSUk9SKCIlczogZnJhbWUgdG9vIHNob3J0IVxuIiwgX19GVU5DVElPTl9fKTsKCQlyZXR1cm47Cgl9CglmcmFtZSA9IChzdHJ1Y3QgdGVzdF9mcmFtZSAqKSBza2ItPmRhdGE7CgoJLyogQnJvYWRjYXN0IGZyYW1lcyBtdXN0IGNhcnJ5IHNhZGRyIGFuZCBkYWRkciBmaWVsZHMgKi8KCWlmIChpbmZvLT5jYWRkciA9PSBDQlJPQURDQVNUKSB7CgkJaWYgKHNrYi0+bGVuIDwgc2l6ZW9mKHN0cnVjdCB0ZXN0X2ZyYW1lKSkgewoJCQlJUkRBX0RFQlVHKDAsICIlcygpIHRlc3QgZnJhbWUgdG9vIHNob3J0IVxuIiwKCQkJCSAgIF9fRlVOQ1RJT05fXyk7CgkJCXJldHVybjsKCQl9CgoJCS8qIFJlYWQgYW5kIHN3YXAgYWRkcmVzc2VzICovCgkJaW5mby0+ZGFkZHIgPSBsZTMyX3RvX2NwdShmcmFtZS0+c2FkZHIpOwoJCWluZm8tPnNhZGRyID0gbGUzMl90b19jcHUoZnJhbWUtPmRhZGRyKTsKCgkJLyogTWFrZSBzdXJlIGZyYW1lIGlzIGFkZHJlc3NlZCB0byB1cyAqLwoJCWlmICgoaW5mby0+c2FkZHIgIT0gc2VsZi0+c2FkZHIpICYmCgkJICAgIChpbmZvLT5zYWRkciAhPSBCUk9BRENBU1QpKSB7CgkJCXJldHVybjsKCQl9Cgl9CgoJaWYgKGNvbW1hbmQpCgkJaXJsYXBfZG9fZXZlbnQoc2VsZiwgUkVDVl9URVNUX0NNRCwgc2tiLCBpbmZvKTsKCWVsc2UKCQlpcmxhcF9kb19ldmVudChzZWxmLCBSRUNWX1RFU1RfUlNQLCBza2IsIGluZm8pOwp9CgovKgogKiBGdW5jdGlvbiBpcmxhcF9kcml2ZXJfcmN2IChza2IsIG5ldGRldiwgcHR5cGUpCiAqCiAqICAgIENhbGxlZCB3aGVuIGEgZnJhbWUgaXMgcmVjZWl2ZWQuIERpc3BhdGNoZXMgdGhlIHJpZ2h0IHJlY2VpdmUgZnVuY3Rpb24KICogICAgZm9yIHByb2Nlc3Npbmcgb2YgdGhlIGZyYW1lLgogKgogKiBOb3RlIG9uIHNrYiBtYW5hZ2VtZW50IDoKICogQWZ0ZXIgY2FsbGluZyB0aGUgaGlnaGVyIGxheWVycyBvZiB0aGUgSXJEQSBzdGFjaywgd2UgYWx3YXlzCiAqIGtmcmVlKCkgdGhlIHNrYiwgd2hpY2ggZHJvcCB0aGUgcmVmZXJlbmNlIGNvdW50IChhbmQgcG90ZW50aWFsbHkKICogZGVzdHJveSBpdCkuCiAqIElmIGEgaGlnaGVyIGxheWVyIG9mIHRoZSBzdGFjayB3YW50IHRvIGtlZXAgdGhlIHNrYiBhcm91bmQgKHRvIHB1dAogKiBpbiBhIHF1ZXVlIG9yIHBhc3MgaXQgdG8gdGhlIGhpZ2hlciBsYXllciksIGl0IHdpbGwgbmVlZCB0byB1c2UKICogc2tiX2dldCgpIHRvIGtlZXAgYSByZWZlcmVuY2Ugb24gaXQuIFRoaXMgaXMgdXN1YWxseSBkb25lIGF0IHRoZQogKiBMTVAgbGV2ZWwgaW4gaXJsbXAuYy4KICogSmVhbiBJSQogKi8KaW50IGlybGFwX2RyaXZlcl9yY3Yoc3RydWN0IHNrX2J1ZmYgKnNrYiwgc3RydWN0IG5ldF9kZXZpY2UgKmRldiwKCQkgICAgIHN0cnVjdCBwYWNrZXRfdHlwZSAqcHR5cGUsIHN0cnVjdCBuZXRfZGV2aWNlICpvcmlnX2RldikKewoJc3RydWN0IGlybGFwX2luZm8gaW5mbzsKCXN0cnVjdCBpcmxhcF9jYiAqc2VsZjsKCWludCBjb21tYW5kOwoJX191OCBjb250cm9sOwoKCS8qIEZJWE1FOiBzaG91bGQgd2UgZ2V0IG91ciBvd24gZmllbGQ/ICovCglzZWxmID0gKHN0cnVjdCBpcmxhcF9jYiAqKSBkZXYtPmF0YWxrX3B0cjsKCgkvKiBJZiB0aGUgbmV0IGRldmljZSBpcyBkb3duLCB0aGVuIElyTEFQIGlzIGdvbmUhICovCglpZiAoIXNlbGYgfHwgc2VsZi0+bWFnaWMgIT0gTEFQX01BR0lDKSB7CgkJZGV2X2tmcmVlX3NrYihza2IpOwoJCXJldHVybiAtMTsKCX0KCgkvKiBXZSBhcmUgbm8gbG9uZ2VyIGFuICJvbGQiIHByb3RvY29sLCBzbyB3ZSBuZWVkIHRvIGhhbmRsZQoJICogc2hhcmUgYW5kIG5vbiBsaW5lYXIgc2ticy4gVGhpcyBzaG91bGQgbmV2ZXIgaGFwcGVuLCBzbwoJICogd2UgZG9uJ3QgbmVlZCB0byBiZSBjbGV2ZXIgYWJvdXQgaXQuIEplYW4gSUkgKi8KCWlmICgoc2tiID0gc2tiX3NoYXJlX2NoZWNrKHNrYiwgR0ZQX0FUT01JQykpID09IE5VTEwpIHsKCQlJUkRBX0VSUk9SKCIlczogY2FuJ3QgY2xvbmUgc2hhcmVkIHNrYiFcbiIsIF9fRlVOQ1RJT05fXyk7CgkJZGV2X2tmcmVlX3NrYihza2IpOwoJCXJldHVybiAtMTsKCX0KCgkvKiBDaGVjayBpZiBmcmFtZSBpcyBsYXJnZSBlbm91Z2ggZm9yIHBhcnNpbmcgKi8KCWlmICghcHNrYl9tYXlfcHVsbChza2IsIDIpKSB7CgkJSVJEQV9FUlJPUigiJXM6IGZyYW1lIHRvbyBzaG9ydCFcbiIsIF9fRlVOQ1RJT05fXyk7CgkJZGV2X2tmcmVlX3NrYihza2IpOwoJCXJldHVybiAtMTsKCX0KCgljb21tYW5kICAgID0gc2tiLT5kYXRhWzBdICYgQ01EX0ZSQU1FOwoJaW5mby5jYWRkciA9IHNrYi0+ZGF0YVswXSAmIENCUk9BRENBU1Q7CgoJaW5mby5wZiAgICAgID0gc2tiLT5kYXRhWzFdICYgIFBGX0JJVDsKCWluZm8uY29udHJvbCA9IHNrYi0+ZGF0YVsxXSAmIH5QRl9CSVQ7IC8qIE1hc2sgYXdheSBwb2xsL2ZpbmFsIGJpdCAqLwoKCWNvbnRyb2wgPSBpbmZvLmNvbnRyb2w7CgoJLyogIEZpcnN0IHdlIGNoZWNrIGlmIHRoaXMgZnJhbWUgaGFzIGEgdmFsaWQgY29ubmVjdGlvbiBhZGRyZXNzICovCglpZiAoKGluZm8uY2FkZHIgIT0gc2VsZi0+Y2FkZHIpICYmIChpbmZvLmNhZGRyICE9IENCUk9BRENBU1QpKSB7CgkJSVJEQV9ERUJVRygwLCAiJXMoKSwgd3JvbmcgY29ubmVjdGlvbiBhZGRyZXNzIVxuIiwKCQkJICAgX19GVU5DVElPTl9fKTsKCQlnb3RvIG91dDsKCX0KCS8qCgkgKiAgT3B0aW1pemUgZm9yIHRoZSBjb21tb24gY2FzZSBhbmQgY2hlY2sgaWYgdGhlIGZyYW1lIGlzIGFuCgkgKiAgSShuZm9ybWF0aW9uKSBmcmFtZS4gT25seSBJLWZyYW1lcyBoYXZlIGJpdCAwIHNldCB0byAwCgkgKi8KCWlmICh+Y29udHJvbCAmIDB4MDEpIHsKCQlpcmxhcF9yZWN2X2lfZnJhbWUoc2VsZiwgc2tiLCAmaW5mbywgY29tbWFuZCk7CgkJZ290byBvdXQ7Cgl9CgkvKgoJICogIFdlIG5vdyBjaGVjayBpcyB0aGUgZnJhbWUgaXMgYW4gUyh1cGVydmlzb3J5KSBmcmFtZS4gT25seQoJICogIFMtZnJhbWVzIGhhdmUgYml0IDAgc2V0IHRvIDEgYW5kIGJpdCAxIHNldCB0byAwCgkgKi8KCWlmICh+Y29udHJvbCAmIDB4MDIpIHsKCQkvKgoJCSAqICBSZWNlaXZlZCBTKHVwZXJ2aXNvcnkpIGZyYW1lLCBjaGVjayB3aGljaCBmcmFtZSB0eXBlIGl0IGlzCgkJICogIG9ubHkgdGhlIGZpcnN0IG5pYmJsZSBpcyBvZiBpbnRlcmVzdAoJCSAqLwoJCXN3aXRjaCAoY29udHJvbCAmIDB4MGYpIHsKCQljYXNlIFJSOgoJCQlpcmxhcF9yZWN2X3JyX2ZyYW1lKHNlbGYsIHNrYiwgJmluZm8sIGNvbW1hbmQpOwoJCQlicmVhazsKCQljYXNlIFJOUjoKCQkJaXJsYXBfcmVjdl9ybnJfZnJhbWUoc2VsZiwgc2tiLCAmaW5mbywgY29tbWFuZCk7CgkJCWJyZWFrOwoJCWNhc2UgUkVKOgoJCQlpcmxhcF9yZWN2X3Jlal9mcmFtZShzZWxmLCBza2IsICZpbmZvLCBjb21tYW5kKTsKCQkJYnJlYWs7CgkJY2FzZSBTUkVKOgoJCQlpcmxhcF9yZWN2X3NyZWpfZnJhbWUoc2VsZiwgc2tiLCAmaW5mbywgY29tbWFuZCk7CgkJCWJyZWFrOwoJCWRlZmF1bHQ6CgkJCUlSREFfV0FSTklORygiJXM6IFVua25vd24gUy1mcmFtZSAlMDJ4IHJlY2VpdmVkIVxuIiwKCQkJCV9fRlVOQ1RJT05fXywgaW5mby5jb250cm9sKTsKCQkJYnJlYWs7CgkJfQoJCWdvdG8gb3V0OwoJfQoJLyoKCSAqICBUaGlzIG11c3QgYmUgYSBDKG9udHJvbCkgZnJhbWUKCSAqLwoJc3dpdGNoIChjb250cm9sKSB7CgljYXNlIFhJRF9SU1A6CgkJaXJsYXBfcmVjdl9kaXNjb3ZlcnlfeGlkX3JzcChzZWxmLCBza2IsICZpbmZvKTsKCQlicmVhazsKCWNhc2UgWElEX0NNRDoKCQlpcmxhcF9yZWN2X2Rpc2NvdmVyeV94aWRfY21kKHNlbGYsIHNrYiwgJmluZm8pOwoJCWJyZWFrOwoJY2FzZSBTTlJNX0NNRDoKCQlpcmxhcF9yZWN2X3Nucm1fY21kKHNlbGYsIHNrYiwgJmluZm8pOwoJCWJyZWFrOwoJY2FzZSBETV9SU1A6CgkJaXJsYXBfZG9fZXZlbnQoc2VsZiwgUkVDVl9ETV9SU1AsIHNrYiwgJmluZm8pOwoJCWJyZWFrOwoJY2FzZSBESVNDX0NNRDogLyogQW5kIFJEX1JTUCBzaW5jZSB0aGV5IGhhdmUgdGhlIHNhbWUgdmFsdWUgKi8KCQlpcmxhcF9yZWN2X2Rpc2NfZnJhbWUoc2VsZiwgc2tiLCAmaW5mbywgY29tbWFuZCk7CgkJYnJlYWs7CgljYXNlIFRFU1RfQ01EOgoJCWlybGFwX3JlY3ZfdGVzdF9mcmFtZShzZWxmLCBza2IsICZpbmZvLCBjb21tYW5kKTsKCQlicmVhazsKCWNhc2UgVUFfUlNQOgoJCWlybGFwX3JlY3ZfdWFfZnJhbWUoc2VsZiwgc2tiLCAmaW5mbyk7CgkJYnJlYWs7CgljYXNlIEZSTVJfUlNQOgoJCWlybGFwX3JlY3ZfZnJtcl9mcmFtZShzZWxmLCBza2IsICZpbmZvKTsKCQlicmVhazsKCWNhc2UgVUlfRlJBTUU6CgkJaXJsYXBfcmVjdl91aV9mcmFtZShzZWxmLCBza2IsICZpbmZvKTsKCQlicmVhazsKCWRlZmF1bHQ6CgkJSVJEQV9XQVJOSU5HKCIlczogVW5rbm93biBmcmFtZSAlMDJ4IHJlY2VpdmVkIVxuIiwKCQkJCV9fRlVOQ1RJT05fXywgaW5mby5jb250cm9sKTsKCQlicmVhazsKCX0Kb3V0OgoJLyogQWx3YXlzIGRyb3Agb3VyIHJlZmVyZW5jZSBvbiB0aGUgc2tiICovCglkZXZfa2ZyZWVfc2tiKHNrYik7CglyZXR1cm4gMDsKfQo=