From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.6 required=3.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, USER_AGENT_SANE_2 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 7EC89C433DF for ; Fri, 24 Jul 2020 09:56:24 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3988820714 for ; Fri, 24 Jul 2020 09:56:24 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="svDIOula" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726941AbgGXJ4U (ORCPT ); Fri, 24 Jul 2020 05:56:20 -0400 Received: from mailgw02.mediatek.com ([1.203.163.81]:63606 "EHLO mailgw02.mediatek.com" rhost-flags-OK-FAIL-OK-FAIL) by vger.kernel.org with ESMTP id S1726114AbgGXJ4U (ORCPT ); Fri, 24 Jul 2020 05:56:20 -0400 X-UUID: 9fb9a55ad1ab43c2a55c1018cd156ff8-20200724 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:MIME-Version:Content-Type:References:In-Reply-To:Date:CC:To:From:Subject:Message-ID; bh=X91yDgTfDA2byKhgCyPcKRjLhJli3RxZLlwdVJHhJRM=; b=svDIOulaCtcBzwjEaNKnOl8m7+hmPJiFtjOF0yeU4mQ8aDAppB87Kk+gGtS3tdfqMyecZ3/yAfZL4EQvt8ZoAgqFKVTI/cVSEYbg/0h9Ha3xx/bLWpAYI+2NinXdqSFE2cT/kVetS2vnVd5Z7x/OIajrJ5w9fMllXmouZEglq5I=; X-UUID: 9fb9a55ad1ab43c2a55c1018cd156ff8-20200724 Received: from mtkcas35.mediatek.inc [(172.27.4.253)] by mailgw02.mediatek.com (envelope-from ) (mailgw01.mediatek.com ESMTP with TLS) with ESMTP id 1435633824; Fri, 24 Jul 2020 17:55:39 +0800 Received: from MTKCAS32.mediatek.inc (172.27.4.184) by MTKMBS31N1.mediatek.inc (172.27.4.69) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 24 Jul 2020 17:55:38 +0800 Received: from [10.17.3.153] (10.17.3.153) by MTKCAS32.mediatek.inc (172.27.4.170) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 24 Jul 2020 17:55:37 +0800 Message-ID: <1595584468.27238.43.camel@mhfsdcap03> Subject: Re: [PATCH RESEND v9 18/18] media: platform: Add jpeg enc feature From: Xia Jiang To: Tomasz Figa CC: Hans Verkuil , Mauro Carvalho Chehab , Rob Herring , "Matthias Brugger" , Rick Chang , , , , , , Marek Szyprowski , , , , , , Date: Fri, 24 Jul 2020 17:54:28 +0800 In-Reply-To: <20200611184640.GC8694@chromium.org> References: <20200604090553.10861-1-xia.jiang@mediatek.com> <20200604090553.10861-20-xia.jiang@mediatek.com> <20200611184640.GC8694@chromium.org> Content-Type: text/plain; charset="UTF-8" X-Mailer: Evolution 3.10.4-0ubuntu2 MIME-Version: 1.0 X-TM-SNTS-SMTP: 02F87A8808ED5D525EB80BC28A01270FA46BF0D424768C6E6D17C33DD07B58E32000:8 X-MTK: N Content-Transfer-Encoding: base64 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org T24gVGh1LCAyMDIwLTA2LTExIGF0IDE4OjQ2ICswMDAwLCBUb21hc3ogRmlnYSB3cm90ZToNCj4g SGkgWGlhLA0KPiANCj4gT24gVGh1LCBKdW4gMDQsIDIwMjAgYXQgMDU6MDU6NTNQTSArMDgwMCwg WGlhIEppYW5nIHdyb3RlOg0KPiA+IEFkZCBtdGsganBlZyBlbmNvZGUgdjRsMiBkcml2ZXIgYmFz ZWQgb24ganBlZyBkZWNvZGUsIGJlY2F1c2UgdGhhdCBqcGVnDQo+ID4gZGVjb2RlIGFuZCBlbmNv ZGUgaGF2ZSBncmVhdCBzaW1pbGFyaXRpZXMgd2l0aCBmdW5jdGlvbiBvcGVyYXRpb24uDQo+ID4g DQo+ID4gU2lnbmVkLW9mZi1ieTogWGlhIEppYW5nIDx4aWEuamlhbmdAbWVkaWF0ZWsuY29tPg0K PiA+IC0tLQ0KPiA+IHY5OiBhZGQgbWVtYmVyIHZhcmlhYmxlKHN0cnVjdCB2NGwyX3JlY3QpIGlu IG91dF9xIHN0cnVjdHVyZSBmb3Igc3RvcmluZw0KPiA+ICAgICB0aGUgYWN0aXZlIGNyb3AgaW5m b3JtYXRpb24uDQo+ID4gICAgIG1vdmUgdGhlIHJlbmFtaW5nIGV4c3RpbmcgZnVuY3Rpb25zL2Rl ZmluZXMvdmFyaWFibGVzIHRvIGEgc2VwYXJhdGUgcGF0Y2guDQo+ID4gLS0tDQo+ID4gIGRyaXZl cnMvbWVkaWEvcGxhdGZvcm0vbXRrLWpwZWcvTWFrZWZpbGUgICAgICB8ICAgNSArLQ0KPiA+ICAu Li4vbWVkaWEvcGxhdGZvcm0vbXRrLWpwZWcvbXRrX2pwZWdfY29yZS5jICAgfCA4NDUgKysrKysr KysrKysrKysrLS0tDQo+ID4gIC4uLi9tZWRpYS9wbGF0Zm9ybS9tdGstanBlZy9tdGtfanBlZ19j b3JlLmggICB8ICA0NCArLQ0KPiA+ICAuLi4vbWVkaWEvcGxhdGZvcm0vbXRrLWpwZWcvbXRrX2pw ZWdfZW5jX2h3LmMgfCAxOTMgKysrKw0KPiA+ICAuLi4vbWVkaWEvcGxhdGZvcm0vbXRrLWpwZWcv bXRrX2pwZWdfZW5jX2h3LmggfCAxMjMgKysrDQo+ID4gIDUgZmlsZXMgY2hhbmdlZCwgMTA4NCBp bnNlcnRpb25zKCspLCAxMjYgZGVsZXRpb25zKC0pDQo+ID4gIGNyZWF0ZSBtb2RlIDEwMDY0NCBk cml2ZXJzL21lZGlhL3BsYXRmb3JtL210ay1qcGVnL210a19qcGVnX2VuY19ody5jDQo+ID4gIGNy ZWF0ZSBtb2RlIDEwMDY0NCBkcml2ZXJzL21lZGlhL3BsYXRmb3JtL210ay1qcGVnL210a19qcGVn X2VuY19ody5oDQo+ID4gDQo+IA0KPiBUaGFuayB5b3UgZm9yIHRoZSBwYXRjaC4gUGxlYXNlIHNl ZSBteSBjb21tZW50cyBpbmxpbmUuDQpEZWFyIFRvbWFzeiwNClRoYW5rIHlvdSBmb3IgeW91ciBj b21tZW50cy4NCkkgaGF2ZSB1cGxvYWRlZCB0aGUgdjEwIHZlcnNpb24gd2hpY2ggY29udGFpbnMg dGhlIGNoYW5nZXMgeW91DQptZW50aW9uZWQuDQo+IA0KPiBbc25pcF0NCj4gPiArc3RhdGljIGlu dCBtdGtfanBlZ19lbmNfcXVlcnljYXAoc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYsDQo+ ID4gKwkJCQkgc3RydWN0IHY0bDJfY2FwYWJpbGl0eSAqY2FwKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1 Y3QgbXRrX2pwZWdfZGV2ICpqcGVnID0gdmlkZW9fZHJ2ZGF0YShmaWxlKTsNCj4gPiArDQo+ID4g KwlzdHJzY3B5KGNhcC0+ZHJpdmVyLCBNVEtfSlBFR19OQU1FLCBzaXplb2YoY2FwLT5kcml2ZXIp KTsNCj4gPiArCXN0cnNjcHkoY2FwLT5jYXJkLCBNVEtfSlBFR19OQU1FICIgZW5jb2RlciIsIHNp emVvZihjYXAtPmNhcmQpKTsNCj4gPiArCXNucHJpbnRmKGNhcC0+YnVzX2luZm8sIHNpemVvZihj YXAtPmJ1c19pbmZvKSwgInBsYXRmb3JtOiVzIiwNCj4gPiArCQkgZGV2X25hbWUoanBlZy0+ZGV2 KSk7DQo+ID4gKw0KPiA+ICsJcmV0dXJuIDA7DQo+ID4gK30NCj4gDQo+IEkgY2FuIHNlZSB0aGF0 IHRoaXMgZnVuY3Rpb24gZGlmZmVycyBmcm9tIG10a19qcGVnX2RlY19xdWVyeWNhcCgpIG9ubHkg d2l0aA0KPiB0aGUgIiBlbmNvZGVyIiBzdHJpbmcuIFBlcmhhcHMgdGhleSBjb3VsZCBiZSBtZXJn ZWQ/DQpkb25lLg0KPiANCj4gPiArDQo+ID4gIHN0YXRpYyBpbnQgbXRrX2pwZWdfZGVjX3F1ZXJ5 Y2FwKHN0cnVjdCBmaWxlICpmaWxlLCB2b2lkICpwcml2LA0KPiA+ICAJCQkJIHN0cnVjdCB2NGwy X2NhcGFiaWxpdHkgKmNhcCkNCj4gPiAgew0KPiA+IEBAIC04OCw2ICsxNTcsNTQgQEAgc3RhdGlj IGludCBtdGtfanBlZ19kZWNfcXVlcnljYXAoc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYs DQo+ID4gIAlyZXR1cm4gMDsNCj4gPiAgfQ0KPiA+ICANCj4gPiArc3RhdGljIGludCB2aWRpb2Nf anBlZ19lbmNfc19jdHJsKHN0cnVjdCB2NGwyX2N0cmwgKmN0cmwpDQo+ID4gK3sNCj4gPiArCXN0 cnVjdCBtdGtfanBlZ19jdHggKmN0eCA9IGN0cmxfdG9fY3R4KGN0cmwpOw0KPiA+ICsNCj4gPiAr CXN3aXRjaCAoY3RybC0+aWQpIHsNCj4gPiArCWNhc2UgVjRMMl9DSURfSlBFR19SRVNUQVJUX0lO VEVSVkFMOg0KPiA+ICsJCWN0eC0+cmVzdGFydF9pbnRlcnZhbCA9IGN0cmwtPnZhbDsNCj4gPiAr CQlicmVhazsNCj4gPiArCWNhc2UgVjRMMl9DSURfSlBFR19DT01QUkVTU0lPTl9RVUFMSVRZOg0K PiA+ICsJCWN0eC0+ZW5jX3F1YWxpdHkgPSBjdHJsLT52YWw7DQo+ID4gKwkJYnJlYWs7DQo+ID4g KwljYXNlIFY0TDJfQ0lEX0pQRUdfQUNUSVZFX01BUktFUjoNCj4gPiArCQljdHgtPmVuYWJsZV9l eGlmID0gY3RybC0+dmFsICYgVjRMMl9KUEVHX0FDVElWRV9NQVJLRVJfQVBQMSA/DQo+ID4gKwkJ CQkgICB0cnVlIDogZmFsc2U7DQo+IA0KPiBuaXQ6IElmIGN0eC0+ZW5hYmxlX2V4aWYgaXMgb2Yg dGhlIGJvb2wgdHlwZSwgdGhlIHRlcm5hcnkgb3BlcmF0b3IgY291bGQgYmUNCj4gcmVtb3ZlZCwg YmVjYXVzZSBhbnkgbm9uLXplcm8gdmFsdWUgaXMgaW1wbGljaXRseSB0dXJuZWQgaW50byAxLCBh cyBwZXIgWzFdLg0KPiANCj4gWzFdIGh0dHBzOi8vd3d3Lmtlcm5lbC5vcmcvZG9jL2h0bWwvdjUu Ni9wcm9jZXNzL2NvZGluZy1zdHlsZS5odG1sI3VzaW5nLWJvb2wNCmRvbmUuDQo+IA0KPiBbc25p cF0NCj4gPiArc3RhdGljIGludCBtdGtfanBlZ19lbmNfZW51bV9mbXRfdmlkX2NhcChzdHJ1Y3Qg ZmlsZSAqZmlsZSwgdm9pZCAqcHJpdiwNCj4gPiArCQkJCQkgc3RydWN0IHY0bDJfZm10ZGVzYyAq ZikNCj4gPiArew0KPiA+ICsJcmV0dXJuIG10a19qcGVnX2VudW1fZm10KG10a19qcGVnX2VuY19m b3JtYXRzLA0KPiA+ICsJCQkJIE1US19KUEVHX0VOQ19OVU1fRk9STUFUUywgZiwNCj4gPiArCQkJ CSBNVEtfSlBFR19GTVRfRkxBR19FTkNfQ0FQVFVSRSk7DQo+ID4gK30NCj4gPiArDQo+ID4gIHN0 YXRpYyBpbnQgbXRrX2pwZWdfZGVjX2VudW1fZm10X3ZpZF9jYXAoc3RydWN0IGZpbGUgKmZpbGUs IHZvaWQgKnByaXYsDQo+ID4gIAkJCQkJIHN0cnVjdCB2NGwyX2ZtdGRlc2MgKmYpDQo+ID4gIHsN Cj4gPiBAQCAtMTE3LDYgKzI0MiwxNCBAQCBzdGF0aWMgaW50IG10a19qcGVnX2RlY19lbnVtX2Zt dF92aWRfY2FwKHN0cnVjdCBmaWxlICpmaWxlLCB2b2lkICpwcml2LA0KPiA+ICAJCQkJIE1US19K UEVHX0ZNVF9GTEFHX0RFQ19DQVBUVVJFKTsNCj4gPiAgfQ0KPiA+ICANCj4gPiArc3RhdGljIGlu dCBtdGtfanBlZ19lbmNfZW51bV9mbXRfdmlkX291dChzdHJ1Y3QgZmlsZSAqZmlsZSwgdm9pZCAq cHJpdiwNCj4gPiArCQkJCQkgc3RydWN0IHY0bDJfZm10ZGVzYyAqZikNCj4gPiArew0KPiA+ICsJ cmV0dXJuIG10a19qcGVnX2VudW1fZm10KG10a19qcGVnX2VuY19mb3JtYXRzLA0KPiA+ICsJCQkJ IE1US19KUEVHX0VOQ19OVU1fRk9STUFUUywgZiwNCj4gPiArCQkJCSBNVEtfSlBFR19GTVRfRkxB R19FTkNfT1VUUFVUKTsNCj4gDQo+IERvIHdlIG5lZWQgc2VwYXJhdGUgaW1wbGVtZW50YXRpb25z IG9mIHRoZXNlPyAiZm9ybWF0cyIgYW5kICJudW1fZm9ybWF0cyINCj4gY291bGQgYmUgc3BlY2lm aWVkIGJ5IHRoZSBtYXRjaCBkYXRhIHN0cnVjdCBhbmQgdXNlZCBpbiBhIGdlbmVyaWMgZnVuY3Rp b24uDQpkb25lLg0KPiANCj4gQWxzbywgZG8gd2UgbmVlZCBzZXBhcmF0ZSBmbGFncyBmb3IgRU5D X09VVFBVVC9DQVBUVVJFIGFuZA0KPiBERUNfT1VUUFVUL0NBUFRVUkU/DQpkb25lDQo+IA0KPiA+ ICt9DQo+ID4gKw0KPiA+ICBzdGF0aWMgaW50IG10a19qcGVnX2RlY19lbnVtX2ZtdF92aWRfb3V0 KHN0cnVjdCBmaWxlICpmaWxlLCB2b2lkICpwcml2LA0KPiA+ICAJCQkJCSBzdHJ1Y3QgdjRsMl9m bXRkZXNjICpmKQ0KPiA+ICB7DQo+ID4gQEAgLTEzMiw5MyArMjY1LDY2IEBAIG10a19qcGVnX2dl dF9xX2RhdGEoc3RydWN0IG10a19qcGVnX2N0eCAqY3R4LCBlbnVtIHY0bDJfYnVmX3R5cGUgdHlw ZSkNCj4gPiAgCXJldHVybiAmY3R4LT5jYXBfcTsNCj4gPiAgfQ0KPiA+ICANCj4gPiAtc3RhdGlj IHN0cnVjdCBtdGtfanBlZ19mbXQgKm10a19qcGVnX2ZpbmRfZm9ybWF0KHN0cnVjdCBtdGtfanBl Z19jdHggKmN0eCwNCj4gPiAtCQkJCQkJIHUzMiBwaXhlbGZvcm1hdCwNCj4gPiArc3RhdGljIHN0 cnVjdCBtdGtfanBlZ19mbXQgKm10a19qcGVnX2ZpbmRfZm9ybWF0KHUzMiBwaXhlbGZvcm1hdCwN Cj4gPiAgCQkJCQkJIHVuc2lnbmVkIGludCBmbXRfdHlwZSkNCj4gPiAgew0KPiA+IC0JdW5zaWdu ZWQgaW50IGssIGZtdF9mbGFnOw0KPiA+ICsJdW5zaWduZWQgaW50IGs7DQo+ID4gKwlzdHJ1Y3Qg bXRrX2pwZWdfZm10ICpmbXQ7DQo+ID4gIA0KPiA+IC0JZm10X2ZsYWcgPSAoZm10X3R5cGUgPT0g TVRLX0pQRUdfRk1UX1RZUEVfT1VUUFVUKSA/DQo+ID4gLQkJICAgTVRLX0pQRUdfRk1UX0ZMQUdf REVDX09VVFBVVCA6DQo+ID4gLQkJICAgTVRLX0pQRUdfRk1UX0ZMQUdfREVDX0NBUFRVUkU7DQo+ ID4gKwlmb3IgKGsgPSAwOyBrIDwgTVRLX0pQRUdfRU5DX05VTV9GT1JNQVRTOyBrKyspIHsNCj4g PiArCQlmbXQgPSAmbXRrX2pwZWdfZW5jX2Zvcm1hdHNba107DQo+ID4gKw0KPiA+ICsJCWlmIChm bXQtPmZvdXJjYyA9PSBwaXhlbGZvcm1hdCAmJiBmbXQtPmZsYWdzICYgZm10X3R5cGUpDQo+ID4g KwkJCXJldHVybiBmbXQ7DQo+ID4gKwl9DQo+ID4gIA0KPiA+ICAJZm9yIChrID0gMDsgayA8IE1U S19KUEVHX0RFQ19OVU1fRk9STUFUUzsgaysrKSB7DQo+ID4gLQkJc3RydWN0IG10a19qcGVnX2Zt dCAqZm10ID0gJm10a19qcGVnX2RlY19mb3JtYXRzW2tdOw0KPiA+ICsJCWZtdCA9ICZtdGtfanBl Z19kZWNfZm9ybWF0c1trXTsNCj4gPiAgDQo+ID4gLQkJaWYgKGZtdC0+Zm91cmNjID09IHBpeGVs Zm9ybWF0ICYmIGZtdC0+ZmxhZ3MgJiBmbXRfZmxhZykNCj4gPiArCQlpZiAoZm10LT5mb3VyY2Mg PT0gcGl4ZWxmb3JtYXQgJiYgZm10LT5mbGFncyAmIGZtdF90eXBlKQ0KPiA+ICAJCQlyZXR1cm4g Zm10Ow0KPiA+ICAJfQ0KPiANCj4gV2Ugc2hvdWxkIG9ubHkgbmVlZCB0byBpdGVyYXRlIHRocm91 Z2ggb25lIG9mIHRoZSBhcnJheXMuIE15IHN1Z2dlc3Rpb24NCj4gYWJvdmUgYWJvdXQgbWFraW5n ICJmb3JtYXRzIiBhbmQgIm51bV9mb3JtYXRzIiBhIG1lbWJlciBvZiB0aGUgbWF0Y2ggZGF0YQ0K PiBzaG91bGQgdGFrZSBjYXJlIG9mIHRoaXMgb25lIHRvby4NCmRvbmUuDQo+IA0KPiA+ICANCj4g PiAgCXJldHVybiBOVUxMOw0KPiA+ICB9DQo+ID4gIA0KPiA+IC1zdGF0aWMgdm9pZCBtdGtfanBl Z19hZGp1c3RfZm10X21wbGFuZShzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHgsDQo+ID4gLQkJCQkg ICAgICAgc3RydWN0IHY0bDJfZm9ybWF0ICpmKQ0KPiA+IC17DQo+ID4gLQlzdHJ1Y3QgdjRsMl9w aXhfZm9ybWF0X21wbGFuZSAqcGl4X21wID0gJmYtPmZtdC5waXhfbXA7DQo+ID4gLQlzdHJ1Y3Qg bXRrX2pwZWdfcV9kYXRhICpxX2RhdGE7DQo+ID4gLQlpbnQgaTsNCj4gPiAtDQo+ID4gLQlxX2Rh dGEgPSBtdGtfanBlZ19nZXRfcV9kYXRhKGN0eCwgZi0+dHlwZSk7DQo+ID4gLQ0KPiA+IC0JcGl4 X21wLT53aWR0aCA9IHFfZGF0YS0+dzsNCj4gPiAtCXBpeF9tcC0+aGVpZ2h0ID0gcV9kYXRhLT5o Ow0KPiA+IC0JcGl4X21wLT5waXhlbGZvcm1hdCA9IHFfZGF0YS0+Zm10LT5mb3VyY2M7DQo+ID4g LQlwaXhfbXAtPm51bV9wbGFuZXMgPSBxX2RhdGEtPmZtdC0+Y29scGxhbmVzOw0KPiA+IC0NCj4g PiAtCWZvciAoaSA9IDA7IGkgPCBwaXhfbXAtPm51bV9wbGFuZXM7IGkrKykgew0KPiA+IC0JCXBp eF9tcC0+cGxhbmVfZm10W2ldLmJ5dGVzcGVybGluZSA9IHFfZGF0YS0+Ynl0ZXNwZXJsaW5lW2ld Ow0KPiA+IC0JCXBpeF9tcC0+cGxhbmVfZm10W2ldLnNpemVpbWFnZSA9IHFfZGF0YS0+c2l6ZWlt YWdlW2ldOw0KPiA+IC0JfQ0KPiA+IC19DQo+ID4gLQ0KPiA+IC1zdGF0aWMgaW50IG10a19qcGVn X3RyeV9mbXRfbXBsYW5lKHN0cnVjdCB2NGwyX2Zvcm1hdCAqZiwNCj4gPiAtCQkJCSAgIHN0cnVj dCBtdGtfanBlZ19mbXQgKmZtdCwNCj4gPiAtCQkJCSAgIHN0cnVjdCBtdGtfanBlZ19jdHggKmN0 eCwgaW50IHFfdHlwZSkNCj4gPiArc3RhdGljIGludCB2aWRpb2NfdHJ5X2ZtdChzdHJ1Y3QgdjRs Ml9mb3JtYXQgKmYsIHN0cnVjdCBtdGtfanBlZ19mbXQgKmZtdCkNCj4gDQo+IFRoZSBuYW1lIGlz IGEgYml0IG1pc2xlYWRpbmcsIGJlY2F1c2UgaXQncyBzdWdnZXN0aW5nIHRoYXQgaXQncyB0aGUN Cj4gdmlkaW9jX3RyeV9mbXQgY2FsbGJhY2ssIGJ1dCBpdCdzIGp1c3QgYW4gaW50ZXJuYWwgaGVs cGVyLiBJIHRoaW5rIHRoZQ0KPiBvcmlnaW5hbCBuYW1lIHdhcyBmaW5lLg0KY2hhbmdlZCBpdCB0 byBvcmlnaW5hbCBuYW1lLg0KPiANCj4gPiAgew0KPiA+ICAJc3RydWN0IHY0bDJfcGl4X2Zvcm1h dF9tcGxhbmUgKnBpeF9tcCA9ICZmLT5mbXQucGl4X21wOw0KPiA+ICAJaW50IGk7DQo+ID4gIA0K PiA+ICAJcGl4X21wLT5maWVsZCA9IFY0TDJfRklFTERfTk9ORTsNCj4gPiAtDQo+ID4gLQlpZiAo Y3R4LT5zdGF0ZSAhPSBNVEtfSlBFR19JTklUKSB7DQo+ID4gLQkJbXRrX2pwZWdfYWRqdXN0X2Zt dF9tcGxhbmUoY3R4LCBmKTsNCj4gPiAtCQlyZXR1cm4gMDsNCj4gPiAtCX0NCj4gDQo+IElzIGl0 IG9rYXkgdG8gcmVtb3ZlIHRoaXM/IE15IHVuZGVyc3RhbmRpbmcgaXMgdGhhdCBpdCBwcmV2ZW50 ZWQgY2hhbmdpbmcNCj4gdGhlIGZvcm1hdCB3aGlsZSBzdHJlYW1pbmcsIHdoaWNoIHNob3VsZCBp cyBhcyBleHBlY3RlZC4NCm10a19qcGVnX2dfZm10X3ZpZF9tcGxhbmUoKSBkb2VzIHRoZSBzYW1l IHRoaW5nLCBzbyB1c2UgaXQgdG8gcmVwbGFjZQ0KbXRrX2pwZWdfYWRqdXN0X2ZtdF9tcGxhbmUu DQo+IA0KPiA+IC0NCj4gPiAgCXBpeF9tcC0+bnVtX3BsYW5lcyA9IGZtdC0+Y29scGxhbmVzOw0K PiA+ICAJcGl4X21wLT5waXhlbGZvcm1hdCA9IGZtdC0+Zm91cmNjOw0KPiA+ICANCj4gPiAtCWlm IChxX3R5cGUgPT0gTVRLX0pQRUdfRk1UX1RZUEVfT1VUUFVUKSB7DQo+ID4gLQkJc3RydWN0IHY0 bDJfcGxhbmVfcGl4X2Zvcm1hdCAqcGZtdCA9ICZwaXhfbXAtPnBsYW5lX2ZtdFswXTsNCj4gPiAt DQo+ID4gKwlpZiAoZm10LT5mb3VyY2MgPT0gVjRMMl9QSVhfRk1UX0pQRUcpIHsNCj4gPiAgCQlw aXhfbXAtPmhlaWdodCA9IGNsYW1wKHBpeF9tcC0+aGVpZ2h0LCBNVEtfSlBFR19NSU5fSEVJR0hU LA0KPiA+ICAJCQkJICAgICAgIE1US19KUEVHX01BWF9IRUlHSFQpOw0KPiA+ICAJCXBpeF9tcC0+ d2lkdGggPSBjbGFtcChwaXhfbXAtPndpZHRoLCBNVEtfSlBFR19NSU5fV0lEVEgsDQo+ID4gIAkJ CQkgICAgICBNVEtfSlBFR19NQVhfV0lEVEgpOw0KPiA+IC0NCj4gPiAtCQlwZm10LT5ieXRlc3Bl cmxpbmUgPSAwOw0KPiA+IC0JCS8qIFNvdXJjZSBzaXplIG11c3QgYmUgYWxpZ25lZCB0byAxMjgg Ki8NCj4gPiAtCQlwZm10LT5zaXplaW1hZ2UgPSByb3VuZF91cChwZm10LT5zaXplaW1hZ2UsIDEy OCk7DQo+ID4gLQkJaWYgKHBmbXQtPnNpemVpbWFnZSA9PSAwKQ0KPiA+IC0JCQlwZm10LT5zaXpl aW1hZ2UgPSBNVEtfSlBFR19ERUZBVUxUX1NJWkVJTUFHRTsNCj4gPiAtCQlyZXR1cm4gMDsNCj4g PiArCQlwaXhfbXAtPnBsYW5lX2ZtdFswXS5ieXRlc3BlcmxpbmUgPSAwOw0KPiA+ICsJCXBpeF9t cC0+cGxhbmVfZm10WzBdLnNpemVpbWFnZSA9DQo+ID4gKwkJCQlyb3VuZF91cChwaXhfbXAtPnBs YW5lX2ZtdFswXS5zaXplaW1hZ2UsIDEyOCk7DQo+ID4gKwkJaWYgKHBpeF9tcC0+cGxhbmVfZm10 WzBdLnNpemVpbWFnZSA9PSAwKQ0KPiA+ICsJCQlwaXhfbXAtPnBsYW5lX2ZtdFswXS5zaXplaW1h Z2UgPQ0KPiA+ICsJCQkJTVRLX0pQRUdfREVGQVVMVF9TSVpFSU1BR0U7DQo+ID4gKwl9IGVsc2Ug ew0KPiA+ICsJCXBpeF9tcC0+aGVpZ2h0ID0gY2xhbXAocm91bmRfdXAocGl4X21wLT5oZWlnaHQs IGZtdC0+dl9hbGlnbiksDQo+ID4gKwkJCQkgICAgICAgTVRLX0pQRUdfTUlOX0hFSUdIVCwNCj4g PiArCQkJCSAgICAgICBNVEtfSlBFR19NQVhfSEVJR0hUKTsNCj4gPiArCQlwaXhfbXAtPndpZHRo ID0gY2xhbXAocm91bmRfdXAocGl4X21wLT53aWR0aCwgZm10LT5oX2FsaWduKSwNCj4gPiArCQkJ CSAgICAgIE1US19KUEVHX01JTl9XSURUSCwgTVRLX0pQRUdfTUFYX1dJRFRIKTsNCj4gPiArCQlm b3IgKGkgPSAwOyBpIDwgcGl4X21wLT5udW1fcGxhbmVzOyBpKyspIHsNCj4gPiArCQkJc3RydWN0 IHY0bDJfcGxhbmVfcGl4X2Zvcm1hdCAqcGZtdCA9DQo+ID4gKwkJCQkJCQkmcGl4X21wLT5wbGFu ZV9mbXRbaV07DQo+ID4gKwkJCXUzMiBzdHJpZGUgPSBwaXhfbXAtPndpZHRoICogZm10LT5oX3Nh bXBsZVtpXSAvIDQ7DQo+ID4gKwkJCXUzMiBoID0gcGl4X21wLT5oZWlnaHQgKiBmbXQtPnZfc2Ft cGxlW2ldIC8gNDsNCj4gPiArDQo+ID4gKwkJCXBmbXQtPmJ5dGVzcGVybGluZSA9IHN0cmlkZTsN Cj4gPiArCQkJcGZtdC0+c2l6ZWltYWdlID0gc3RyaWRlICogaDsNCj4gPiArCQl9DQo+ID4gIAl9 DQo+ID4gIA0KPiA+IC0JLyogdHlwZSBpcyBNVEtfSlBFR19GTVRfVFlQRV9DQVBUVVJFICovDQo+ ID4gLQlwaXhfbXAtPmhlaWdodCA9IGNsYW1wKHJvdW5kX3VwKHBpeF9tcC0+aGVpZ2h0LCBmbXQt PnZfYWxpZ24pLA0KPiA+IC0JCQkgICAgICAgTVRLX0pQRUdfTUlOX0hFSUdIVCwgTVRLX0pQRUdf TUFYX0hFSUdIVCk7DQo+ID4gLQlwaXhfbXAtPndpZHRoID0gY2xhbXAocm91bmRfdXAocGl4X21w LT53aWR0aCwgZm10LT5oX2FsaWduKSwNCj4gPiAtCQkJICAgICAgTVRLX0pQRUdfTUlOX1dJRFRI LCBNVEtfSlBFR19NQVhfV0lEVEgpOw0KPiA+IC0NCj4gPiAtCWZvciAoaSA9IDA7IGkgPCBmbXQt PmNvbHBsYW5lczsgaSsrKSB7DQo+ID4gLQkJc3RydWN0IHY0bDJfcGxhbmVfcGl4X2Zvcm1hdCAq cGZtdCA9ICZwaXhfbXAtPnBsYW5lX2ZtdFtpXTsNCj4gPiAtCQl1MzIgc3RyaWRlID0gcGl4X21w LT53aWR0aCAqIGZtdC0+aF9zYW1wbGVbaV0gLyA0Ow0KPiA+IC0JCXUzMiBoID0gcGl4X21wLT5o ZWlnaHQgKiBmbXQtPnZfc2FtcGxlW2ldIC8gNDsNCj4gPiAtDQo+ID4gLQkJcGZtdC0+Ynl0ZXNw ZXJsaW5lID0gc3RyaWRlOw0KPiA+IC0JCXBmbXQtPnNpemVpbWFnZSA9IHN0cmlkZSAqIGg7DQo+ ID4gLQl9DQo+ID4gIAlyZXR1cm4gMDsNCj4gDQo+IEFyZSBhbGwgdGhlIGNoYW5nZXMgYWJvdmUg bmVlZGVkIGZvciB0aGUgZW5jb2Rlcj8gSWYgSSdtIGxvb2tpbmcgY29ycmVjdGx5LA0KPiB0aGV5 J3JlIG1vc3RseSByZWZhY3RvcmluZyBhbmQgc2hvdWxkIGJlIGRvbmUgaW4gYSBzZXBhcmF0ZSBw YXRjaC4gSG93ZXZlciwNCj4gSSBkb24ndCBzZWUgYW55IGJpZyBpc3N1ZSB3aXRoIHRoZSBleGlz dGluZyBjb2Rpbmcgc3R5bGUgaW4gdGhpcyBmdW5jdGlvbiwNCj4gc28gcGVyaGFwcyB0aGUgcmVm YWN0b3JpbmcgY291bGQgYmUgYXZvaWRlZC4NCkluIG9yZGVyIHRvIGNvbXBhdGlibGUganBlZyBl bmNvZGVyLCB1c2UgdGhlIGZvdXJjYyB0byBkaXN0aW5ndWlzaA0KZGlmZmVyZW50IHR5cGVzIGFz IHlvdSBtZW50aW9uZWQgYmVmb3JlLg0KPiANCj4gPiAgfQ0KPiA+ICANCj4gPiBAQCAtMjcxLDE0 ICszNzcsMzUgQEAgc3RhdGljIGludCBtdGtfanBlZ19nX2ZtdF92aWRfbXBsYW5lKHN0cnVjdCBm aWxlICpmaWxlLCB2b2lkICpwcml2LA0KPiA+ICAJcmV0dXJuIDA7DQo+ID4gIH0NCj4gPiAgDQo+ ID4gK3N0YXRpYyBpbnQgbXRrX2pwZWdfZW5jX3RyeV9mbXRfdmlkX2NhcF9tcGxhbmUoc3RydWN0 IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYsDQo+ID4gKwkJCQkJICAgICAgIHN0cnVjdCB2NGwyX2Zv cm1hdCAqZikNCj4gPiArew0KPiA+ICsJc3RydWN0IG10a19qcGVnX2N0eCAqY3R4ID0gbXRrX2pw ZWdfZmhfdG9fY3R4KHByaXYpOw0KPiA+ICsJc3RydWN0IG10a19qcGVnX2ZtdCAqZm10Ow0KPiA+ ICsNCj4gPiArCWZtdCA9IG10a19qcGVnX2ZpbmRfZm9ybWF0KGYtPmZtdC5waXhfbXAucGl4ZWxm b3JtYXQsDQo+ID4gKwkJCQkgICBNVEtfSlBFR19GTVRfRkxBR19FTkNfQ0FQVFVSRSk7DQo+ID4g KwlpZiAoIWZtdCkNCj4gPiArCQlmbXQgPSBjdHgtPmNhcF9xLmZtdDsNCj4gPiArDQo+ID4gKwl2 NGwyX2RiZygyLCBkZWJ1ZywgJmN0eC0+anBlZy0+djRsMl9kZXYsICIoJWQpIHRyeV9mbXQ6JWMl YyVjJWNcbiIsDQo+ID4gKwkJIGYtPnR5cGUsDQo+ID4gKwkJIChmbXQtPmZvdXJjYyAmIDB4ZmYp LA0KPiA+ICsJCSAoZm10LT5mb3VyY2MgPj4gIDggJiAweGZmKSwNCj4gPiArCQkgKGZtdC0+Zm91 cmNjID4+IDE2ICYgMHhmZiksDQo+ID4gKwkJIChmbXQtPmZvdXJjYyA+PiAyNCAmIDB4ZmYpKTsN Cj4gPiArDQo+ID4gKwlyZXR1cm4gdmlkaW9jX3RyeV9mbXQoZiwgZm10KTsNCj4gPiArfQ0KPiAN Cj4gSXMgdGhlcmUgcmVhbGx5IGFueXRoaW5nIGVuY29kZXItc3BlY2lmaWMgaW4gdGhpcyBmdW5j dGlvbj8gQ291bGQgdGhlIHNhbWUNCj4gZnVuY3Rpb24gYXMgdGhlIGRlY29kZXIgYmUgdXNlZCBp bnN0ZWFkPw0KZG9uZS4NCj4gDQo+ID4gKw0KPiA+ICBzdGF0aWMgaW50IG10a19qcGVnX2RlY190 cnlfZm10X3ZpZF9jYXBfbXBsYW5lKHN0cnVjdCBmaWxlICpmaWxlLCB2b2lkICpwcml2LA0KPiA+ ICAJCQkJCSAgICAgICBzdHJ1Y3QgdjRsMl9mb3JtYXQgKmYpDQo+ID4gIHsNCj4gPiAgCXN0cnVj dCBtdGtfanBlZ19jdHggKmN0eCA9IG10a19qcGVnX2ZoX3RvX2N0eChwcml2KTsNCj4gPiAgCXN0 cnVjdCBtdGtfanBlZ19mbXQgKmZtdDsNCj4gPiAgDQo+ID4gLQlmbXQgPSBtdGtfanBlZ19maW5k X2Zvcm1hdChjdHgsIGYtPmZtdC5waXhfbXAucGl4ZWxmb3JtYXQsDQo+ID4gLQkJCQkgICBNVEtf SlBFR19GTVRfVFlQRV9DQVBUVVJFKTsNCj4gPiArCWZtdCA9IG10a19qcGVnX2ZpbmRfZm9ybWF0 KGYtPmZtdC5waXhfbXAucGl4ZWxmb3JtYXQsDQo+ID4gKwkJCQkgICBNVEtfSlBFR19GTVRfRkxB R19ERUNfQ0FQVFVSRSk7DQo+ID4gIAlpZiAoIWZtdCkNCj4gPiAgCQlmbXQgPSBjdHgtPmNhcF9x LmZtdDsNCj4gPiAgDQo+ID4gQEAgLTI4OSw3ICs0MTYsMzMgQEAgc3RhdGljIGludCBtdGtfanBl Z19kZWNfdHJ5X2ZtdF92aWRfY2FwX21wbGFuZShzdHJ1Y3QgZmlsZSAqZmlsZSwgdm9pZCAqcHJp diwNCj4gPiAgCQkgKGZtdC0+Zm91cmNjID4+IDE2ICYgMHhmZiksDQo+ID4gIAkJIChmbXQtPmZv dXJjYyA+PiAyNCAmIDB4ZmYpKTsNCj4gPiAgDQo+ID4gLQlyZXR1cm4gbXRrX2pwZWdfdHJ5X2Zt dF9tcGxhbmUoZiwgZm10LCBjdHgsIE1US19KUEVHX0ZNVF9UWVBFX0NBUFRVUkUpOw0KPiA+ICsJ aWYgKGN0eC0+c3RhdGUgIT0gTVRLX0pQRUdfSU5JVCkgew0KPiA+ICsJCW10a19qcGVnX2dfZm10 X3ZpZF9tcGxhbmUoZmlsZSwgcHJpdiwgZik7DQo+ID4gKwkJcmV0dXJuIDA7DQo+ID4gKwl9DQo+ IA0KPiBJcyB0aGlzIHJlYWxseSBsaW1pdGVkIHRvIHRoZSBkZWNvZGVyPyBJbiBnZW5lcmFsIGN1 cnJlbnRseSB3ZSBkb24ndA0KPiBzdXBwb3J0IGNoYW5naW5nIHRoZSByZXNvbHV0aW9uIGZyb20g dGhlIHVzZXJzcGFjZSB3aGVuIHN0cmVhbWluZyBpcw0KPiBzdGFydGVkIGFuZCBpdCBhcHBsaWVz IHRvIGJvdGggZW5jb2RlciBhbmQgZGVjb2Rlci4NCmRvbmUuDQo+IA0KPiA+ICsNCj4gPiArCXJl dHVybiB2aWRpb2NfdHJ5X2ZtdChmLCBmbXQpOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMg aW50IG10a19qcGVnX2VuY190cnlfZm10X3ZpZF9vdXRfbXBsYW5lKHN0cnVjdCBmaWxlICpmaWxl LCB2b2lkICpwcml2LA0KPiA+ICsJCQkJCSAgICAgICBzdHJ1Y3QgdjRsMl9mb3JtYXQgKmYpDQo+ ID4gK3sNCj4gPiArCXN0cnVjdCBtdGtfanBlZ19jdHggKmN0eCA9IG10a19qcGVnX2ZoX3RvX2N0 eChwcml2KTsNCj4gPiArCXN0cnVjdCBtdGtfanBlZ19mbXQgKmZtdDsNCj4gPiArDQo+ID4gKwlm bXQgPSBtdGtfanBlZ19maW5kX2Zvcm1hdChmLT5mbXQucGl4X21wLnBpeGVsZm9ybWF0LA0KPiA+ ICsJCQkJICAgTVRLX0pQRUdfRk1UX0ZMQUdfRU5DX09VVFBVVCk7DQo+ID4gKwlpZiAoIWZtdCkN Cj4gPiArCQlmbXQgPSBjdHgtPm91dF9xLmZtdDsNCj4gPiArDQo+ID4gKwl2NGwyX2RiZygyLCBk ZWJ1ZywgJmN0eC0+anBlZy0+djRsMl9kZXYsICIoJWQpIHRyeV9mbXQ6JWMlYyVjJWNcbiIsDQo+ ID4gKwkJIGYtPnR5cGUsDQo+ID4gKwkJIChmbXQtPmZvdXJjYyAmIDB4ZmYpLA0KPiA+ICsJCSAo Zm10LT5mb3VyY2MgPj4gIDggJiAweGZmKSwNCj4gPiArCQkgKGZtdC0+Zm91cmNjID4+IDE2ICYg MHhmZiksDQo+ID4gKwkJIChmbXQtPmZvdXJjYyA+PiAyNCAmIDB4ZmYpKTsNCj4gPiArDQo+ID4g KwlyZXR1cm4gdmlkaW9jX3RyeV9mbXQoZiwgZm10KTsNCj4gPiAgfQ0KPiANCj4gRGl0dG8uDQpk b25lLg0KPiANCj4gPiAgDQo+ID4gIHN0YXRpYyBpbnQgbXRrX2pwZWdfZGVjX3RyeV9mbXRfdmlk X291dF9tcGxhbmUoc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYsDQo+ID4gQEAgLTI5OCw4 ICs0NTEsOCBAQCBzdGF0aWMgaW50IG10a19qcGVnX2RlY190cnlfZm10X3ZpZF9vdXRfbXBsYW5l KHN0cnVjdCBmaWxlICpmaWxlLCB2b2lkICpwcml2LA0KPiA+ICAJc3RydWN0IG10a19qcGVnX2N0 eCAqY3R4ID0gbXRrX2pwZWdfZmhfdG9fY3R4KHByaXYpOw0KPiA+ICAJc3RydWN0IG10a19qcGVn X2ZtdCAqZm10Ow0KPiA+ICANCj4gPiAtCWZtdCA9IG10a19qcGVnX2ZpbmRfZm9ybWF0KGN0eCwg Zi0+Zm10LnBpeF9tcC5waXhlbGZvcm1hdCwNCj4gPiAtCQkJCSAgIE1US19KUEVHX0ZNVF9UWVBF X09VVFBVVCk7DQo+ID4gKwlmbXQgPSBtdGtfanBlZ19maW5kX2Zvcm1hdChmLT5mbXQucGl4X21w LnBpeGVsZm9ybWF0LA0KPiA+ICsJCQkJICAgTVRLX0pQRUdfRk1UX0ZMQUdfREVDX09VVFBVVCk7 DQo+ID4gIAlpZiAoIWZtdCkNCj4gPiAgCQlmbXQgPSBjdHgtPm91dF9xLmZtdDsNCj4gPiAgDQo+ ID4gQEAgLTMxMCwxNyArNDYzLDIxIEBAIHN0YXRpYyBpbnQgbXRrX2pwZWdfZGVjX3RyeV9mbXRf dmlkX291dF9tcGxhbmUoc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYsDQo+ID4gIAkJIChm bXQtPmZvdXJjYyA+PiAxNiAmIDB4ZmYpLA0KPiA+ICAJCSAoZm10LT5mb3VyY2MgPj4gMjQgJiAw eGZmKSk7DQo+ID4gIA0KPiA+IC0JcmV0dXJuIG10a19qcGVnX3RyeV9mbXRfbXBsYW5lKGYsIGZt dCwgY3R4LCBNVEtfSlBFR19GTVRfVFlQRV9PVVRQVVQpOw0KPiA+ICsJaWYgKGN0eC0+c3RhdGUg IT0gTVRLX0pQRUdfSU5JVCkgew0KPiA+ICsJCW10a19qcGVnX2dfZm10X3ZpZF9tcGxhbmUoZmls ZSwgcHJpdiwgZik7DQo+ID4gKwkJcmV0dXJuIDA7DQo+ID4gKwl9DQo+IA0KPiBEaXR0by4NCmRv bmUuDQo+IA0KPiA+ICsNCj4gPiArCXJldHVybiB2aWRpb2NfdHJ5X2ZtdChmLCBmbXQpOw0KPiA+ ICB9DQo+ID4gIA0KPiA+ICBzdGF0aWMgaW50IG10a19qcGVnX3NfZm10X21wbGFuZShzdHJ1Y3Qg bXRrX2pwZWdfY3R4ICpjdHgsDQo+ID4gLQkJCQkgc3RydWN0IHY0bDJfZm9ybWF0ICpmKQ0KPiA+ ICsJCQkJIHN0cnVjdCB2NGwyX2Zvcm1hdCAqZiwgdW5zaWduZWQgaW50IGZtdF90eXBlKQ0KPiA+ ICB7DQo+ID4gIAlzdHJ1Y3QgdmIyX3F1ZXVlICp2cTsNCj4gPiAgCXN0cnVjdCBtdGtfanBlZ19x X2RhdGEgKnFfZGF0YSA9IE5VTEw7DQo+ID4gIAlzdHJ1Y3QgdjRsMl9waXhfZm9ybWF0X21wbGFu ZSAqcGl4X21wID0gJmYtPmZtdC5waXhfbXA7DQo+ID4gIAlzdHJ1Y3QgbXRrX2pwZWdfZGV2ICpq cGVnID0gY3R4LT5qcGVnOw0KPiA+IC0JdW5zaWduZWQgaW50IGZfdHlwZTsNCj4gPiAgCWludCBp Ow0KPiA+ICANCj4gPiAgCXZxID0gdjRsMl9tMm1fZ2V0X3ZxKGN0eC0+ZmgubTJtX2N0eCwgZi0+ dHlwZSk7DQo+ID4gQEAgLTMzNCwxMiArNDkxLDExIEBAIHN0YXRpYyBpbnQgbXRrX2pwZWdfc19m bXRfbXBsYW5lKHN0cnVjdCBtdGtfanBlZ19jdHggKmN0eCwNCj4gPiAgCQlyZXR1cm4gLUVCVVNZ Ow0KPiA+ICAJfQ0KPiA+ICANCj4gPiAtCWZfdHlwZSA9IFY0TDJfVFlQRV9JU19PVVRQVVQoZi0+ dHlwZSkgPw0KPiA+IC0JCQkgTVRLX0pQRUdfRk1UX1RZUEVfT1VUUFVUIDogTVRLX0pQRUdfRk1U X1RZUEVfQ0FQVFVSRTsNCj4gPiAtDQo+ID4gLQlxX2RhdGEtPmZtdCA9IG10a19qcGVnX2ZpbmRf Zm9ybWF0KGN0eCwgcGl4X21wLT5waXhlbGZvcm1hdCwgZl90eXBlKTsNCj4gPiArCXFfZGF0YS0+ Zm10ID0gbXRrX2pwZWdfZmluZF9mb3JtYXQocGl4X21wLT5waXhlbGZvcm1hdCwgZm10X3R5cGUp Ow0KPiA+ICAJcV9kYXRhLT53ID0gcGl4X21wLT53aWR0aDsNCj4gPiAgCXFfZGF0YS0+aCA9IHBp eF9tcC0+aGVpZ2h0Ow0KPiA+ICsJcV9kYXRhLT5jcm9wX3JlY3Qud2lkdGggPSBwaXhfbXAtPndp ZHRoOw0KPiA+ICsJcV9kYXRhLT5jcm9wX3JlY3QuaGVpZ2h0ID0gcGl4X21wLT5oZWlnaHQ7DQo+ ID4gIAljdHgtPmNvbG9yc3BhY2UgPSBwaXhfbXAtPmNvbG9yc3BhY2U7DQo+ID4gIAljdHgtPnlj YmNyX2VuYyA9IHBpeF9tcC0+eWNiY3JfZW5jOw0KPiA+ICAJY3R4LT54ZmVyX2Z1bmMgPSBwaXhf bXAtPnhmZXJfZnVuYzsNCj4gPiBAQCAtMzY1LDYgKzUyMSwxOSBAQCBzdGF0aWMgaW50IG10a19q cGVnX3NfZm10X21wbGFuZShzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHgsDQo+ID4gIAlyZXR1cm4g MDsNCj4gPiAgfQ0KPiA+ICANCj4gPiArc3RhdGljIGludCBtdGtfanBlZ19lbmNfc19mbXRfdmlk X291dF9tcGxhbmUoc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYsDQo+ID4gKwkJCQkJICAg ICBzdHJ1Y3QgdjRsMl9mb3JtYXQgKmYpDQo+ID4gK3sNCj4gPiArCWludCByZXQ7DQo+ID4gKw0K PiA+ICsJcmV0ID0gbXRrX2pwZWdfZW5jX3RyeV9mbXRfdmlkX291dF9tcGxhbmUoZmlsZSwgcHJp diwgZik7DQo+ID4gKwlpZiAocmV0KQ0KPiA+ICsJCXJldHVybiByZXQ7DQo+ID4gKw0KPiA+ICsJ cmV0dXJuIG10a19qcGVnX3NfZm10X21wbGFuZShtdGtfanBlZ19maF90b19jdHgocHJpdiksIGYs DQo+ID4gKwkJCQkgICAgIE1US19KUEVHX0ZNVF9GTEFHX0VOQ19PVVRQVVQpOw0KPiA+ICt9DQo+ ID4gKw0KPiA+ICBzdGF0aWMgaW50IG10a19qcGVnX2RlY19zX2ZtdF92aWRfb3V0X21wbGFuZShz dHJ1Y3QgZmlsZSAqZmlsZSwgdm9pZCAqcHJpdiwNCj4gPiAgCQkJCQkgICAgIHN0cnVjdCB2NGwy X2Zvcm1hdCAqZikNCj4gPiAgew0KPiA+IEBAIC0zNzQsNyArNTQzLDIxIEBAIHN0YXRpYyBpbnQg bXRrX2pwZWdfZGVjX3NfZm10X3ZpZF9vdXRfbXBsYW5lKHN0cnVjdCBmaWxlICpmaWxlLCB2b2lk ICpwcml2LA0KPiA+ICAJaWYgKHJldCkNCj4gPiAgCQlyZXR1cm4gcmV0Ow0KPiA+ICANCj4gPiAt CXJldHVybiBtdGtfanBlZ19zX2ZtdF9tcGxhbmUobXRrX2pwZWdfZmhfdG9fY3R4KHByaXYpLCBm KTsNCj4gPiArCXJldHVybiBtdGtfanBlZ19zX2ZtdF9tcGxhbmUobXRrX2pwZWdfZmhfdG9fY3R4 KHByaXYpLCBmLA0KPiA+ICsJCQkJICAgICBNVEtfSlBFR19GTVRfRkxBR19ERUNfT1VUUFVUKTsN Cj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIGludCBtdGtfanBlZ19lbmNfc19mbXRfdmlkX2Nh cF9tcGxhbmUoc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYsDQo+ID4gKwkJCQkJICAgICBz dHJ1Y3QgdjRsMl9mb3JtYXQgKmYpDQo+ID4gK3sNCj4gPiArCWludCByZXQ7DQo+ID4gKw0KPiA+ ICsJcmV0ID0gbXRrX2pwZWdfZW5jX3RyeV9mbXRfdmlkX2NhcF9tcGxhbmUoZmlsZSwgcHJpdiwg Zik7DQo+ID4gKwlpZiAocmV0KQ0KPiA+ICsJCXJldHVybiByZXQ7DQo+ID4gKw0KPiA+ICsJcmV0 dXJuIG10a19qcGVnX3NfZm10X21wbGFuZShtdGtfanBlZ19maF90b19jdHgocHJpdiksIGYsDQo+ ID4gKwkJCQkgICAgIE1US19KUEVHX0ZNVF9GTEFHX0VOQ19DQVBUVVJFKTsNCj4gPiAgfQ0KPiA+ ICANCj4gPiAgc3RhdGljIGludCBtdGtfanBlZ19kZWNfc19mbXRfdmlkX2NhcF9tcGxhbmUoc3Ry dWN0IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYsDQo+ID4gQEAgLTM4Niw3ICs1NjksOCBAQCBzdGF0 aWMgaW50IG10a19qcGVnX2RlY19zX2ZtdF92aWRfY2FwX21wbGFuZShzdHJ1Y3QgZmlsZSAqZmls ZSwgdm9pZCAqcHJpdiwNCj4gPiAgCWlmIChyZXQpDQo+ID4gIAkJcmV0dXJuIHJldDsNCj4gPiAg DQo+ID4gLQlyZXR1cm4gbXRrX2pwZWdfc19mbXRfbXBsYW5lKG10a19qcGVnX2ZoX3RvX2N0eChw cml2KSwgZik7DQo+ID4gKwlyZXR1cm4gbXRrX2pwZWdfc19mbXRfbXBsYW5lKG10a19qcGVnX2Zo X3RvX2N0eChwcml2KSwgZiwNCj4gPiArCQkJCSAgICAgTVRLX0pQRUdfRk1UX0ZMQUdfREVDX0NB UFRVUkUpOw0KPiA+ICB9DQo+IA0KPiBJcyBpdCByZWFsbHkgbmVjZXNzYXJ5IHRvIGhhdmUgc2Vw YXJhdGUgdmFyaWFudHMgb2YgdGhlIGFib3ZlIGZ1bmN0aW9ucyBmb3INCj4gZGVjb2RlciBhbmQg ZW5jb2Rlcj8NCmRvbmUuDQo+IA0KPiA+ICANCj4gPiAgc3RhdGljIHZvaWQgbXRrX2pwZWdfcXVl dWVfc3JjX2NoZ19ldmVudChzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHgpDQo+ID4gQEAgLTQxMSw2 ICs1OTUsMjkgQEAgc3RhdGljIGludCBtdGtfanBlZ19zdWJzY3JpYmVfZXZlbnQoc3RydWN0IHY0 bDJfZmggKmZoLA0KPiA+ICAJcmV0dXJuIHY0bDJfY3RybF9zdWJzY3JpYmVfZXZlbnQoZmgsIHN1 Yik7DQo+ID4gIH0NCj4gPiAgDQo+ID4gK3N0YXRpYyBpbnQgbXRrX2pwZWdfZW5jX2dfc2VsZWN0 aW9uKHN0cnVjdCBmaWxlICpmaWxlLCB2b2lkICpwcml2LA0KPiA+ICsJCQkJICAgIHN0cnVjdCB2 NGwyX3NlbGVjdGlvbiAqcykNCj4gPiArew0KPiA+ICsJc3RydWN0IG10a19qcGVnX2N0eCAqY3R4 ID0gbXRrX2pwZWdfZmhfdG9fY3R4KHByaXYpOw0KPiA+ICsNCj4gPiArCWlmIChzLT50eXBlICE9 IFY0TDJfQlVGX1RZUEVfVklERU9fT1VUUFVUKQ0KPiA+ICsJCXJldHVybiAtRUlOVkFMOw0KPiA+ ICsNCj4gPiArCXN3aXRjaCAocy0+dGFyZ2V0KSB7DQo+ID4gKwljYXNlIFY0TDJfU0VMX1RHVF9D Uk9QOg0KPiA+ICsJY2FzZSBWNEwyX1NFTF9UR1RfQ1JPUF9CT1VORFM6DQo+ID4gKwljYXNlIFY0 TDJfU0VMX1RHVF9DUk9QX0RFRkFVTFQ6DQo+ID4gKwkJcy0+ci53aWR0aCA9IGN0eC0+b3V0X3Eu dzsNCj4gPiArCQlzLT5yLmhlaWdodCA9IGN0eC0+b3V0X3EuaDsNCj4gPiArCQlzLT5yLmxlZnQg PSAwOw0KPiA+ICsJCXMtPnIudG9wID0gMDsNCj4gDQo+IElzIHRoaXMgcmVhbGx5IGNvcnJlY3Q/ IFRoZSBmdW5jdGlvbiBzZWVtcyB0byBiZSByZXR1cm5pbmcgdGhlIGZ1bGwgZnJhbWUNCj4gc2l6 ZSByZWdhcmRsZXNzIG9mIHRoZSBzZWxlY3Rpb24gdGFyZ2V0LiBGb3IgQk9VTkRTIGFuZCBERUZB VUxUUyB0aGlzIHdvdWxkDQo+IGJlIHRoZSBjb3JyZWN0IGJlaGF2aW9yIGluZGVlZCwgYnV0IENS T1Agc2hvdWxkIHJldHVybiB0aGUgYWN0aXZlIGNyb3ANCj4gcmVjdGFuZ2xlLCBhcyBzZXQgYnkg U19TRUxFQ1RJT04uDQpkb25lLg0KPiANCj4gPiArCQlicmVhazsNCj4gPiArCWRlZmF1bHQ6DQo+ ID4gKwkJcmV0dXJuIC1FSU5WQUw7DQo+ID4gKwl9DQo+ID4gKwlyZXR1cm4gMDsNCj4gPiArfQ0K PiA+ICsNCj4gPiAgc3RhdGljIGludCBtdGtfanBlZ19kZWNfZ19zZWxlY3Rpb24oc3RydWN0IGZp bGUgKmZpbGUsIHZvaWQgKnByaXYsDQo+ID4gIAkJCQkgICAgc3RydWN0IHY0bDJfc2VsZWN0aW9u ICpzKQ0KPiA+ICB7DQo+ID4gQEAgLTQ0MCw2ICs2NDcsMjkgQEAgc3RhdGljIGludCBtdGtfanBl Z19kZWNfZ19zZWxlY3Rpb24oc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYsDQo+ID4gIAly ZXR1cm4gMDsNCj4gPiAgfQ0KPiA+ICANCj4gPiArc3RhdGljIGludCBtdGtfanBlZ19lbmNfc19z ZWxlY3Rpb24oc3RydWN0IGZpbGUgKmZpbGUsIHZvaWQgKnByaXYsDQo+ID4gKwkJCQkgICAgc3Ry dWN0IHY0bDJfc2VsZWN0aW9uICpzKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgbXRrX2pwZWdfY3R4 ICpjdHggPSBtdGtfanBlZ19maF90b19jdHgocHJpdik7DQo+ID4gKw0KPiA+ICsJaWYgKHMtPnR5 cGUgIT0gVjRMMl9CVUZfVFlQRV9WSURFT19PVVRQVVQpDQo+ID4gKwkJcmV0dXJuIC1FSU5WQUw7 DQo+ID4gKw0KPiA+ICsJc3dpdGNoIChzLT50YXJnZXQpIHsNCj4gPiArCWNhc2UgVjRMMl9TRUxf VEdUX0NST1A6DQo+ID4gKwkJcy0+ci5sZWZ0ID0gMDsNCj4gPiArCQlzLT5yLnRvcCA9IDA7DQo+ ID4gKwkJcy0+ci53aWR0aCA9IG1pbihzLT5yLndpZHRoLCBjdHgtPm91dF9xLncpOw0KPiA+ICsJ CXMtPnIuaGVpZ2h0ID0gbWluKHMtPnIuaGVpZ2h0LCBjdHgtPm91dF9xLmgpOw0KPiA+ICsJCWN0 eC0+b3V0X3EuY3JvcF9yZWN0ID0gcy0+cjsNCj4gPiArCQlicmVhazsNCj4gPiArCWRlZmF1bHQ6 DQo+ID4gKwkJcmV0dXJuIC1FSU5WQUw7DQo+ID4gKwl9DQo+ID4gKw0KPiA+ICsJcmV0dXJuIDA7 DQo+ID4gK30NCj4gPiArDQo+ID4gIHN0YXRpYyBpbnQgbXRrX2pwZWdfZGVjX3Nfc2VsZWN0aW9u KHN0cnVjdCBmaWxlICpmaWxlLCB2b2lkICpwcml2LA0KPiA+ICAJCQkJICAgIHN0cnVjdCB2NGwy X3NlbGVjdGlvbiAqcykNCj4gPiAgew0KPiA+IEBAIC00ODQsNiArNzE0LDMzIEBAIHN0YXRpYyBp bnQgbXRrX2pwZWdfcWJ1ZihzdHJ1Y3QgZmlsZSAqZmlsZSwgdm9pZCAqcHJpdiwgc3RydWN0IHY0 bDJfYnVmZmVyICpidWYpDQo+ID4gIAlyZXR1cm4gdjRsMl9tMm1fcWJ1ZihmaWxlLCBmaC0+bTJt X2N0eCwgYnVmKTsNCj4gPiAgfQ0KPiA+ICANCj4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCB2NGwy X2lvY3RsX29wcyBtdGtfanBlZ19lbmNfaW9jdGxfb3BzID0gew0KPiA+ICsJLnZpZGlvY19xdWVy eWNhcCAgICAgICAgICAgICAgICA9IG10a19qcGVnX2VuY19xdWVyeWNhcCwNCj4gPiArCS52aWRp b2NfZW51bV9mbXRfdmlkX2NhcAk9IG10a19qcGVnX2VuY19lbnVtX2ZtdF92aWRfY2FwLA0KPiA+ ICsJLnZpZGlvY19lbnVtX2ZtdF92aWRfb3V0CT0gbXRrX2pwZWdfZW5jX2VudW1fZm10X3ZpZF9v dXQsDQo+ID4gKwkudmlkaW9jX3RyeV9mbXRfdmlkX2NhcF9tcGxhbmUJPSBtdGtfanBlZ19lbmNf dHJ5X2ZtdF92aWRfY2FwX21wbGFuZSwNCj4gPiArCS52aWRpb2NfdHJ5X2ZtdF92aWRfb3V0X21w bGFuZQk9IG10a19qcGVnX2VuY190cnlfZm10X3ZpZF9vdXRfbXBsYW5lLA0KPiA+ICsJLnZpZGlv Y19nX2ZtdF92aWRfY2FwX21wbGFuZSAgICA9IG10a19qcGVnX2dfZm10X3ZpZF9tcGxhbmUsDQo+ ID4gKwkudmlkaW9jX2dfZm10X3ZpZF9vdXRfbXBsYW5lICAgID0gbXRrX2pwZWdfZ19mbXRfdmlk X21wbGFuZSwNCj4gPiArCS52aWRpb2Nfc19mbXRfdmlkX2NhcF9tcGxhbmUgICAgPSBtdGtfanBl Z19lbmNfc19mbXRfdmlkX2NhcF9tcGxhbmUsDQo+ID4gKwkudmlkaW9jX3NfZm10X3ZpZF9vdXRf bXBsYW5lICAgID0gbXRrX2pwZWdfZW5jX3NfZm10X3ZpZF9vdXRfbXBsYW5lLA0KPiA+ICsJLnZp ZGlvY19xYnVmICAgICAgICAgICAgICAgICAgICA9IG10a19qcGVnX3FidWYsDQo+IA0KPiBOb3Qg ZGlyZWN0bHkgYSBjb21tZW50IGZvciB0aGlzIHBhdGNoLCBidXQgc2luY2UgdGhlIHByZXZpb3Vz IHBhdGNoIHJlbW92ZWQNCj4gdGhlIExBU1RfRlJBTUUgaGFuZGxpbmcsIHdvdWxkbid0IGl0IGJl IGVub3VnaCB0byBqdXN0IHVzZSB2NGwyX20ybV9xYnVmKCkNCj4gYXMgdGhpcyBjYWxsYmFjaz8N Cnllcyxkb25lLg0KPiANCj4gW3NuaXBdDQo+ID4gK3N0YXRpYyB2b2lkIG10a19qcGVnX2VuY19i dWZfcXVldWUoc3RydWN0IHZiMl9idWZmZXIgKnZiKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgbXRr X2pwZWdfY3R4ICpjdHggPSB2YjJfZ2V0X2Rydl9wcml2KHZiLT52YjJfcXVldWUpOw0KPiA+ICsJ c3RydWN0IG10a19qcGVnX2RldiAqanBlZyA9IGN0eC0+anBlZzsNCj4gPiArDQo+ID4gKwl2NGwy X2RiZygyLCBkZWJ1ZywgJmpwZWctPnY0bDJfZGV2LCAiKCVkKSBidWZfcSBpZD0lZCwgdmI9JXBc biIsDQo+ID4gKwkJIHZiLT52YjJfcXVldWUtPnR5cGUsIHZiLT5pbmRleCwgdmIpOw0KPiA+ICsN Cj4gPiArCXY0bDJfbTJtX2J1Zl9xdWV1ZShjdHgtPmZoLm0ybV9jdHgsIHRvX3ZiMl92NGwyX2J1 ZmZlcih2YikpOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICBzdGF0aWMgdm9pZCBtdGtfanBlZ19kZWNf YnVmX3F1ZXVlKHN0cnVjdCB2YjJfYnVmZmVyICp2YikNCj4gPiAgew0KPiA+ICAJc3RydWN0IG10 a19qcGVnX2N0eCAqY3R4ID0gdmIyX2dldF9kcnZfcHJpdih2Yi0+dmIyX3F1ZXVlKTsNCj4gPiBA QCAtNjY0LDYgKzkzMiwxNSBAQCBzdGF0aWMgc3RydWN0IHZiMl92NGwyX2J1ZmZlciAqbXRrX2pw ZWdfYnVmX3JlbW92ZShzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHgsDQo+ID4gIAkJcmV0dXJuIHY0 bDJfbTJtX2RzdF9idWZfcmVtb3ZlKGN0eC0+ZmgubTJtX2N0eCk7DQo+ID4gIH0NCj4gPiAgDQo+ ID4gK3N0YXRpYyB2b2lkIG10a19qcGVnX2VuY19zdG9wX3N0cmVhbWluZyhzdHJ1Y3QgdmIyX3F1 ZXVlICpxKQ0KPiA+ICt7DQo+ID4gKwlzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHggPSB2YjJfZ2V0 X2Rydl9wcml2KHEpOw0KPiA+ICsJc3RydWN0IHZiMl92NGwyX2J1ZmZlciAqdmI7DQo+ID4gKw0K PiA+ICsJd2hpbGUgKCh2YiA9IG10a19qcGVnX2J1Zl9yZW1vdmUoY3R4LCBxLT50eXBlKSkpDQo+ ID4gKwkJdjRsMl9tMm1fYnVmX2RvbmUodmIsIFZCMl9CVUZfU1RBVEVfRVJST1IpOw0KPiA+ICt9 DQo+ID4gKw0KPiA+ICBzdGF0aWMgdm9pZCBtdGtfanBlZ19kZWNfc3RvcF9zdHJlYW1pbmcoc3Ry dWN0IHZiMl9xdWV1ZSAqcSkNCj4gPiAgew0KPiA+ICAJc3RydWN0IG10a19qcGVnX2N0eCAqY3R4 ID0gdmIyX2dldF9kcnZfcHJpdihxKTsNCj4gPiBAQCAtNjk5LDYgKzk3NiwxNSBAQCBzdGF0aWMg Y29uc3Qgc3RydWN0IHZiMl9vcHMgbXRrX2pwZWdfZGVjX3FvcHMgPSB7DQo+ID4gIAkuc3RvcF9z dHJlYW1pbmcgICAgID0gbXRrX2pwZWdfZGVjX3N0b3Bfc3RyZWFtaW5nLA0KPiA+ICB9Ow0KPiA+ ICANCj4gPiArc3RhdGljIGNvbnN0IHN0cnVjdCB2YjJfb3BzIG10a19qcGVnX2VuY19xb3BzID0g ew0KPiA+ICsJLnF1ZXVlX3NldHVwICAgICAgICA9IG10a19qcGVnX3F1ZXVlX3NldHVwLA0KPiA+ ICsJLmJ1Zl9wcmVwYXJlICAgICAgICA9IG10a19qcGVnX2J1Zl9wcmVwYXJlLA0KPiA+ICsJLmJ1 Zl9xdWV1ZSAgICAgICAgICA9IG10a19qcGVnX2VuY19idWZfcXVldWUsDQo+ID4gKwkud2FpdF9w cmVwYXJlICAgICAgID0gdmIyX29wc193YWl0X3ByZXBhcmUsDQo+ID4gKwkud2FpdF9maW5pc2gg ICAgICAgID0gdmIyX29wc193YWl0X2ZpbmlzaCwNCj4gPiArCS5zdG9wX3N0cmVhbWluZyAgICAg PSBtdGtfanBlZ19lbmNfc3RvcF9zdHJlYW1pbmcsDQo+ID4gK307DQo+ID4gKw0KPiA+ICBzdGF0 aWMgdm9pZCBtdGtfanBlZ19zZXRfZGVjX3NyYyhzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHgsDQo+ ID4gIAkJCQkgc3RydWN0IHZiMl9idWZmZXIgKnNyY19idWYsDQo+ID4gIAkJCQkgc3RydWN0IG10 a19qcGVnX2JzICpicykNCj4gPiBAQCAtNzM2LDYgKzEwMjIsODUgQEAgc3RhdGljIGludCBtdGtf anBlZ19zZXRfZGVjX2RzdChzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHgsDQo+ID4gIAlyZXR1cm4g MDsNCj4gPiAgfQ0KPiA+ICANCj4gPiArc3RhdGljIHZvaWQgbXRrX2pwZWdfc2V0X2VuY19kc3Qo c3RydWN0IG10a19qcGVnX2N0eCAqY3R4LCB2b2lkIF9faW9tZW0gKmJhc2UsDQo+ID4gKwkJCQkg c3RydWN0IHZiMl9idWZmZXIgKmRzdF9idWYsDQo+ID4gKwkJCQkgc3RydWN0IG10a19qcGVnX2Vu Y19icyAqYnMpDQo+ID4gK3sNCj4gPiArCWJzLT5kbWFfYWRkciA9IHZiMl9kbWFfY29udGlnX3Bs YW5lX2RtYV9hZGRyKGRzdF9idWYsIDApOw0KPiA+ICsJYnMtPmRtYV9hZGRyX29mZnNldCA9IGN0 eC0+ZW5hYmxlX2V4aWYgPyBNVEtfSlBFR19NQVhfRVhJRl9TSVpFIDogMDsNCj4gPiArCWJzLT5k bWFfYWRkcl9vZmZzZXRtYXNrID0gYnMtPmRtYV9hZGRyICYgSlBFR19FTkNfRFNUX0FERFJfT0ZG U0VUX01BU0s7DQo+ID4gKwlicy0+c2l6ZSA9IHZiMl9wbGFuZV9zaXplKGRzdF9idWYsIDApOw0K PiANCj4gV2UncmUgY29tcHV0aW5nIHRoZXNlIHZhbHVlcyBhbmQgdGhlbiB3cml0aW5nIHRvIHRo ZSBoYXJkd2FyZSBzdHJhaWdodGF3YXkuDQo+IERvIHdlIG5lZWQgdG8gc2F2ZSB0aGVzZSB2YWx1 ZXMgdG8gdGhlIGJzIHN0cnVjdD8gSWYgbm8sIGRvIHdlIG5lZWQgdGhlIGJzDQo+IHN0cnVjdCBh dCBhbGw/DQp5ZXMsIHJlbW92ZWQgdGhpcyBzdHJ1Y3R1cmUuDQo+IA0KPiA+ICsNCj4gPiArCW10 a19qcGVnX2VuY19zZXRfZHN0X2FkZHIoYmFzZSwgYnMtPmRtYV9hZGRyLCBicy0+c2l6ZSwNCj4g PiArCQkJCSAgYnMtPmRtYV9hZGRyX29mZnNldCwNCj4gPiArCQkJCSAgYnMtPmRtYV9hZGRyX29m ZnNldG1hc2spOw0KPiA+ICt9DQo+ID4gKw0KPiA+ICtzdGF0aWMgdm9pZCBtdGtfanBlZ19zZXRf ZW5jX3NyYyhzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHgsIHZvaWQgX19pb21lbSAqYmFzZSwNCj4g PiArCQkJCSBzdHJ1Y3QgdmIyX2J1ZmZlciAqc3JjX2J1ZikNCj4gPiArew0KPiA+ICsJaW50IGk7 DQo+ID4gKwlkbWFfYWRkcl90CWRtYV9hZGRyOw0KPiANCj4gbml0OiBPbmx5IG9uZSBzcGFjZSBz aG91bGQgYmUgYmV0d2VlbiB2YXJpYWJsZSB0eXBlIGFuZCBuYW1lLg0KZG9uZS4NCj4gDQo+ID4g Kw0KPiA+ICsJbXRrX2pwZWdfZW5jX3NldF9pbWdfc2l6ZShiYXNlLCBjdHgtPm91dF9xLmNyb3Bf cmVjdC53aWR0aCwNCj4gPiArCQkJCSAgY3R4LT5vdXRfcS5jcm9wX3JlY3QuaGVpZ2h0KTsNCj4g PiArCW10a19qcGVnX2VuY19zZXRfYmxrX251bShiYXNlLCBjdHgtPm91dF9xLmZtdC0+Zm91cmNj LA0KPiA+ICsJCQkJIGN0eC0+b3V0X3EuY3JvcF9yZWN0LndpZHRoLA0KPiA+ICsJCQkJIGN0eC0+ b3V0X3EuY3JvcF9yZWN0LmhlaWdodCk7DQo+ID4gKwltdGtfanBlZ19lbmNfc2V0X3N0cmlkZShi YXNlLCBjdHgtPm91dF9xLmZtdC0+Zm91cmNjLCBjdHgtPm91dF9xLncsDQo+ID4gKwkJCQljdHgt Pm91dF9xLmgsIGN0eC0+b3V0X3EuYnl0ZXNwZXJsaW5lWzBdKTsNCj4gPiArDQo+ID4gKwlmb3Ig KGkgPSAwOyBpIDwgc3JjX2J1Zi0+bnVtX3BsYW5lczsgaSsrKSB7DQo+ID4gKwkJZG1hX2FkZHIg PSB2YjJfZG1hX2NvbnRpZ19wbGFuZV9kbWFfYWRkcihzcmNfYnVmLCBpKSArDQo+ID4gKwkJCSAg IHNyY19idWYtPnBsYW5lc1tpXS5kYXRhX29mZnNldDsNCj4gPiArCQltdGtfanBlZ19lbmNfc2V0 X3NyY19hZGRyKGJhc2UsIGRtYV9hZGRyLCBpKTsNCj4gPiArCX0NCj4gPiArfQ0KPiA+ICsNCj4g PiArc3RhdGljIHZvaWQgbXRrX2pwZWdfZW5jX2RldmljZV9ydW4odm9pZCAqcHJpdikNCj4gPiAr ew0KPiA+ICsJc3RydWN0IG10a19qcGVnX2N0eCAqY3R4ID0gcHJpdjsNCj4gPiArCXN0cnVjdCBt dGtfanBlZ19kZXYgKmpwZWcgPSBjdHgtPmpwZWc7DQo+ID4gKwlzdHJ1Y3QgdmIyX3Y0bDJfYnVm ZmVyICpzcmNfYnVmLCAqZHN0X2J1ZjsNCj4gPiArCWVudW0gdmIyX2J1ZmZlcl9zdGF0ZSBidWZf c3RhdGUgPSBWQjJfQlVGX1NUQVRFX0VSUk9SOw0KPiA+ICsJdW5zaWduZWQgbG9uZyBmbGFnczsN Cj4gPiArCXN0cnVjdCBtdGtfanBlZ19zcmNfYnVmICpqcGVnX3NyY19idWY7DQo+ID4gKwlzdHJ1 Y3QgbXRrX2pwZWdfZW5jX2JzIGVuY19iczsNCj4gPiArCWludCByZXQ7DQo+ID4gKw0KPiA+ICsJ c3JjX2J1ZiA9IHY0bDJfbTJtX25leHRfc3JjX2J1ZihjdHgtPmZoLm0ybV9jdHgpOw0KPiA+ICsJ ZHN0X2J1ZiA9IHY0bDJfbTJtX25leHRfZHN0X2J1ZihjdHgtPmZoLm0ybV9jdHgpOw0KPiA+ICsJ anBlZ19zcmNfYnVmID0gbXRrX2pwZWdfdmIyX3RvX3NyY2J1Zigmc3JjX2J1Zi0+dmIyX2J1Zik7 DQo+ID4gKw0KPiA+ICsJcmV0ID0gcG1fcnVudGltZV9nZXRfc3luYyhqcGVnLT5kZXYpOw0KPiA+ ICsJaWYgKHJldCA8IDApDQo+ID4gKwkJZ290byBlbmNfZW5kOw0KPiA+ICsNCj4gPiArCXNwaW5f bG9ja19pcnFzYXZlKCZqcGVnLT5od19sb2NrLCBmbGFncyk7DQo+ID4gKw0KPiA+ICsJLyoNCj4g PiArCSAqIFJlc2V0dGluZyB0aGUgaGFyZHdhcmUgZXZlcnkgZnJhbWUgaXMgdG8gZW5zdXJlIHRo YXQgYWxsIHRoZQ0KPiA+ICsJICogcmVnaXN0ZXJzIGFyZSBjbGVhcmVkLiBUaGlzIGlzIGEgaGFy ZHdhcmUgcmVxdWlyZW1lbnQuDQo+ID4gKwkgKi8NCj4gPiArCW10a19qcGVnX2VuY19yZXNldChq cGVnLT5yZWdfYmFzZSk7DQo+ID4gKw0KPiA+ICsJbXRrX2pwZWdfc2V0X2VuY19kc3QoY3R4LCBq cGVnLT5yZWdfYmFzZSwgJmRzdF9idWYtPnZiMl9idWYsICZlbmNfYnMpOw0KPiA+ICsJbXRrX2pw ZWdfc2V0X2VuY19zcmMoY3R4LCBqcGVnLT5yZWdfYmFzZSwgJnNyY19idWYtPnZiMl9idWYpOw0K PiA+ICsJbXRrX2pwZWdfZW5jX3NldF9jb25maWcoanBlZy0+cmVnX2Jhc2UsIGN0eC0+b3V0X3Eu Zm10LT5od19mb3JtYXQsDQo+ID4gKwkJCQljdHgtPmVuYWJsZV9leGlmLCBjdHgtPmVuY19xdWFs aXR5LA0KPiA+ICsJCQkJY3R4LT5yZXN0YXJ0X2ludGVydmFsKTsNCj4gPiArCW10a19qcGVnX2Vu Y19zdGFydChqcGVnLT5yZWdfYmFzZSk7DQo+IA0KPiBDb3VsZCB3ZSBqdXN0IG1vdmUgdGhlIGFi b3ZlIDUgZnVuY3Rpb25zIGludG8gb25lIGZ1bmN0aW9uIGluc2lkZQ0KPiBtdGtfanBlZ19lbmNf aHcuYyB0aGF0IHRha2VzIG10a19qcGVnX2RldiBwb2ludGVyIGFzIGl0cyBhcmd1bWVudCwgbGV0 J3MNCj4gc2F5IG10a19qcGVnX2VuY19od19ydW4oKSBhbmQgc2ltcGx5IHByb2dyYW0gYWxsIHRo ZSBkYXRhIHRvIHRoZSByZWdpc3RlcnMNCj4gZGlyZWN0bHksIHdpdGhvdXQgdGhlIGV4dHJhIGxl dmVsIG9mIGFic3RyYWN0aW9ucz8NCmRvbmUuDQo+IA0KPiA+ICsJc3Bpbl91bmxvY2tfaXJxcmVz dG9yZSgmanBlZy0+aHdfbG9jaywgZmxhZ3MpOw0KPiA+ICsJcmV0dXJuOw0KPiA+ICsNCj4gPiAr ZW5jX2VuZDoNCj4gPiArCXY0bDJfbTJtX3NyY19idWZfcmVtb3ZlKGN0eC0+ZmgubTJtX2N0eCk7 DQo+ID4gKwl2NGwyX20ybV9kc3RfYnVmX3JlbW92ZShjdHgtPmZoLm0ybV9jdHgpOw0KPiA+ICsJ djRsMl9tMm1fYnVmX2RvbmUoc3JjX2J1ZiwgYnVmX3N0YXRlKTsNCj4gPiArCXY0bDJfbTJtX2J1 Zl9kb25lKGRzdF9idWYsIGJ1Zl9zdGF0ZSk7DQo+ID4gKwl2NGwyX20ybV9qb2JfZmluaXNoKGpw ZWctPm0ybV9kZXYsIGN0eC0+ZmgubTJtX2N0eCk7DQo+ID4gK30NCj4gPiArDQo+ID4gIHN0YXRp YyB2b2lkIG10a19qcGVnX2RlY19kZXZpY2VfcnVuKHZvaWQgKnByaXYpDQo+ID4gIHsNCj4gPiAg CXN0cnVjdCBtdGtfanBlZ19jdHggKmN0eCA9IHByaXY7DQo+ID4gQEAgLTc4NSw2ICsxMTUwLDEx IEBAIHN0YXRpYyB2b2lkIG10a19qcGVnX2RlY19kZXZpY2VfcnVuKHZvaWQgKnByaXYpDQo+ID4g IAl2NGwyX20ybV9qb2JfZmluaXNoKGpwZWctPm0ybV9kZXYsIGN0eC0+ZmgubTJtX2N0eCk7DQo+ ID4gIH0NCj4gPiAgDQo+ID4gK3N0YXRpYyBpbnQgbXRrX2pwZWdfZW5jX2pvYl9yZWFkeSh2b2lk ICpwcml2KQ0KPiA+ICt7DQo+ID4gKwkJcmV0dXJuIDE7DQo+ID4gK30NCj4gPiArDQo+IA0KPiBU aGUgY2FsbGJhY2sgaXMgb3B0aW9uYWwsIHNvIGNhbiBiZSBqdXN0IHJlbW92ZWQgaWYgaXQgYWx3 YXlzIHJldHVybnMgMS4NCmRvbmUuDQo+IA0KPiA+ICBzdGF0aWMgaW50IG10a19qcGVnX2RlY19q b2JfcmVhZHkodm9pZCAqcHJpdikNCj4gPiAgew0KPiA+ICAJc3RydWN0IG10a19qcGVnX2N0eCAq Y3R4ID0gcHJpdjsNCj4gPiBAQCAtNzkyLDYgKzExNjIsMTEgQEAgc3RhdGljIGludCBtdGtfanBl Z19kZWNfam9iX3JlYWR5KHZvaWQgKnByaXYpDQo+ID4gIAlyZXR1cm4gKGN0eC0+c3RhdGUgPT0g TVRLX0pQRUdfUlVOTklORykgPyAxIDogMDsNCj4gPiAgfQ0KPiA+ICANCj4gPiArc3RhdGljIGNv bnN0IHN0cnVjdCB2NGwyX20ybV9vcHMgbXRrX2pwZWdfZW5jX20ybV9vcHMgPSB7DQo+ID4gKwku ZGV2aWNlX3J1biA9IG10a19qcGVnX2VuY19kZXZpY2VfcnVuLA0KPiA+ICsJLmpvYl9yZWFkeSAg PSBtdGtfanBlZ19lbmNfam9iX3JlYWR5LA0KPiA+ICt9Ow0KPiA+ICsNCj4gPiAgc3RhdGljIGNv bnN0IHN0cnVjdCB2NGwyX20ybV9vcHMgbXRrX2pwZWdfZGVjX20ybV9vcHMgPSB7DQo+ID4gIAku ZGV2aWNlX3J1biA9IG10a19qcGVnX2RlY19kZXZpY2VfcnVuLA0KPiA+ICAJLmpvYl9yZWFkeSAg PSBtdGtfanBlZ19kZWNfam9iX3JlYWR5LA0KPiA+IEBAIC04MzAsMjQgKzEyMDUsMTA5IEBAIHN0 YXRpYyBpbnQgbXRrX2pwZWdfZGVjX3F1ZXVlX2luaXQodm9pZCAqcHJpdiwgc3RydWN0IHZiMl9x dWV1ZSAqc3JjX3ZxLA0KPiA+ICAJcmV0dXJuIHJldDsNCj4gPiAgfQ0KPiA+ICANCj4gPiAtc3Rh dGljIHZvaWQgbXRrX2pwZWdfY2xrX29uKHN0cnVjdCBtdGtfanBlZ19kZXYgKmpwZWcpDQo+ID4g K3N0YXRpYyBpbnQgbXRrX2pwZWdfZW5jX3F1ZXVlX2luaXQodm9pZCAqcHJpdiwgc3RydWN0IHZi Ml9xdWV1ZSAqc3JjX3ZxLA0KPiA+ICsJCQkJICAgc3RydWN0IHZiMl9xdWV1ZSAqZHN0X3ZxKQ0K PiA+ICB7DQo+ID4gKwlzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHggPSBwcml2Ow0KPiA+ICAJaW50 IHJldDsNCj4gPiAgDQo+ID4gKwlzcmNfdnEtPnR5cGUgPSBWNEwyX0JVRl9UWVBFX1ZJREVPX09V VFBVVF9NUExBTkU7DQo+ID4gKwlzcmNfdnEtPmlvX21vZGVzID0gVkIyX0RNQUJVRiB8IFZCMl9N TUFQOw0KPiA+ICsJc3JjX3ZxLT5kcnZfcHJpdiA9IGN0eDsNCj4gPiArCXNyY192cS0+YnVmX3N0 cnVjdF9zaXplID0gc2l6ZW9mKHN0cnVjdCBtdGtfanBlZ19zcmNfYnVmKTsNCj4gPiArCXNyY192 cS0+b3BzID0gJm10a19qcGVnX2VuY19xb3BzOw0KPiA+ICsJc3JjX3ZxLT5tZW1fb3BzID0gJnZi Ml9kbWFfY29udGlnX21lbW9wczsNCj4gPiArCXNyY192cS0+dGltZXN0YW1wX2ZsYWdzID0gVjRM Ml9CVUZfRkxBR19USU1FU1RBTVBfQ09QWTsNCj4gPiArCXNyY192cS0+bG9jayA9ICZjdHgtPmpw ZWctPmxvY2s7DQo+ID4gKwlzcmNfdnEtPmRldiA9IGN0eC0+anBlZy0+ZGV2Ow0KPiA+ICsJcmV0 ID0gdmIyX3F1ZXVlX2luaXQoc3JjX3ZxKTsNCj4gPiArCWlmIChyZXQpDQo+ID4gKwkJcmV0dXJu IHJldDsNCj4gPiArDQo+ID4gKwlkc3RfdnEtPnR5cGUgPSBWNEwyX0JVRl9UWVBFX1ZJREVPX0NB UFRVUkVfTVBMQU5FOw0KPiA+ICsJZHN0X3ZxLT5pb19tb2RlcyA9IFZCMl9ETUFCVUYgfCBWQjJf TU1BUDsNCj4gPiArCWRzdF92cS0+ZHJ2X3ByaXYgPSBjdHg7DQo+ID4gKwlkc3RfdnEtPmJ1Zl9z dHJ1Y3Rfc2l6ZSA9IHNpemVvZihzdHJ1Y3QgdjRsMl9tMm1fYnVmZmVyKTsNCj4gPiArCWRzdF92 cS0+b3BzID0gJm10a19qcGVnX2VuY19xb3BzOw0KPiA+ICsJZHN0X3ZxLT5tZW1fb3BzID0gJnZi Ml9kbWFfY29udGlnX21lbW9wczsNCj4gPiArCWRzdF92cS0+dGltZXN0YW1wX2ZsYWdzID0gVjRM Ml9CVUZfRkxBR19USU1FU1RBTVBfQ09QWTsNCj4gPiArCWRzdF92cS0+bG9jayA9ICZjdHgtPmpw ZWctPmxvY2s7DQo+ID4gKwlkc3RfdnEtPmRldiA9IGN0eC0+anBlZy0+ZGV2Ow0KPiA+ICsJcmV0 ID0gdmIyX3F1ZXVlX2luaXQoZHN0X3ZxKTsNCj4gPiArDQo+ID4gKwlyZXR1cm4gcmV0Ow0KPiA+ ICt9DQo+IA0KPiBUaGlzIG9ubHkgZGlmZmVycyBpbiAib3BzIiBmcm9tIHRoZSBkZWNvZGVyIGlt cGxlbWVudGF0aW9uLiBQZXJoYXBzDQo+IGJvdGggZnVuY3Rpb25zIGNvdWxkIGJlIG1lcmdlZD8N CmRvbmUuDQo+IA0KPiA+ICsNCj4gPiArc3RhdGljIHZvaWQgbXRrX2pwZWdfY2xrX29uKHN0cnVj dCBtdGtfanBlZ19kZXYgKmpwZWcpDQo+ID4gK3sNCj4gPiArCWludCByZXQsIGk7DQo+ID4gKw0K PiA+ICAJcmV0ID0gbXRrX3NtaV9sYXJiX2dldChqcGVnLT5sYXJiKTsNCj4gPiAgCWlmIChyZXQp DQo+ID4gIAkJZGV2X2VycihqcGVnLT5kZXYsICJtdGtfc21pX2xhcmJfZ2V0IGxhcmJ2ZGVjIGZh aWwgJWRcbiIsIHJldCk7DQo+ID4gLQljbGtfcHJlcGFyZV9lbmFibGUoanBlZy0+Y2xrX2pkZWNf c21pKTsNCj4gPiAtCWNsa19wcmVwYXJlX2VuYWJsZShqcGVnLT5jbGtfamRlYyk7DQo+ID4gKw0K PiA+ICsJZm9yIChpID0gMDsgaSA8IGpwZWctPnZhcmlhbnQtPm51bV9jbG9ja3M7IGkrKykgew0K PiA+ICsJCXJldCA9IGNsa19wcmVwYXJlX2VuYWJsZShqcGVnLT5jbG9ja3NbaV0pOw0KPiANCj4g SW5zdGVhZCBvZiBhbiBvcGVuIGNvZGVkIGxvb3AsIGNvdWxkIHRoZSBjbGtfYnVsa18qKCkgaGVs cGVycyBiZSB1c2VkDQo+IGluc3RlYWQ/IChMb29rIGZvciBkZXZtX2Nsa19idWxrX2dldCgpIGFu ZCBkZXZtX2Nsa19idWxrX3ByZXBhcmVfZW5hYmxlKCkuKQ0KPiANCj4gPiArCQlpZiAocmV0KSB7 DQo+ID4gKwkJCXdoaWxlICgtLWkgPj0gMCkNCj4gPiArCQkJCWNsa19kaXNhYmxlX3VucHJlcGFy ZShqcGVnLT5jbG9ja3NbaV0pOw0KPiANCj4gbml0OiBUaGUgdHlwaWNhbCBjb252ZW50aW9uIGlz IHRvIGRvIGVycm9yIGhhbmRsaW5nIGluIGFuIGVycm9yIHBhdGggb24gdGhlDQo+IGJvdHRvbSBv ZiB0aGUgZnVuY3Rpb24uDQpkb25lDQo+IA0KPiBBbHNvLCBpdCB3b3VsZCBiZSBuaWNlIHRvIHBy aW50IGFuIGVycm9yIG1lc3NhZ2UuDQpkb25lLg0KPiANCj4gPiArCQl9DQo+ID4gKwl9DQo+ID4g IH0NCj4gPiAgDQo+ID4gIHN0YXRpYyB2b2lkIG10a19qcGVnX2Nsa19vZmYoc3RydWN0IG10a19q cGVnX2RldiAqanBlZykNCj4gPiAgew0KPiA+IC0JY2xrX2Rpc2FibGVfdW5wcmVwYXJlKGpwZWct PmNsa19qZGVjKTsNCj4gPiAtCWNsa19kaXNhYmxlX3VucHJlcGFyZShqcGVnLT5jbGtfamRlY19z bWkpOw0KPiA+ICsJaW50IGk7DQo+ID4gKw0KPiA+ICsJZm9yIChpID0ganBlZy0+dmFyaWFudC0+ bnVtX2Nsb2NrcyAtIDE7IGkgPj0gMDsgaS0tKQ0KPiA+ICsJCWNsa19kaXNhYmxlX3VucHJlcGFy ZShqcGVnLT5jbG9ja3NbaV0pOw0KPiANCj4gRGl0dG8uDQpkb25lLg0KPiANCj4gPiAgCW10a19z bWlfbGFyYl9wdXQoanBlZy0+bGFyYik7DQo+ID4gIH0NCj4gPiAgDQo+ID4gK3N0YXRpYyBpcnFy ZXR1cm5fdCBtdGtfanBlZ19lbmNfaXJxKGludCBpcnEsIHZvaWQgKnByaXYpDQo+ID4gK3sNCj4g PiArCXN0cnVjdCBtdGtfanBlZ19kZXYgKmpwZWcgPSBwcml2Ow0KPiA+ICsJc3RydWN0IG10a19q cGVnX2N0eCAqY3R4Ow0KPiA+ICsJc3RydWN0IHZiMl92NGwyX2J1ZmZlciAqc3JjX2J1ZiwgKmRz dF9idWY7DQo+ID4gKwlzdHJ1Y3QgbXRrX2pwZWdfc3JjX2J1ZiAqanBlZ19zcmNfYnVmOw0KPiA+ ICsJZW51bSB2YjJfYnVmZmVyX3N0YXRlIGJ1Zl9zdGF0ZSA9IFZCMl9CVUZfU1RBVEVfRVJST1I7 DQo+ID4gKwl1MzIgZW5jX2lycV9yZXQ7DQo+ID4gKwl1MzIgZW5jX3JldCwgcmVzdWx0X3NpemU7 DQo+ID4gKw0KPiA+ICsJY3R4ID0gdjRsMl9tMm1fZ2V0X2N1cnJfcHJpdihqcGVnLT5tMm1fZGV2 KTsNCj4gPiArCWlmICghY3R4KSB7DQo+ID4gKwkJdjRsMl9lcnIoJmpwZWctPnY0bDJfZGV2LCAi Q29udGV4dCBpcyBOVUxMXG4iKTsNCj4gPiArCQlyZXR1cm4gSVJRX0hBTkRMRUQ7DQo+ID4gKwl9 DQo+ID4gKw0KPiA+ICsJc3JjX2J1ZiA9IHY0bDJfbTJtX3NyY19idWZfcmVtb3ZlKGN0eC0+Zmgu bTJtX2N0eCk7DQo+ID4gKwlkc3RfYnVmID0gdjRsMl9tMm1fZHN0X2J1Zl9yZW1vdmUoY3R4LT5m aC5tMm1fY3R4KTsNCj4gPiArCWpwZWdfc3JjX2J1ZiA9IG10a19qcGVnX3ZiMl90b19zcmNidWYo JnNyY19idWYtPnZiMl9idWYpOw0KPiA+ICsNCj4gPiArCWVuY19yZXQgPSBtdGtfanBlZ19lbmNf Z2V0X2FuZF9jbGVhcl9pbnRfc3RhdHVzKGpwZWctPnJlZ19iYXNlKTsNCj4gDQo+IFdlIHNob3Vs ZCBjaGVjayB0aGUgaW50ZXJydXB0IHN0YXR1cyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSBmdW5j dGlvbiBhbmQNCj4gcmV0dXJuIElSUV9OT05FIGlmIHRoZXJlIHdhc24ndCBhbnkgZmxhZyBzZXQu DQpkb25lLg0KPiANCj4gPiArCWVuY19pcnFfcmV0ID0gbXRrX2pwZWdfZW5jX2VudW1fcmVzdWx0 KGpwZWctPnJlZ19iYXNlLCBlbmNfcmV0KTsNCj4gPiArDQo+ID4gKwlpZiAoZW5jX2lycV9yZXQg Pj0gTVRLX0pQRUdfRU5DX1JFU1VMVF9TVEFMTCkNCj4gPiArCQltdGtfanBlZ19lbmNfcmVzZXQo anBlZy0+cmVnX2Jhc2UpOw0KPiA+ICsNCj4gPiArCWlmIChlbmNfaXJxX3JldCAhPSBNVEtfSlBF R19FTkNfUkVTVUxUX0RPTkUpIHsNCj4gPiArCQlkZXZfZXJyKGpwZWctPmRldiwgImVuY29kZSBm YWlsZWRcbiIpOw0KPiA+ICsJCWdvdG8gZW5jX2VuZDsNCj4gPiArCX0NCj4gDQo+IEFzIEkgc3Vn Z2VzdGVkIGJlZm9yZSwgaXQgd291bGQgaGF2ZSBiZWVuIG11Y2ggbW9yZSBjbGVhciBpZiB0aGUg aW50ZXJydXB0DQo+IHN0YXR1cyBiaXRzIHdlcmUganVzdCBkaXJlY3RseSByZWFkIGFuZCBjaGVj a2VkIGluIHRoaXMgZnVuY3Rpb24sIHdpdGhvdXQNCj4gaW50cm9kdWNpbmcgdGhlIGFkZGl0aW9u YWwgYWJzdHJhY3Rpb24uDQpkb25lLg0KPiANCj4gPiArDQo+ID4gKwlyZXN1bHRfc2l6ZSA9IG10 a19qcGVnX2VuY19nZXRfZmlsZV9zaXplKGpwZWctPnJlZ19iYXNlKTsNCj4gPiArCXZiMl9zZXRf cGxhbmVfcGF5bG9hZCgmZHN0X2J1Zi0+dmIyX2J1ZiwgMCwgcmVzdWx0X3NpemUpOw0KPiA+ICsN Cj4gPiArCWJ1Zl9zdGF0ZSA9IFZCMl9CVUZfU1RBVEVfRE9ORTsNCj4gPiArDQo+ID4gK2VuY19l bmQ6DQo+ID4gKwl2NGwyX20ybV9idWZfZG9uZShzcmNfYnVmLCBidWZfc3RhdGUpOw0KPiA+ICsJ djRsMl9tMm1fYnVmX2RvbmUoZHN0X2J1ZiwgYnVmX3N0YXRlKTsNCj4gPiArCXY0bDJfbTJtX2pv Yl9maW5pc2goanBlZy0+bTJtX2RldiwgY3R4LT5maC5tMm1fY3R4KTsNCj4gPiArCXBtX3J1bnRp bWVfcHV0KGN0eC0+anBlZy0+ZGV2KTsNCj4gPiArCXJldHVybiBJUlFfSEFORExFRDsNCj4gPiAr fQ0KPiA+ICsNCj4gPiAgc3RhdGljIGlycXJldHVybl90IG10a19qcGVnX2RlY19pcnEoaW50IGly cSwgdm9pZCAqcHJpdikNCj4gPiAgew0KPiA+ICAJc3RydWN0IG10a19qcGVnX2RldiAqanBlZyA9 IHByaXY7DQo+ID4gQEAgLTg5MywzNiArMTM1MywxMzAgQEAgc3RhdGljIGlycXJldHVybl90IG10 a19qcGVnX2RlY19pcnEoaW50IGlycSwgdm9pZCAqcHJpdikNCj4gPiAgCXJldHVybiBJUlFfSEFO RExFRDsNCj4gPiAgfQ0KPiA+ICANCj4gPiArc3RhdGljIHZvaWQgbXRrX2pwZWdfc2V0X2VuY19k ZWZhdWx0X3BhcmFtcyhzdHJ1Y3QgbXRrX2pwZWdfY3R4ICpjdHgpDQo+ID4gK3sNCj4gPiArCXN0 cnVjdCBtdGtfanBlZ19xX2RhdGEgKnEgPSAmY3R4LT5vdXRfcTsNCj4gPiArCXN0cnVjdCB2NGwy X3BpeF9mb3JtYXRfbXBsYW5lICpwaXhfbXA7DQo+ID4gKw0KPiA+ICsJcGl4X21wID0ga21hbGxv YyhzaXplb2YoKnBpeF9tcCksIEdGUF9LRVJORUwpOw0KPiANCj4gRG8gd2UgbmVlZCB0byBhbGxv Y2F0ZSB0aGlzIHBpeF9tcD8gQ291bGQgd2UgaW5zdGVhZCBqdXN0IGVtYmVkIGl0IGluc2lkZQ0K PiBjdHg/DQo+IA0KPiBBbHNvLCB0aGlzIGlzIGFjdHVhbGx5IGEgbWVtb3J5IGxlYWssIGJlY2F1 c2UgSSBkb24ndCBzZWUgdGhpcyBzdHJ1Y3R1cmUNCj4gc2F2ZWQgYW55d2hlcmUgb3IgZnJlZWQu DQo+IA0KPiA+ICsNCj4gPiArCWN0eC0+ZmguY3RybF9oYW5kbGVyID0gJmN0eC0+Y3RybF9oZGw7 DQo+ID4gKwljdHgtPmNvbG9yc3BhY2UgPSBWNEwyX0NPTE9SU1BBQ0VfSlBFRywNCj4gPiArCWN0 eC0+eWNiY3JfZW5jID0gVjRMMl9ZQ0JDUl9FTkNfREVGQVVMVDsNCj4gPiArCWN0eC0+cXVhbnRp emF0aW9uID0gVjRMMl9RVUFOVElaQVRJT05fREVGQVVMVDsNCj4gPiArCWN0eC0+eGZlcl9mdW5j ID0gVjRMMl9YRkVSX0ZVTkNfREVGQVVMVDsNCj4gDQo+IFNpbmNlIHdlIGFscmVhZHkgaGF2ZSBh IHY0bDJfcGl4X2Zvcm1hdF9tcGxhbmUgc3RydWN0IHdoaWNoIGhhcyBmaWVsZHMgZm9yDQo+IHRo ZSBhYm92ZSA0IHZhbHVlcywgY291bGQgd2UganVzdCBzdG9yZSB0aGVtIHRoZXJlPw0KPiANCj4g QWxzbywgSSBkb24ndCBzZWUgdGhpcyBkcml2ZXIgaGFuZGxpbmcgdGhlIGNvbG9yc3BhY2VzIGlu IGFueSB3YXksIGJ1dCBpdA0KPiBzZWVtcyB0byBhbGxvdyBjaGFuZ2luZyB0aGVtIGZyb20gdGhl IHVzZXJzcGFjZS4gVGhpcyBpcyBpbmNvcnJlY3QsIGJlY2F1c2UNCj4gdGhlIHVzZXJzcGFjZSBo YXMgbm8gd2F5IHRvIGtub3cgdGhhdCB0aGUgY29sb3JzcGFjZSBpcyBub3QgaGFuZGxlZC4NCj4g SW5zdGVhZCwgdGhlIHRyeV9mbXQgaW1wbGVtZW50YXRpb24gc2hvdWxkIGFsd2F5cyBvdmVycmlk ZSB0aGUNCj4gdXNlcnNwYWNlLXByb3ZpZGVkIGNvbG9yc3BhY2UgY29uZmlndXJhdGlvbiB3aXRo IHRoZSBvbmVzIHRoYXQgdGhlIGRyaXZlcg0KPiBhc3N1bWVzLg0KZGlkIGFzIHdoYXQgd2UgZGlz Y3Vzc2VkIGVhcmxpZXIuDQo+IA0KPiA+ICsJcGl4X21wLT53aWR0aCA9IE1US19KUEVHX01JTl9X SURUSDsNCj4gPiArCXBpeF9tcC0+aGVpZ2h0ID0gTVRLX0pQRUdfTUlOX0hFSUdIVDsNCj4gPiAr DQo+ID4gKwlxLT5mbXQgPSBtdGtfanBlZ19maW5kX2Zvcm1hdChWNEwyX1BJWF9GTVRfWVVZViwN Cj4gPiArCQkJCSAgICAgIE1US19KUEVHX0ZNVF9GTEFHX0VOQ19PVVRQVVQpOw0KPiA+ICsJdmlk aW9jX3RyeV9mbXQoY29udGFpbmVyX29mKHBpeF9tcCwgc3RydWN0IHY0bDJfZm9ybWF0LA0KPiA+ ICsJCQkJICAgIGZtdC5waXhfbXApLCBxLT5mbXQpOw0KPiA+ICsJcS0+dyA9IHBpeF9tcC0+d2lk dGg7DQo+ID4gKwlxLT5oID0gcGl4X21wLT5oZWlnaHQ7DQo+ID4gKwlxLT5jcm9wX3JlY3Qud2lk dGggPSBwaXhfbXAtPndpZHRoOw0KPiA+ICsJcS0+Y3JvcF9yZWN0LmhlaWdodCA9IHBpeF9tcC0+ aGVpZ2h0Ow0KPiA+ICsJcS0+c2l6ZWltYWdlWzBdID0gcGl4X21wLT5wbGFuZV9mbXRbMF0uc2l6 ZWltYWdlOw0KPiA+ICsJcS0+Ynl0ZXNwZXJsaW5lWzBdID0gcGl4X21wLT5wbGFuZV9mbXRbMF0u Ynl0ZXNwZXJsaW5lOw0KPiANCj4gQWN0dWFsbHksIGRvIHdlIG5lZWQgdGhpcyBjdXN0b20gbXRr X2pwZWdfcV9kYXRhIHN0cnVjdD8gV2h5IGNvdWxkbid0IHdlDQo+IGp1c3Qga2VlcCB0aGUgc2Ft ZSB2YWx1ZXMgaW5zaWRlIHRoZSBzdGFuZGFyZCB2NGwyX3BpeF9mb3JtYXRfbXBsYW5lDQo+IHN0 cnVjdD8NCj4gDQo+IEluIGdlbmVyYWwgaXQncyBwcmVmZXJyZWQgdG8gdXNlIHRoZSBzdGFuZGFy ZCBrZXJuZWwgc3RydWN0dXJlcyBhcyBtdWNoIGFzDQo+IHBvc3NpYmxlIGFuZCBvbmx5IGludHJv ZHVjZSBsb2NhbCBkcml2ZXIgc3RydWN0dXJlcyBmb3IgZGF0YSB0aGF0IGNhbid0IGJlDQo+IHN0 b3JlZCBpbiBnZW5lcmljIG9uZXMuDQpkaWQgYXMgd2hhdCB3ZSBkaXNjdXNzZWQgZWFybGllci4N Cj4gDQo+ID4gKw0KPiA+ICsJcSA9ICZjdHgtPmNhcF9xOw0KPiA+ICsJcS0+Zm10ID0gbXRrX2pw ZWdfZmluZF9mb3JtYXQoVjRMMl9QSVhfRk1UX0pQRUcsDQo+ID4gKwkJCQkgICAgICBNVEtfSlBF R19GTVRfRkxBR19FTkNfQ0FQVFVSRSk7DQo+ID4gKwlwaXhfbXAtPndpZHRoID0gTVRLX0pQRUdf TUlOX1dJRFRIOw0KPiA+ICsJcGl4X21wLT5oZWlnaHQgPSBNVEtfSlBFR19NSU5fSEVJR0hUOw0K PiA+ICsJdmlkaW9jX3RyeV9mbXQoY29udGFpbmVyX29mKHBpeF9tcCwgc3RydWN0IHY0bDJfZm9y bWF0LA0KPiA+ICsJCQkJICAgIGZtdC5waXhfbXApLCBxLT5mbXQpOw0KPiA+ICsJcS0+dyA9IHBp eF9tcC0+d2lkdGg7DQo+ID4gKwlxLT5oID0gcGl4X21wLT5oZWlnaHQ7DQo+ID4gKwlxLT5zaXpl aW1hZ2VbMF0gPSBwaXhfbXAtPnBsYW5lX2ZtdFswXS5zaXplaW1hZ2U7DQo+ID4gKwlxLT5ieXRl c3BlcmxpbmVbMF0gPSBwaXhfbXAtPnBsYW5lX2ZtdFswXS5ieXRlc3BlcmxpbmU7DQo+IA0KPiBE aXR0by4NCmRvbmUuDQo+IA0KPiA+ICt9DQo+ID4gKw0KPiA+ICBzdGF0aWMgdm9pZCBtdGtfanBl Z19zZXRfZGVjX2RlZmF1bHRfcGFyYW1zKHN0cnVjdCBtdGtfanBlZ19jdHggKmN0eCkNCj4gPiAg ew0KPiA+ICAJc3RydWN0IG10a19qcGVnX3FfZGF0YSAqcSA9ICZjdHgtPm91dF9xOw0KPiA+ICsJ c3RydWN0IHY0bDJfcGl4X2Zvcm1hdF9tcGxhbmUgKnBpeF9tcDsNCj4gPiAgCWludCBpOw0KPiA+ ICANCj4gPiArCXBpeF9tcCA9IGttYWxsb2Moc2l6ZW9mKCpwaXhfbXApLCBHRlBfS0VSTkVMKTsN Cj4gPiArDQo+ID4gKwljdHgtPmZoLmN0cmxfaGFuZGxlciA9ICZjdHgtPmN0cmxfaGRsOw0KPiA+ ICAJY3R4LT5jb2xvcnNwYWNlID0gVjRMMl9DT0xPUlNQQUNFX0pQRUcsDQo+ID4gIAljdHgtPnlj YmNyX2VuYyA9IFY0TDJfWUNCQ1JfRU5DX0RFRkFVTFQ7DQo+ID4gIAljdHgtPnF1YW50aXphdGlv biA9IFY0TDJfUVVBTlRJWkFUSU9OX0RFRkFVTFQ7DQo+ID4gIAljdHgtPnhmZXJfZnVuYyA9IFY0 TDJfWEZFUl9GVU5DX0RFRkFVTFQ7DQo+ID4gLQ0KPiA+IC0JcS0+Zm10ID0gbXRrX2pwZWdfZmlu ZF9mb3JtYXQoY3R4LCBWNEwyX1BJWF9GTVRfSlBFRywNCj4gPiAtCQkJCQkgICAgICBNVEtfSlBF R19GTVRfVFlQRV9PVVRQVVQpOw0KPiA+IC0JcS0+dyA9IE1US19KUEVHX01JTl9XSURUSDsNCj4g PiAtCXEtPmggPSBNVEtfSlBFR19NSU5fSEVJR0hUOw0KPiA+IC0JcS0+Ynl0ZXNwZXJsaW5lWzBd ID0gMDsNCj4gPiAtCXEtPnNpemVpbWFnZVswXSA9IE1US19KUEVHX0RFRkFVTFRfU0laRUlNQUdF Ow0KPiA+ICsJcGl4X21wLT53aWR0aCA9IE1US19KUEVHX01JTl9XSURUSDsNCj4gPiArCXBpeF9t cC0+aGVpZ2h0ID0gTVRLX0pQRUdfTUlOX0hFSUdIVDsNCj4gPiArDQo+ID4gKwlxLT5mbXQgPSBt dGtfanBlZ19maW5kX2Zvcm1hdChWNEwyX1BJWF9GTVRfSlBFRywNCj4gPiArCQkJCSAgICAgIE1U S19KUEVHX0ZNVF9GTEFHX0RFQ19PVVRQVVQpOw0KPiA+ICsJdmlkaW9jX3RyeV9mbXQoY29udGFp bmVyX29mKHBpeF9tcCwgc3RydWN0IHY0bDJfZm9ybWF0LA0KPiA+ICsJCQkJICAgIGZtdC5waXhf bXApLCBxLT5mbXQpOw0KPiA+ICsJcS0+dyA9IHBpeF9tcC0+d2lkdGg7DQo+ID4gKwlxLT5oID0g cGl4X21wLT5oZWlnaHQ7DQo+ID4gKwlxLT5zaXplaW1hZ2VbMF0gPSBwaXhfbXAtPnBsYW5lX2Zt dFswXS5zaXplaW1hZ2U7DQo+ID4gKwlxLT5ieXRlc3BlcmxpbmVbMF0gPSBwaXhfbXAtPnBsYW5l X2ZtdFswXS5ieXRlc3BlcmxpbmU7DQo+ID4gIA0KPiA+ICAJcSA9ICZjdHgtPmNhcF9xOw0KPiA+ IC0JcS0+Zm10ID0gbXRrX2pwZWdfZmluZF9mb3JtYXQoY3R4LCBWNEwyX1BJWF9GTVRfWVVWNDIw TSwNCj4gPiAtCQkJCQkgICAgICBNVEtfSlBFR19GTVRfVFlQRV9DQVBUVVJFKTsNCj4gPiAtCXEt PncgPSBNVEtfSlBFR19NSU5fV0lEVEg7DQo+ID4gLQlxLT5oID0gTVRLX0pQRUdfTUlOX0hFSUdI VDsNCj4gPiAtDQo+ID4gKwlxLT5mbXQgPSBtdGtfanBlZ19maW5kX2Zvcm1hdChWNEwyX1BJWF9G TVRfWVVWNDIwTSwNCj4gPiArCQkJCSAgICAgIE1US19KUEVHX0ZNVF9GTEFHX0RFQ19DQVBUVVJF KTsNCj4gPiArCXBpeF9tcC0+d2lkdGggPSBNVEtfSlBFR19NSU5fV0lEVEg7DQo+ID4gKwlwaXhf bXAtPmhlaWdodCA9IE1US19KUEVHX01JTl9IRUlHSFQ7DQo+ID4gKwl2aWRpb2NfdHJ5X2ZtdChj b250YWluZXJfb2YocGl4X21wLCBzdHJ1Y3QgdjRsMl9mb3JtYXQsDQo+ID4gKwkJCQkgICAgZm10 LnBpeF9tcCksIHEtPmZtdCk7DQo+ID4gKwlxLT53ID0gcGl4X21wLT53aWR0aDsNCj4gPiArCXEt PmggPSBwaXhfbXAtPmhlaWdodDsNCj4gPiAgCWZvciAoaSA9IDA7IGkgPCBxLT5mbXQtPmNvbHBs YW5lczsgaSsrKSB7DQo+ID4gLQkJdTMyIHN0cmlkZSA9IHEtPncgKiBxLT5mbXQtPmhfc2FtcGxl W2ldIC8gNDsNCj4gPiAtCQl1MzIgaCA9IHEtPmggKiBxLT5mbXQtPnZfc2FtcGxlW2ldIC8gNDsN Cj4gPiArCQlxLT5zaXplaW1hZ2VbaV0gPSBwaXhfbXAtPnBsYW5lX2ZtdFtpXS5zaXplaW1hZ2U7 DQo+ID4gKwkJcS0+Ynl0ZXNwZXJsaW5lW2ldID0gcGl4X21wLT5wbGFuZV9mbXRbaV0uYnl0ZXNw ZXJsaW5lOw0KPiA+ICsJfQ0KPiA+ICt9DQo+ID4gIA0KPiANCj4gU2FtZSBjb21tZW50cyBhcyBm b3IgdGhlIGVuY29kZXIgdmVyc2lvbi4NCj4gDQo+IE9uIHRvcCBvZiB0aGF0LCBib3RoIGZ1bmN0 aW9ucyBhcmUgYWxtb3N0IGlkZW50aWNhbCBhbmQgaXQgc2hvdWxkIGJlDQo+IHBvc3NpYmxlIHRv IG1lcmdlIHRoZW0uDQpkb25lLg0KPiANCj4gPiAtCQlxLT5ieXRlc3BlcmxpbmVbaV0gPSBzdHJp ZGU7DQo+ID4gLQkJcS0+c2l6ZWltYWdlW2ldID0gc3RyaWRlICogaDsNCj4gPiArc3RhdGljIGlu dCBtdGtfanBlZ19lbmNfb3BlbihzdHJ1Y3QgZmlsZSAqZmlsZSkNCj4gPiArew0KPiA+ICsJc3Ry dWN0IG10a19qcGVnX2RldiAqanBlZyA9IHZpZGVvX2RydmRhdGEoZmlsZSk7DQo+ID4gKwlzdHJ1 Y3QgdmlkZW9fZGV2aWNlICp2ZmQgPSB2aWRlb19kZXZkYXRhKGZpbGUpOw0KPiA+ICsJc3RydWN0 IG10a19qcGVnX2N0eCAqY3R4Ow0KPiA+ICsJaW50IHJldCA9IDA7DQo+ID4gKw0KPiA+ICsJY3R4 ID0ga3phbGxvYyhzaXplb2YoKmN0eCksIEdGUF9LRVJORUwpOw0KPiA+ICsJaWYgKCFjdHgpDQo+ ID4gKwkJcmV0dXJuIC1FTk9NRU07DQo+ID4gKw0KPiA+ICsJaWYgKG11dGV4X2xvY2tfaW50ZXJy dXB0aWJsZSgmanBlZy0+bG9jaykpIHsNCj4gPiArCQlyZXQgPSAtRVJFU1RBUlRTWVM7DQo+ID4g KwkJZ290byBmcmVlOw0KPiA+ICsJfQ0KPiA+ICsNCj4gPiArCXY0bDJfZmhfaW5pdCgmY3R4LT5m aCwgdmZkKTsNCj4gPiArCWZpbGUtPnByaXZhdGVfZGF0YSA9ICZjdHgtPmZoOw0KPiA+ICsJdjRs Ml9maF9hZGQoJmN0eC0+ZmgpOw0KPiA+ICsNCj4gPiArCWN0eC0+anBlZyA9IGpwZWc7DQo+ID4g KwljdHgtPmZoLm0ybV9jdHggPSB2NGwyX20ybV9jdHhfaW5pdChqcGVnLT5tMm1fZGV2LCBjdHgs DQo+ID4gKwkJCQkJICAgIG10a19qcGVnX2VuY19xdWV1ZV9pbml0KTsNCj4gPiArCWlmIChJU19F UlIoY3R4LT5maC5tMm1fY3R4KSkgew0KPiA+ICsJCXJldCA9IFBUUl9FUlIoY3R4LT5maC5tMm1f Y3R4KTsNCj4gPiArCQlnb3RvIGVycm9yOw0KPiA+ICAJfQ0KPiA+ICsNCj4gPiArCXJldCA9IG10 a19qcGVnX2VuY19jdHJsc19zZXR1cChjdHgpOw0KPiA+ICsJaWYgKHJldCkgew0KPiA+ICsJCXY0 bDJfZXJyKCZqcGVnLT52NGwyX2RldiwgIkZhaWxlZCB0byBzZXR1cCBqcGVnIGVuYyBjb250cm9s c1xuIik7DQo+ID4gKwkJZ290byBlcnJvcjsNCj4gPiArCX0NCj4gPiArCW10a19qcGVnX3NldF9l bmNfZGVmYXVsdF9wYXJhbXMoY3R4KTsNCj4gPiArDQo+ID4gKwltdXRleF91bmxvY2soJmpwZWct PmxvY2spOw0KPiA+ICsJcmV0dXJuIDA7DQo+ID4gKw0KPiA+ICtlcnJvcjoNCj4gPiArCXY0bDJf ZmhfZGVsKCZjdHgtPmZoKTsNCj4gPiArCXY0bDJfZmhfZXhpdCgmY3R4LT5maCk7DQo+ID4gKwlt dXRleF91bmxvY2soJmpwZWctPmxvY2spOw0KPiA+ICtmcmVlOg0KPiA+ICsJa2ZyZWUoY3R4KTsN Cj4gPiArCXJldHVybiByZXQ7DQo+ID4gIH0NCj4gDQo+IEl0IGxvb2tzIGxpa2UgdGhlIHF1ZXVl X2luaXQgYXJndW1lbnQgdG8gdjRsMl9tMm1fY3R4X2luaXQoKSBhbmQgY29udHJvbA0KPiBoYW5k bGluZyB3b3VsZCBiZSB0aGUgb25seSBkaWZmZXJlbmNlcyBmcm9tIHRoZSBkZWNvZGVyIHZlcnNp b24uIFBlcmhhcHMNCj4gdGhlIGZ1bmN0aW9ucyBjYW4gYmUgbWVyZ2VkPw0KZG9uZS4NCj4gDQo+ ID4gIA0KPiA+ICBzdGF0aWMgaW50IG10a19qcGVnX2RlY19vcGVuKHN0cnVjdCBmaWxlICpmaWxl KQ0KPiA+IEBAIC05NTMsNiArMTUwNywxMiBAQCBzdGF0aWMgaW50IG10a19qcGVnX2RlY19vcGVu KHN0cnVjdCBmaWxlICpmaWxlKQ0KPiA+ICAJCWdvdG8gZXJyb3I7DQo+ID4gIAl9DQo+ID4gIA0K PiA+ICsJdjRsMl9jdHJsX2hhbmRsZXJfaW5pdCgmY3R4LT5jdHJsX2hkbCwgMCk7DQo+ID4gKwly ZXQgPSB2NGwyX2N0cmxfaGFuZGxlcl9zZXR1cCgmY3R4LT5jdHJsX2hkbCk7DQo+ID4gKwlpZiAo cmV0KSB7DQo+ID4gKwkJdjRsMl9lcnIoJmpwZWctPnY0bDJfZGV2LCAiRmFpbGVkIHRvIHNldHVw IGpwZWcgZGVjIGNvbnRyb2xzXG4iKTsNCj4gPiArCQlnb3RvIGVycm9yOw0KPiA+ICsJfQ0KPiAN Cj4gVGhlcmUgYXJlIG5vIGNvbnRyb2xzIGZvciB0aGUgZGVjb2Rlciwgc28gdGhlcmUgc2hvdWxk IGJlIG5vIG5lZWQgdG8gc2V0IHVwDQo+IGEgY29udHJvbCBoYW5kbGVyLg0KZG9uZS4NCj4gDQo+ ID4gIAltdGtfanBlZ19zZXRfZGVjX2RlZmF1bHRfcGFyYW1zKGN0eCk7DQo+ID4gIAltdXRleF91 bmxvY2soJmpwZWctPmxvY2spOw0KPiA+ICAJcmV0dXJuIDA7DQo+ID4gQEAgLTk3Myw2ICsxNTMz LDcgQEAgc3RhdGljIGludCBtdGtfanBlZ19yZWxlYXNlKHN0cnVjdCBmaWxlICpmaWxlKQ0KPiA+ ICANCj4gPiAgCW11dGV4X2xvY2soJmpwZWctPmxvY2spOw0KPiA+ICAJdjRsMl9tMm1fY3R4X3Jl bGVhc2UoY3R4LT5maC5tMm1fY3R4KTsNCj4gPiArCXY0bDJfY3RybF9oYW5kbGVyX2ZyZWUoJmN0 eC0+Y3RybF9oZGwpOw0KPiA+ICAJdjRsMl9maF9kZWwoJmN0eC0+ZmgpOw0KPiA+ICAJdjRsMl9m aF9leGl0KCZjdHgtPmZoKTsNCj4gPiAgCWtmcmVlKGN0eCk7DQo+ID4gQEAgLTk4MCw2ICsxNTQx LDE1IEBAIHN0YXRpYyBpbnQgbXRrX2pwZWdfcmVsZWFzZShzdHJ1Y3QgZmlsZSAqZmlsZSkNCj4g PiAgCXJldHVybiAwOw0KPiA+ICB9DQo+ID4gIA0KPiA+ICtzdGF0aWMgY29uc3Qgc3RydWN0IHY0 bDJfZmlsZV9vcGVyYXRpb25zIG10a19qcGVnX2VuY19mb3BzID0gew0KPiA+ICsJLm93bmVyICAg ICAgICAgID0gVEhJU19NT0RVTEUsDQo+ID4gKwkub3BlbiAgICAgICAgICAgPSBtdGtfanBlZ19l bmNfb3BlbiwNCj4gPiArCS5yZWxlYXNlICAgICAgICA9IG10a19qcGVnX3JlbGVhc2UsDQo+ID4g KwkucG9sbCAgICAgICAgICAgPSB2NGwyX20ybV9mb3BfcG9sbCwNCj4gPiArCS51bmxvY2tlZF9p b2N0bCA9IHZpZGVvX2lvY3RsMiwNCj4gPiArCS5tbWFwICAgICAgICAgICA9IHY0bDJfbTJtX2Zv cF9tbWFwLA0KPiA+ICt9Ow0KPiA+ICsNCj4gDQo+IElmIHdlIG1lcmdlIHRoZSAub3BlbigpIGlt cGxlbWVudGF0aW9uLCB0aGUgc2FtZSBzdHJ1Y3QgY291bGQgYmUgdXNlZCBmb3INCj4gYm90aCBk ZWNvZGVyIGFuZCBlbmNvZGVyLg0KZG9uZS4NCj4gDQo+IFtzbmlwXQ0KPiA+IEBAIC0xMDQyLDgg KzE2MTksMTIgQEAgc3RhdGljIGludCBtdGtfanBlZ19wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2 aWNlICpwZGV2KQ0KPiA+ICAJCXJldHVybiBqcGVnX2lycTsNCj4gPiAgCX0NCj4gPiAgDQo+ID4g LQlyZXQgPSBkZXZtX3JlcXVlc3RfaXJxKCZwZGV2LT5kZXYsIGpwZWdfaXJxLCBtdGtfanBlZ19k ZWNfaXJxLCAwLA0KPiA+IC0JCQkgICAgICAgcGRldi0+bmFtZSwganBlZyk7DQo+ID4gKwlpZiAo anBlZy0+dmFyaWFudC0+aXNfZW5jb2RlcikNCj4gPiArCQlyZXQgPSBkZXZtX3JlcXVlc3RfaXJx KCZwZGV2LT5kZXYsIGpwZWdfaXJxLCBtdGtfanBlZ19lbmNfaXJxLA0KPiA+ICsJCQkJICAgICAg IDAsIHBkZXYtPm5hbWUsIGpwZWcpOw0KPiA+ICsJZWxzZQ0KPiA+ICsJCXJldCA9IGRldm1fcmVx dWVzdF9pcnEoJnBkZXYtPmRldiwganBlZ19pcnEsIG10a19qcGVnX2RlY19pcnEsDQo+ID4gKwkJ CQkgICAgICAgMCwgcGRldi0+bmFtZSwganBlZyk7DQo+IA0KPiBSYXRoZXIgdGhhbiBoYXZpbmcg ImlzX2VuY29kZXIiIGluIHRoZSB2YXJpYW50IHN0cnVjdCwgd291bGQgaXQgbWFrZSBtb3JlDQo+ IHNlbnNlIHRvIGhhdmUgImlycV9oYW5kbGVyIiBpbnN0ZWFkPyBUaGF0IHdvdWxkIGF2b2lkIHRo ZSBleHBsaWNpdCBpZi4NCmRvbmUuDQo+IA0KPiA+ICAJaWYgKHJldCkgew0KPiA+ICAJCWRldl9l cnIoJnBkZXYtPmRldiwgIkZhaWxlZCB0byByZXF1ZXN0IGpwZWdfaXJxICVkICglZClcbiIsDQo+ ID4gIAkJCWpwZWdfaXJxLCByZXQpOw0KPiA+IEBAIC0xMDYzLDcgKzE2NDQsMTAgQEAgc3RhdGlj IGludCBtdGtfanBlZ19wcm9iZShzdHJ1Y3QgcGxhdGZvcm1fZGV2aWNlICpwZGV2KQ0KPiA+ICAJ CWdvdG8gZXJyX2Rldl9yZWdpc3RlcjsNCj4gPiAgCX0NCj4gPiAgDQo+ID4gLQlqcGVnLT5tMm1f ZGV2ID0gdjRsMl9tMm1faW5pdCgmbXRrX2pwZWdfZGVjX20ybV9vcHMpOw0KPiA+ICsJaWYgKGpw ZWctPnZhcmlhbnQtPmlzX2VuY29kZXIpDQo+ID4gKwkJanBlZy0+bTJtX2RldiA9IHY0bDJfbTJt X2luaXQoJm10a19qcGVnX2VuY19tMm1fb3BzKTsNCj4gPiArCWVsc2UNCj4gPiArCQlqcGVnLT5t Mm1fZGV2ID0gdjRsMl9tMm1faW5pdCgmbXRrX2pwZWdfZGVjX20ybV9vcHMpOw0KPiANCj4gU2Ft ZSBoZXJlLiBUaGUgdmFyaWFudCBzdHJ1Y3QgY291bGQgaGF2ZSBhICJtMm1fb3BzIiBwb2ludGVy Lg0KZG9uZS4NCj4gDQo+ID4gIAlpZiAoSVNfRVJSKGpwZWctPm0ybV9kZXYpKSB7DQo+ID4gIAkJ djRsMl9lcnIoJmpwZWctPnY0bDJfZGV2LCAiRmFpbGVkIHRvIGluaXQgbWVtMm1lbSBkZXZpY2Vc biIpOw0KPiA+ICAJCXJldCA9IFBUUl9FUlIoanBlZy0+bTJtX2Rldik7DQo+ID4gQEAgLTEwNzYs OSArMTY2MCwxNSBAQCBzdGF0aWMgaW50IG10a19qcGVnX3Byb2JlKHN0cnVjdCBwbGF0Zm9ybV9k ZXZpY2UgKnBkZXYpDQo+ID4gIAkJZ290byBlcnJfdmZkX2pwZWdfYWxsb2M7DQo+ID4gIAl9DQo+ ID4gIAlzbnByaW50ZihqcGVnLT52ZGV2LT5uYW1lLCBzaXplb2YoanBlZy0+dmRldi0+bmFtZSks DQo+ID4gLQkJICIlcy1kZWMiLCBNVEtfSlBFR19OQU1FKTsNCj4gPiAtCWpwZWctPnZkZXYtPmZv cHMgPSAmbXRrX2pwZWdfZGVjX2ZvcHM7DQo+ID4gLQlqcGVnLT52ZGV2LT5pb2N0bF9vcHMgPSAm bXRrX2pwZWdfZGVjX2lvY3RsX29wczsNCj4gPiArCQkgIiVzLSVzIiwgTVRLX0pQRUdfTkFNRSwN Cj4gPiArCQkganBlZy0+dmFyaWFudC0+aXNfZW5jb2RlciA/ICJlbmMiIDogImRlYyIpOw0KPiA+ ICsJaWYgKGpwZWctPnZhcmlhbnQtPmlzX2VuY29kZXIpIHsNCj4gPiArCQlqcGVnLT52ZGV2LT5m b3BzID0gJm10a19qcGVnX2VuY19mb3BzOw0KPiA+ICsJCWpwZWctPnZkZXYtPmlvY3RsX29wcyA9 ICZtdGtfanBlZ19lbmNfaW9jdGxfb3BzOw0KPiA+ICsJfSBlbHNlIHsNCj4gPiArCQlqcGVnLT52 ZGV2LT5mb3BzID0gJm10a19qcGVnX2RlY19mb3BzOw0KPiA+ICsJCWpwZWctPnZkZXYtPmlvY3Rs X29wcyA9ICZtdGtfanBlZ19kZWNfaW9jdGxfb3BzOw0KPiA+ICsJfQ0KPiANCj4gU2ltaWxhcmx5 IGhlcmUuDQpkb25lLg0KPiANCj4gW3NuaXBdDQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvbWVk aWEvcGxhdGZvcm0vbXRrLWpwZWcvbXRrX2pwZWdfY29yZS5oIGIvZHJpdmVycy9tZWRpYS9wbGF0 Zm9ybS9tdGstanBlZy9tdGtfanBlZ19jb3JlLmgNCj4gPiBpbmRleCAwYjU5ZTQ4NDk1ZDUuLjll YzJjMzM1MGExNiAxMDA2NDQNCj4gPiAtLS0gYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL210ay1q cGVnL210a19qcGVnX2NvcmUuaA0KPiA+ICsrKyBiL2RyaXZlcnMvbWVkaWEvcGxhdGZvcm0vbXRr LWpwZWcvbXRrX2pwZWdfY29yZS5oDQo+ID4gQEAgLTMsNiArMyw3IEBADQo+ID4gICAqIENvcHly aWdodCAoYykgMjAxNiBNZWRpYVRlayBJbmMuDQo+ID4gICAqIEF1dGhvcjogTWluZyBIc2l1IFRz YWkgPG1pbmdoc2l1LnRzYWlAbWVkaWF0ZWsuY29tPg0KPiA+ICAgKiAgICAgICAgIFJpY2sgQ2hh bmcgPHJpY2suY2hhbmdAbWVkaWF0ZWsuY29tPg0KPiA+ICsgKiAgICAgICAgIFhpYSBKaWFuZyA8 eGlhLmppYW5nQG1lZGlhdGVrLmNvbT4NCj4gPiAgICovDQo+ID4gIA0KPiA+ICAjaWZuZGVmIF9N VEtfSlBFR19DT1JFX0gNCj4gPiBAQCAtMTYsMTkgKzE3LDIxIEBADQo+ID4gICNkZWZpbmUgTVRL X0pQRUdfTkFNRQkJIm10ay1qcGVnIg0KPiA+ICANCj4gPiAgI2RlZmluZSBNVEtfSlBFR19DT01Q X01BWAkJMw0KPiA+ICsjZGVmaW5lIE1US19KUEVHX01BWF9DTE9DS1MJCTINCj4gPiArDQo+ID4g IA0KPiANCj4gRHVwbGljYXRlIGJsYW5rIGxpbmUuDQpyZW1vdmVkLg0KPiANCj4gPiAgI2RlZmlu ZSBNVEtfSlBFR19GTVRfRkxBR19ERUNfT1VUUFVUCUJJVCgwKQ0KPiA+ICAjZGVmaW5lIE1US19K UEVHX0ZNVF9GTEFHX0RFQ19DQVBUVVJFCUJJVCgxKQ0KPiA+IC0NCj4gPiAtI2RlZmluZSBNVEtf SlBFR19GTVRfVFlQRV9PVVRQVVQJMQ0KPiA+IC0jZGVmaW5lIE1US19KUEVHX0ZNVF9UWVBFX0NB UFRVUkUJMg0KPiA+ICsjZGVmaW5lIE1US19KUEVHX0ZNVF9GTEFHX0VOQ19PVVRQVVQJQklUKDIp DQo+ID4gKyNkZWZpbmUgTVRLX0pQRUdfRk1UX0ZMQUdfRU5DX0NBUFRVUkUJQklUKDMpDQo+IA0K PiBEbyB3ZSBuZWVkIHNlcGFyYXRlIGJpdHMgZm9yIGRlY29kZXIgYW5kIGVuY29kZXI/DQpubyBu ZWVkLCBJIGhhdmUgcmVtb3ZlZCBpdC4NCj4gDQo+ID4gIA0KPiA+ICAjZGVmaW5lIE1US19KUEVH X01JTl9XSURUSAkzMlUNCj4gPiAgI2RlZmluZSBNVEtfSlBFR19NSU5fSEVJR0hUCTMyVQ0KPiA+ IC0jZGVmaW5lIE1US19KUEVHX01BWF9XSURUSAk4MTkyVQ0KPiA+IC0jZGVmaW5lIE1US19KUEVH X01BWF9IRUlHSFQJODE5MlUNCj4gPiArI2RlZmluZSBNVEtfSlBFR19NQVhfV0lEVEgJNjU1MzVV DQo+ID4gKyNkZWZpbmUgTVRLX0pQRUdfTUFYX0hFSUdIVAk2NTUzNVUNCj4gDQo+IElmIHRoaXMg aXMgYSBjaGFuZ2UgdmFsaWQgZm9yIHRoZSBkZWNvZGVyIHRvbywgaXQgc2hvdWxkIGJlIGEgc2Vw YXJhdGUNCj4gcGF0Y2guDQpkb25lLg0KPiANCj4gPiAgDQo+ID4gICNkZWZpbmUgTVRLX0pQRUdf REVGQVVMVF9TSVpFSU1BR0UJKDEgKiAxMDI0ICogMTAyNCkNCj4gPiArI2RlZmluZSBNVEtfSlBF R19NQVhfRVhJRl9TSVpFCSg2NCAqIDEwMjQpDQo+IA0KPiBUaGVyZSBpcyBvbmUgdGhpbmcgdGhh dCBJIHJlYWxpemVkIG5vdy4gSWYgdGhlIEVYSUYgbW9kZSBpcyBlbmFibGVkLCB0aGUNCj4gZHJp dmVyIG5lZWRzIHRvIGVuc3VyZSB0aGF0IHRoZSBidWZmZXIgaXMgYmlnIGVub3VnaCB0byBob2xk IHRoZSBFWElGIGRhdGEuDQo+IFRoZSB2YjIgLmJ1Zl9wcmVwYXJlIGNhbGxiYWNrIHdvdWxkIGJl IHRoZSByaWdodCBwbGFjZSB0byBkbyB0aGF0Lg0KZG9uZS4NCj4gDQo+ID4gIA0KPiA+ICAvKioN Cj4gPiAgICogZW51bSBtdGtfanBlZ19jdHhfc3RhdGUgLSBzdGF0ZXMgb2YgdGhlIGNvbnRleHQg c3RhdGUgbWFjaGluZQ0KPiA+IEBAIC00Miw2ICs0NSwxOCBAQCBlbnVtIG10a19qcGVnX2N0eF9z dGF0ZSB7DQo+ID4gIAlNVEtfSlBFR19TT1VSQ0VfQ0hBTkdFLA0KPiA+ICB9Ow0KPiA+ICANCj4g PiArLyoqDQo+ID4gKyAqIG10a19qcGVnX3ZhcmlhbnQgLSBtdGsganBlZyBkcml2ZXIgdmFyaWFu dA0KPiA+ICsgKiBAaXNfZW5jb2RlcjoJCWRyaXZlciBtb2RlIGlzIGpwZWcgZW5jb2Rlcg0KPiA+ ICsgKiBAY2xrX25hbWVzOgkJY2xvY2sgbmFtZXMNCj4gPiArICogQG51bV9jbG9ja3M6CQludW1i ZXJzIG9mIGNsb2NrDQo+ID4gKyAqLw0KPiA+ICtzdHJ1Y3QgbXRrX2pwZWdfdmFyaWFudCB7DQo+ ID4gKwlib29sIGlzX2VuY29kZXI7DQo+ID4gKwljb25zdCBjaGFyCQkqY2xrX25hbWVzW01US19K UEVHX01BWF9DTE9DS1NdOw0KPiA+ICsJaW50CQkJbnVtX2Nsb2NrczsNCj4gDQo+IGhpbnQ6IFBs ZWFzZSBhdm9pZCB0YWJzIGJldHdlZW4gdHlwZXMgYW5kIG5hbWVzLCBhcyBpdCBtYWtlcyBpdCBk aWZmaWN1bHQNCj4gdG8gYWRkIG5ldyBmaWVsZHMgbGF0ZXIgKHRoZSBudW1iZXIgb2YgdGFicyBt aWdodCBuZWVkIHRvIGNoYW5nZSBmb3IgYWxsDQo+IG1lbWJlcnMpLg0KZG9uZS4NCj4gDQo+IFtz bmlwXQ0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL21lZGlhL3BsYXRmb3JtL210ay1qcGVnL210 a19qcGVnX2VuY19ody5jIGIvZHJpdmVycy9tZWRpYS9wbGF0Zm9ybS9tdGstanBlZy9tdGtfanBl Z19lbmNfaHcuYw0KPiA+IG5ldyBmaWxlIG1vZGUgMTAwNjQ0DQo+ID4gaW5kZXggMDAwMDAwMDAw MDAwLi43ZmMxZGU5MjBhNzUNCj4gPiAtLS0gL2Rldi9udWxsDQo+ID4gKysrIGIvZHJpdmVycy9t ZWRpYS9wbGF0Zm9ybS9tdGstanBlZy9tdGtfanBlZ19lbmNfaHcuYw0KPiA+IEBAIC0wLDAgKzEs MTkzIEBADQo+ID4gKy8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBHUEwtMi4wLW9ubHkNCj4g PiArLyoNCj4gPiArICogQ29weXJpZ2h0IChjKSAyMDE5IE1lZGlhVGVrIEluYy4NCj4gPiArICog QXV0aG9yOiBYaWEgSmlhbmcgPHhpYS5qaWFuZ0BtZWRpYXRlay5jb20+DQo+ID4gKyAqDQo+ID4g KyAqLw0KPiA+ICsNCj4gPiArI2luY2x1ZGUgPGxpbnV4L2lvLmg+DQo+ID4gKyNpbmNsdWRlIDxs aW51eC9rZXJuZWwuaD4NCj4gPiArI2luY2x1ZGUgPG1lZGlhL3ZpZGVvYnVmMi1jb3JlLmg+DQo+ ID4gKw0KPiA+ICsjaW5jbHVkZSAibXRrX2pwZWdfZW5jX2h3LmgiDQo+ID4gKw0KPiA+ICtzdGF0 aWMgY29uc3Qgc3RydWN0IG10a19qcGVnX2VuY19xbHQgbXRrX2pwZWdfZW5jX3F1YWxpdHlbXSA9 IHsNCj4gPiArCXsucXVhbGl0eV9wYXJhbSA9IDM0LCAuaGFyZHdhcmVfdmFsdWUgPSBKUEVHX0VO Q19RVUFMSVRZX1EzNH0sDQo+ID4gKwl7LnF1YWxpdHlfcGFyYW0gPSAzOSwgLmhhcmR3YXJlX3Zh bHVlID0gSlBFR19FTkNfUVVBTElUWV9RMzl9LA0KPiA+ICsJey5xdWFsaXR5X3BhcmFtID0gNDgs IC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTQ4fSwNCj4gPiArCXsucXVhbGl0 eV9wYXJhbSA9IDYwLCAuaGFyZHdhcmVfdmFsdWUgPSBKUEVHX0VOQ19RVUFMSVRZX1E2MH0sDQo+ ID4gKwl7LnF1YWxpdHlfcGFyYW0gPSA2NCwgLmhhcmR3YXJlX3ZhbHVlID0gSlBFR19FTkNfUVVB TElUWV9RNjR9LA0KPiA+ICsJey5xdWFsaXR5X3BhcmFtID0gNjgsIC5oYXJkd2FyZV92YWx1ZSA9 IEpQRUdfRU5DX1FVQUxJVFlfUTY4fSwNCj4gPiArCXsucXVhbGl0eV9wYXJhbSA9IDc0LCAuaGFy ZHdhcmVfdmFsdWUgPSBKUEVHX0VOQ19RVUFMSVRZX1E3NH0sDQo+ID4gKwl7LnF1YWxpdHlfcGFy YW0gPSA4MCwgLmhhcmR3YXJlX3ZhbHVlID0gSlBFR19FTkNfUVVBTElUWV9RODB9LA0KPiA+ICsJ ey5xdWFsaXR5X3BhcmFtID0gODIsIC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlf UTgyfSwNCj4gPiArCXsucXVhbGl0eV9wYXJhbSA9IDg0LCAuaGFyZHdhcmVfdmFsdWUgPSBKUEVH X0VOQ19RVUFMSVRZX1E4NH0sDQo+ID4gKwl7LnF1YWxpdHlfcGFyYW0gPSA4NywgLmhhcmR3YXJl X3ZhbHVlID0gSlBFR19FTkNfUVVBTElUWV9RODd9LA0KPiA+ICsJey5xdWFsaXR5X3BhcmFtID0g OTAsIC5oYXJkd2FyZV92YWx1ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTkwfSwNCj4gPiArCXsucXVh bGl0eV9wYXJhbSA9IDkyLCAuaGFyZHdhcmVfdmFsdWUgPSBKUEVHX0VOQ19RVUFMSVRZX1E5Mn0s DQo+ID4gKwl7LnF1YWxpdHlfcGFyYW0gPSA5NSwgLmhhcmR3YXJlX3ZhbHVlID0gSlBFR19FTkNf UVVBTElUWV9ROTV9LA0KPiA+ICsJey5xdWFsaXR5X3BhcmFtID0gOTcsIC5oYXJkd2FyZV92YWx1 ZSA9IEpQRUdfRU5DX1FVQUxJVFlfUTk3fSwNCj4gPiArfTsNCj4gPiArDQo+ID4gK3ZvaWQgbXRr X2pwZWdfZW5jX3Jlc2V0KHZvaWQgX19pb21lbSAqYmFzZSkNCj4gDQo+IEknZCBzdWdnZXN0IHBh c3Npbmcgc3RydWN0IG10a19qcGVnX2RldiBwb2ludGVyIHRvIGFsbCB0aGVzZSBmdW5jdGlvbnMs IGluDQo+IGNhc2UgbW9yZSBkYXRhIGFib3V0IHRoZSBoYXJkd2FyZSBpcyBuZWVkZWQgaW4gdGhl IGZ1dHVyZS4NCj4gDQo+ID4gK3sNCj4gPiArCXdyaXRlbCgweDAwLCBiYXNlICsgSlBFR19FTkNf UlNUQik7DQo+IA0KPiBuaXQ6IEp1c3QgMCBpcyBlbm91Z2guDQpkb25lLg0KPiANCj4gPiArCXdy aXRlbChKUEVHX0VOQ19SRVNFVF9CSVQsIGJhc2UgKyBKUEVHX0VOQ19SU1RCKTsNCj4gPiArCXdy aXRlbCgweDAwLCBiYXNlICsgSlBFR19FTkNfQ09ERUNfU0VMKTsNCj4gDQo+IERpdHRvLg0KZG9u ZS4NCj4gDQo+ID4gK30NCj4gPiArDQo+ID4gK3UzMiBtdGtfanBlZ19lbmNfZ2V0X2FuZF9jbGVh cl9pbnRfc3RhdHVzKHZvaWQgX19pb21lbSAqYmFzZSkNCj4gPiArew0KPiA+ICsJdTMyIHJldDsN Cj4gPiArDQo+ID4gKwlyZXQgPSByZWFkbChiYXNlICsgSlBFR19FTkNfSU5UX1NUUykgJg0KPiA+ ICsJCSAgICBKUEVHX0VOQ19JTlRfU1RBVFVTX01BU0tfQUxMSVJROw0KPiA+ICsJaWYgKHJldCkN Cj4gPiArCQl3cml0ZWwoMCwgYmFzZSArIEpQRUdfRU5DX0lOVF9TVFMpOw0KPiA+ICsNCj4gPiAr CXJldHVybiByZXQ7DQo+ID4gK30NCj4gPiArDQo+ID4gK3UzMiBtdGtfanBlZ19lbmNfZ2V0X2Zp bGVfc2l6ZSh2b2lkIF9faW9tZW0gKmJhc2UpDQo+ID4gK3sNCj4gPiArCXJldHVybiByZWFkbChi YXNlICsgSlBFR19FTkNfRE1BX0FERFIwKSAtDQo+ID4gKwkgICAgICAgcmVhZGwoYmFzZSArIEpQ RUdfRU5DX0RTVF9BRERSMCk7DQo+ID4gK30NCj4gPiArDQo+ID4gK3UzMiBtdGtfanBlZ19lbmNf ZW51bV9yZXN1bHQodm9pZCBfX2lvbWVtICpiYXNlLCB1MzIgaXJxX3N0YXR1cykNCj4gPiArew0K PiA+ICsJaWYgKGlycV9zdGF0dXMgJiBKUEVHX0VOQ19JTlRfU1RBVFVTX0RPTkUpDQo+ID4gKwkJ cmV0dXJuIE1US19KUEVHX0VOQ19SRVNVTFRfRE9ORTsNCj4gPiArCWVsc2UgaWYgKGlycV9zdGF0 dXMgJiBKUEVHX0VOQ19JTlRfU1RBVFVTX1NUQUxMKQ0KPiA+ICsJCXJldHVybiBNVEtfSlBFR19F TkNfUkVTVUxUX1NUQUxMOw0KPiA+ICsJZWxzZQ0KPiA+ICsJCXJldHVybiBNVEtfSlBFR19FTkNf UkVTVUxUX1ZDT0RFQ19JUlE7DQo+ID4gK30NCj4gDQo+IEl0IGxvb2tzIGxpa2UgdGhlIGRyaXZl ciBvbmx5IGNhcmVzIGFib3V0IDIgY2FzZXM6IERPTkUgYW5kIGFueXRoaW5nIGVsc2UuDQo+IEFj dHVhbGx5IGl0IGFsc28gY2FyZXMgYWJvdXQgYSBjYXNlIHdoZXJlIG5vIGJpdHMgYXJlIHNldCBp biBpcnFfc3RhdHVzLA0KPiB3aGljaCBjb3VsZCBiZSBhbiBpbnRlcnJ1cHQgY29udHJvbGxlciBt aXNjb25maWd1cmF0aW9uIG9yIGFuIGludGVycnVwdA0KPiBnZW5lcmF0ZWQgYnkgYW5vdGhlciBk ZXZpY2Ugb24gdGhlIHNhbWUgc2hhcmVkIElSUSBsaW5lLCB3aGljaCBzaG91bGQgYmUNCj4gaGFu ZGxlZCBieSByZXR1cm5pbmcgSVJRX05PTkUuIFNpbmNlIGludGVycnVwdCBoYW5kbGluZyBpcyBh IGxvdyBsZXZlbA0KPiBoYXJkd2FyZSBvcGVyYXRpb24sIEknZCBzdWdnZXN0IGFub3RoZXIgZGVz aWduOg0KPiAtIHB1dCB0aGUgaXJxX2hhbmRsZXJfdCBmdW5jdGlvbiBoZXJlIGluIHRoaXMgZmls ZSBhbmQgaGF2ZSBpdCBkaXJlY3RseQ0KPiAgIGFjY2VzcyB0aGUgaGFyZHdhcmUgcmVnaXN0ZXJz IGFuZCBjaGVjayB0aGUgaW50ZXJydXB0IGJpdHMsDQo+IC0gYWRkIGFuIG10a19qcGVnX2VuY19k b25lKC4uLiwgZW51bSB2YjJfYnVmZmVyX3N0YXRlIHN0YXRlLCBzaXplX3QNCj4gICBwYXlsb2Fk KSwgd2hpY2ggd291bGQgYmUgY2FsbGVkIGZyb20gdGhpcyBsb3cgbGV2ZWwgaW50ZXJydXB0IGhh bmRsZXIgYW5kDQo+ICAgZG8gdGhlIFY0TDIgYnVmZmVyIGFuZCBNMk0gam9iIGhhbmRsaW5nLg0K PiANCj4gV0RZVD8NCmRvbmUuDQo+IA0KPiA+ICsNCj4gPiArdm9pZCBtdGtfanBlZ19lbmNfc2V0 X2ltZ19zaXplKHZvaWQgX19pb21lbSAqYmFzZSwgdTMyIHdpZHRoLCB1MzIgaGVpZ2h0KQ0KPiAN Cj4gSWYgd2UgcGFzcyBzdHJ1Y3QgbXRrX2pwZWdfZGV2IHRvIHRoaXMgZnVuY3Rpb24sIHRoZSB3 aWR0aCBhbmQgaGVpZ2h0DQo+IGFyZ3VtZW50cyB3b3VsZG4ndCBiZSBuZWNlc3NhcnksIGFzIHRo ZXkgY291bGQgYmUgZGlyZWN0bHkgcmV0cmlldmVkIGZyb20NCj4gdGhlIGRyaXZlciBzdGF0ZS4N Cj4gDQo+IFNpbWlsYXIgYWR2aWNlIGFwcGxpZXMgdG8gdGhlIG90aGVyIGZ1bmN0aW9ucyBpbiB0 aGlzIGZpbGUuDQpkb25lLg0KPiANCj4gPiArew0KPiA+ICsJdTMyIHZhbHVlOw0KPiA+ICsNCj4g PiArCXZhbHVlID0gd2lkdGggPDwgMTYgfCBoZWlnaHQ7DQo+ID4gKwl3cml0ZWwodmFsdWUsIGJh c2UgKyBKUEVHX0VOQ19JTUdfU0laRSk7DQo+ID4gK30NCj4gPiArDQo+ID4gK3ZvaWQgbXRrX2pw ZWdfZW5jX3NldF9ibGtfbnVtKHZvaWQgX19pb21lbSAqYmFzZSwgdTMyIGVuY19mb3JtYXQsIHUz MiB3aWR0aCwNCj4gPiArCQkJICAgICAgdTMyIGhlaWdodCkNCj4gPiArew0KPiA+ICsJdTMyIGJs a19udW07DQo+ID4gKwl1MzIgaXNfNDIwOw0KPiA+ICsJdTMyIHBhZGRpbmdfd2lkdGg7DQo+ID4g Kwl1MzIgcGFkZGluZ19oZWlnaHQ7DQo+ID4gKwl1MzIgbHVtYV9ibG9ja3M7DQo+ID4gKwl1MzIg Y2hyb21hX2Jsb2NrczsNCj4gPiArDQo+ID4gKwlpc180MjAgPSAoZW5jX2Zvcm1hdCA9PSBWNEwy X1BJWF9GTVRfTlYxMk0gfHwNCj4gPiArCQkgIGVuY19mb3JtYXQgPT0gVjRMMl9QSVhfRk1UX05W MjFNKSA/IDEgOiAwOw0KPiA+ICsJcGFkZGluZ193aWR0aCA9IHJvdW5kX3VwKHdpZHRoLCAxNik7 DQo+ID4gKwlwYWRkaW5nX2hlaWdodCA9IHJvdW5kX3VwKGhlaWdodCwgaXNfNDIwID8gMTYgOiA4 KTsNCj4gPiArDQo+ID4gKwlsdW1hX2Jsb2NrcyA9IHBhZGRpbmdfd2lkdGggLyA4ICogcGFkZGlu Z19oZWlnaHQgLyA4Ow0KPiA+ICsJaWYgKGlzXzQyMCkNCj4gPiArCQljaHJvbWFfYmxvY2tzID0g bHVtYV9ibG9ja3MgLyA0Ow0KPiA+ICsJZWxzZQ0KPiA+ICsJCWNocm9tYV9ibG9ja3MgPSBsdW1h X2Jsb2NrcyAvIDI7DQo+ID4gKw0KPiA+ICsJYmxrX251bSA9IGx1bWFfYmxvY2tzICsgMiAqIGNo cm9tYV9ibG9ja3MgLSAxOw0KPiA+ICsNCj4gPiArCXdyaXRlbChibGtfbnVtLCBiYXNlICsgSlBF R19FTkNfQkxLX05VTSk7DQo+ID4gK30NCj4gDQo+IE15IGNvbW1lbnRzIGZvciB0aGlzIGZ1bmN0 aW9uIGZyb20gdjcgaGF2ZW4ndCBiZWVuIGFkZHJlc3NlZC4NCmRvbmUuDQo+IA0KPiA+ICsNCj4g PiArdm9pZCBtdGtfanBlZ19lbmNfc2V0X3N0cmlkZSh2b2lkIF9faW9tZW0gKmJhc2UsIHUzMiBl bmNfZm9ybWF0LCB1MzIgd2lkdGgsDQo+ID4gKwkJCSAgICAgdTMyIGhlaWdodCwgdTMyIGJ5dGVz cGVybGluZSkNCj4gPiArew0KPiA+ICsJdTMyIGltZ19zdHJpZGU7DQo+ID4gKwl1MzIgbWVtX3N0 cmlkZTsNCj4gPiArDQo+ID4gKwlpZiAoZW5jX2Zvcm1hdCA9PSBWNEwyX1BJWF9GTVRfTlYxMk0g fHwNCj4gPiArCSAgICBlbmNfZm9ybWF0ID09IFY0TDJfUElYX0ZNVF9OVjIxTSkgew0KPiA+ICsJ CWltZ19zdHJpZGUgPSByb3VuZF91cCh3aWR0aCwgMTYpOw0KPiA+ICsJCW1lbV9zdHJpZGUgPSBi eXRlc3BlcmxpbmU7DQo+ID4gKwl9IGVsc2Ugew0KPiA+ICsJCWltZ19zdHJpZGUgPSByb3VuZF91 cCh3aWR0aCAqIDIsIDMyKTsNCj4gPiArCQltZW1fc3RyaWRlID0gaW1nX3N0cmlkZTsNCj4gPiAr CX0NCj4gPiArDQo+ID4gKwl3cml0ZWwoaW1nX3N0cmlkZSwgYmFzZSArIEpQRUdfRU5DX0lNR19T VFJJREUpOw0KPiA+ICsJd3JpdGVsKG1lbV9zdHJpZGUsIGJhc2UgKyBKUEVHX0VOQ19TVFJJREUp Ow0KPiA+ICt9DQo+ID4gKw0KPiANCj4gTXkgY29tbWVudHMgZm9yIHRoaXMgZnVuY3Rpb24gZnJv bSB2NyBoYXZlbid0IGJlZW4gYWRkcmVzc2VkLg0KZG9uZS4NCj4gDQo+ID4gK3ZvaWQgbXRrX2pw ZWdfZW5jX3NldF9zcmNfYWRkcih2b2lkIF9faW9tZW0gKmJhc2UsIHUzMiBzcmNfYWRkciwNCj4g PiArCQkJICAgICAgIHUzMiBwbGFuZV9pbmRleCkNCj4gPiArew0KPiA+ICsJaWYgKCFwbGFuZV9p bmRleCkNCj4gPiArCQl3cml0ZWwoc3JjX2FkZHIsIGJhc2UgKyBKUEVHX0VOQ19TUkNfTFVNQV9B RERSKTsNCj4gPiArCWVsc2UNCj4gPiArCQl3cml0ZWwoc3JjX2FkZHIsIGJhc2UgKyBKUEVHX0VO Q19TUkNfQ0hST01BX0FERFIpOw0KPiANCj4gRG8gd2UgbmVlZCB0aGlzIHBsYW5lX2luZGV4IGlm IHdlIG9ubHkgaGF2ZSAyIHBsYW5lcz8gQWxzbywgZm9yIGludGVybGVhdmVkDQo+IGZvcm1hdHMs IGxpa2UgWVVZViwgd2hhdCBzaG91bGQgdGhlIExVTUEgYW5kIENIUk9NQSByZWdpc3RlcnMgYmUg c2V0IHRvPw0KSWYgdGhlIGZvcm1hdCBpcyBZVVlWLCB0aGVyZSBpcyBubyBuZWVkIHRvIHNldCBD SFJPTUEgcmVnaXN0ZXIuIEhhcmR3YXJlDQpjYW4gY29tcHV0ZSB0aGUgQ0hST01BIGFkZHJlc3Mg ZnJvbSB0aGUgTFVNQSBhZGRyZXNzIGl0c2VsZi4NCj4gDQo+ID4gK30NCj4gPiArDQo+ID4gK3Zv aWQgbXRrX2pwZWdfZW5jX3NldF9kc3RfYWRkcih2b2lkIF9faW9tZW0gKmJhc2UsIHUzMiBkc3Rf YWRkciwNCj4gPiArCQkJICAgICAgIHUzMiBzdGFsbF9zaXplLCB1MzIgaW5pdF9vZmZzZXQsDQo+ ID4gKwkJCSAgICAgICB1MzIgb2Zmc2V0X21hc2spDQo+ID4gK3sNCj4gPiArCXdyaXRlbChpbml0 X29mZnNldCAmIH4weGYsIGJhc2UgKyBKUEVHX0VOQ19PRkZTRVRfQUREUik7DQo+ID4gKwl3cml0 ZWwob2Zmc2V0X21hc2sgJiAweGYsIGJhc2UgKyBKUEVHX0VOQ19CWVRFX09GRlNFVF9NQVNLKTsN Cj4gPiArCXdyaXRlbChkc3RfYWRkciAmIH4weGYsIGJhc2UgKyBKUEVHX0VOQ19EU1RfQUREUjAp Ow0KPiA+ICsJd3JpdGVsKChkc3RfYWRkciArIHN0YWxsX3NpemUpICYgfjB4ZiwgYmFzZSArIEpQ RUdfRU5DX1NUQUxMX0FERFIwKTsNCj4gPiArfQ0KPiA+ICsNCj4gPiArc3RhdGljIHZvaWQgbXRr X2pwZWdfZW5jX3NldF9xdWFsaXR5KHZvaWQgX19pb21lbSAqYmFzZSwgdTMyIHF1YWxpdHkpDQo+ ID4gK3sNCj4gPiArCXUzMiB2YWx1ZTsNCj4gPiArCXUzMiBpLCBlbmNfcXVhbGl0eTsNCj4gPiAr DQo+ID4gKwllbmNfcXVhbGl0eSA9IG10a19qcGVnX2VuY19xdWFsaXR5WzBdLmhhcmR3YXJlX3Zh bHVlOw0KPiA+ICsJZm9yIChpID0gMDsgaSA8IEFSUkFZX1NJWkUobXRrX2pwZWdfZW5jX3F1YWxp dHkpOyBpKyspIHsNCj4gPiArCQlpZiAocXVhbGl0eSA8PSBtdGtfanBlZ19lbmNfcXVhbGl0eVtp XS5xdWFsaXR5X3BhcmFtKSB7DQo+ID4gKwkJCWVuY19xdWFsaXR5ID0gbXRrX2pwZWdfZW5jX3F1 YWxpdHlbaV0uaGFyZHdhcmVfdmFsdWU7DQo+ID4gKwkJCWJyZWFrOw0KPiA+ICsJCX0NCj4gPiAr CX0NCj4gPiArDQo+ID4gKwl2YWx1ZSA9IHJlYWRsKGJhc2UgKyBKUEVHX0VOQ19RVUFMSVRZKTsN Cj4gDQo+IG5pdDogSXMgaXQgc3RpbGwgbmVjZXNzYXJ5IHRvIHJlYWQgdGhlIHJlZ2lzdGVyIGhl cmU/IFR5cGljYWxseSB0aGUgcmVzZXJ2ZWQNCj4gYml0cyB3b3VsZCBiZSBkZWZpbmVkIGFzIFNC WiAoc2hvdWxkIGJlIHplcm8pIGFuZCBpdCBzaG91bGQgYmUgc2FmZSB0byBqdXN0DQo+IHdyaXRl IDAgdG8gdGhlbS4NCnllcyxyZW1vdmVkIGl0Lg0KPiANCj4gPiArCXZhbHVlID0gKHZhbHVlICYg SlBFR19FTkNfUVVBTElUWV9NQVNLKSB8IGVuY19xdWFsaXR5Ow0KPiA+ICsJd3JpdGVsKHZhbHVl LCBiYXNlICsgSlBFR19FTkNfUVVBTElUWSk7DQo+ID4gK30NCj4gPiArDQo+ID4gK3N0YXRpYyB2 b2lkIG10a19qcGVnX2VuY19zZXRfY3RybCh2b2lkIF9faW9tZW0gKmJhc2UsIHUzMiBlbmNfZm9y bWF0LA0KPiA+ICsJCQkJICBib29sIGV4aWZfZW4sIHUzMiByZXN0YXJ0X2ludGVydmFsKQ0KPiA+ ICt7DQo+ID4gKwl1MzIgdmFsdWU7DQo+ID4gKw0KPiA+ICsJdmFsdWUgPSByZWFkbChiYXNlICsg SlBFR19FTkNfQ1RSTCk7DQo+IA0KPiBuaXQ6IElzIGl0IHN0aWxsIG5lY2Vzc2FyeSB0byByZWFk IHRoZSByZWdpc3RlciBoZXJlPw0KSSB0aGluayBpdCBpcyBuZWNlc3NhcnkgdG8gcmVhZCB0aGlz IHJlZ2lzdGVyLkJlY2F1c2UgdGhhdCB0aGUgZGVmYXVsdA0KdmFsdWUgb2YgSlBFR19FTkNfQ1RS TCdzIGJpdFsyXShlbmFibGUgaW50ZXJydXB0KSBpcyAxLg0KPiANCj4gPiArCXZhbHVlICY9IH5K UEVHX0VOQ19DVFJMX1lVVl9GT1JNQVRfTUFTSzsNCj4gPiArCXZhbHVlIHw9IChlbmNfZm9ybWF0 ICYgMykgPDwgMzsNCj4gPiArCWlmIChleGlmX2VuKQ0KPiA+ICsJCXZhbHVlIHw9IEpQRUdfRU5D X0NUUkxfRklMRV9GT1JNQVRfQklUOw0KPiA+ICsJZWxzZQ0KPiA+ICsJCXZhbHVlICY9IH5KUEVH X0VOQ19DVFJMX0ZJTEVfRk9STUFUX0JJVDsNCj4gPiArCWlmIChyZXN0YXJ0X2ludGVydmFsKQ0K PiA+ICsJCXZhbHVlIHw9IEpQRUdfRU5DX0NUUkxfUkVTVEFSVF9FTl9CSVQ7DQo+ID4gKwllbHNl DQo+ID4gKwkJdmFsdWUgJj0gfkpQRUdfRU5DX0NUUkxfUkVTVEFSVF9FTl9CSVQ7DQo+ID4gKwl3 cml0ZWwodmFsdWUsIGJhc2UgKyBKUEVHX0VOQ19DVFJMKTsNCj4gPiArfQ0KPiA+ICsNCj4gDQo+ IEJlc3QgcmVnYXJkcywNCj4gVG9tYXN6DQpCZXN0IFJlZ2FyZHMsDQpYaWEgSmlhbmcNCg0K From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.5 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, USER_AGENT_SANE_2 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 45793C433DF for ; Fri, 24 Jul 2020 09:58:29 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EB76B20674 for ; Fri, 24 Jul 2020 09:58:28 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="2BYUe5Dc"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="svDIOula" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EB76B20674 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Date:To:From: Subject:Message-ID:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=axzLIkw+zdqLCPLA8L6yoiuM/POoiS6CMrusOApn54Y=; b=2BYUe5DcjP6NM7nT10+x9NBm+ /ICkcRtJ4lmYxKjNZbXXqVRFCUGFCY44Zj0KgkOk0nTvOU3fk1bjkkqSobtIsHASefHl/ZNKNa9ef GtdF+ljAQwOrx5xJJFFSwpASXKBhkgGCSWx62EBOwHwrZRkmNwFNEkY1t39vjOfi4/61WhFeNWgBm 1vlJ5TaEPfmof4AdozcSeIhYc1s2KMCM9fS1DSKl6LNa8h3ZFa69nPClwEOFAobYhQxIYytookIND eMMYmck08CNnWlaBhnlbSZJ8ZG7qHRHmrhljmEZnXLK4fNvM7DfjHu6d+nGyzUbffdrHAMzr9PNOU 5Rac/PkmQ==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jyuT2-0005hV-AS; Fri, 24 Jul 2020 09:58:16 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jyuSx-0005g9-Tf; Fri, 24 Jul 2020 09:58:14 +0000 X-UUID: ca46aa9e6e394bc5a6e3366ad7496073-20200724 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:MIME-Version:Content-Type:References:In-Reply-To:Date:CC:To:From:Subject:Message-ID; bh=X91yDgTfDA2byKhgCyPcKRjLhJli3RxZLlwdVJHhJRM=; b=svDIOulaCtcBzwjEaNKnOl8m7+hmPJiFtjOF0yeU4mQ8aDAppB87Kk+gGtS3tdfqMyecZ3/yAfZL4EQvt8ZoAgqFKVTI/cVSEYbg/0h9Ha3xx/bLWpAYI+2NinXdqSFE2cT/kVetS2vnVd5Z7x/OIajrJ5w9fMllXmouZEglq5I=; X-UUID: ca46aa9e6e394bc5a6e3366ad7496073-20200724 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 2027073142; Fri, 24 Jul 2020 01:57:40 -0800 Received: from MTKMBS31N1.mediatek.inc (172.27.4.69) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 24 Jul 2020 02:55:40 -0700 Received: from MTKCAS32.mediatek.inc (172.27.4.184) by MTKMBS31N1.mediatek.inc (172.27.4.69) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 24 Jul 2020 17:55:38 +0800 Received: from [10.17.3.153] (10.17.3.153) by MTKCAS32.mediatek.inc (172.27.4.170) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 24 Jul 2020 17:55:37 +0800 Message-ID: <1595584468.27238.43.camel@mhfsdcap03> Subject: Re: [PATCH RESEND v9 18/18] media: platform: Add jpeg enc feature From: Xia Jiang To: Tomasz Figa Date: Fri, 24 Jul 2020 17:54:28 +0800 In-Reply-To: <20200611184640.GC8694@chromium.org> References: <20200604090553.10861-1-xia.jiang@mediatek.com> <20200604090553.10861-20-xia.jiang@mediatek.com> <20200611184640.GC8694@chromium.org> X-Mailer: Evolution 3.10.4-0ubuntu2 MIME-Version: 1.0 X-TM-SNTS-SMTP: 02F87A8808ED5D525EB80BC28A01270FA46BF0D424768C6E6D17C33DD07B58E32000:8 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200724_055812_225117_21210B92 X-CRM114-Status: GOOD ( 34.78 ) X-BeenThere: linux-mediatek@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: drinkcat@chromium.org, devicetree@vger.kernel.org, mojahsu@chromium.org, srv_heupstream@mediatek.com, Rick Chang , senozhatsky@chromium.org, linux-kernel@vger.kernel.org, maoguang.meng@mediatek.com, Mauro Carvalho Chehab , sj.huang@mediatek.com, Rob Herring , Matthias Brugger , Hans Verkuil , linux-mediatek@lists.infradead.org, Marek Szyprowski , linux-arm-kernel@lists.infradead.org, linux-media@vger.kernel.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "Linux-mediatek" Errors-To: linux-mediatek-bounces+linux-mediatek=archiver.kernel.org@lists.infradead.org On Thu, 2020-06-11 at 18:46 +0000, Tomasz Figa wrote: > Hi Xia, > > On Thu, Jun 04, 2020 at 05:05:53PM +0800, Xia Jiang wrote: > > Add mtk jpeg encode v4l2 driver based on jpeg decode, because that jpeg > > decode and encode have great similarities with function operation. > > > > Signed-off-by: Xia Jiang > > --- > > v9: add member variable(struct v4l2_rect) in out_q structure for storing > > the active crop information. > > move the renaming exsting functions/defines/variables to a separate patch. > > --- > > drivers/media/platform/mtk-jpeg/Makefile | 5 +- > > .../media/platform/mtk-jpeg/mtk_jpeg_core.c | 845 +++++++++++++++--- > > .../media/platform/mtk-jpeg/mtk_jpeg_core.h | 44 +- > > .../media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c | 193 ++++ > > .../media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h | 123 +++ > > 5 files changed, 1084 insertions(+), 126 deletions(-) > > create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c > > create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h > > > > Thank you for the patch. Please see my comments inline. Dear Tomasz, Thank you for your comments. I have uploaded the v10 version which contains the changes you mentioned. > > [snip] > > +static int mtk_jpeg_enc_querycap(struct file *file, void *priv, > > + struct v4l2_capability *cap) > > +{ > > + struct mtk_jpeg_dev *jpeg = video_drvdata(file); > > + > > + strscpy(cap->driver, MTK_JPEG_NAME, sizeof(cap->driver)); > > + strscpy(cap->card, MTK_JPEG_NAME " encoder", sizeof(cap->card)); > > + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", > > + dev_name(jpeg->dev)); > > + > > + return 0; > > +} > > I can see that this function differs from mtk_jpeg_dec_querycap() only with > the " encoder" string. Perhaps they could be merged? done. > > > + > > static int mtk_jpeg_dec_querycap(struct file *file, void *priv, > > struct v4l2_capability *cap) > > { > > @@ -88,6 +157,54 @@ static int mtk_jpeg_dec_querycap(struct file *file, void *priv, > > return 0; > > } > > > > +static int vidioc_jpeg_enc_s_ctrl(struct v4l2_ctrl *ctrl) > > +{ > > + struct mtk_jpeg_ctx *ctx = ctrl_to_ctx(ctrl); > > + > > + switch (ctrl->id) { > > + case V4L2_CID_JPEG_RESTART_INTERVAL: > > + ctx->restart_interval = ctrl->val; > > + break; > > + case V4L2_CID_JPEG_COMPRESSION_QUALITY: > > + ctx->enc_quality = ctrl->val; > > + break; > > + case V4L2_CID_JPEG_ACTIVE_MARKER: > > + ctx->enable_exif = ctrl->val & V4L2_JPEG_ACTIVE_MARKER_APP1 ? > > + true : false; > > nit: If ctx->enable_exif is of the bool type, the ternary operator could be > removed, because any non-zero value is implicitly turned into 1, as per [1]. > > [1] https://www.kernel.org/doc/html/v5.6/process/coding-style.html#using-bool done. > > [snip] > > +static int mtk_jpeg_enc_enum_fmt_vid_cap(struct file *file, void *priv, > > + struct v4l2_fmtdesc *f) > > +{ > > + return mtk_jpeg_enum_fmt(mtk_jpeg_enc_formats, > > + MTK_JPEG_ENC_NUM_FORMATS, f, > > + MTK_JPEG_FMT_FLAG_ENC_CAPTURE); > > +} > > + > > static int mtk_jpeg_dec_enum_fmt_vid_cap(struct file *file, void *priv, > > struct v4l2_fmtdesc *f) > > { > > @@ -117,6 +242,14 @@ static int mtk_jpeg_dec_enum_fmt_vid_cap(struct file *file, void *priv, > > MTK_JPEG_FMT_FLAG_DEC_CAPTURE); > > } > > > > +static int mtk_jpeg_enc_enum_fmt_vid_out(struct file *file, void *priv, > > + struct v4l2_fmtdesc *f) > > +{ > > + return mtk_jpeg_enum_fmt(mtk_jpeg_enc_formats, > > + MTK_JPEG_ENC_NUM_FORMATS, f, > > + MTK_JPEG_FMT_FLAG_ENC_OUTPUT); > > Do we need separate implementations of these? "formats" and "num_formats" > could be specified by the match data struct and used in a generic function. done. > > Also, do we need separate flags for ENC_OUTPUT/CAPTURE and > DEC_OUTPUT/CAPTURE? done > > > +} > > + > > static int mtk_jpeg_dec_enum_fmt_vid_out(struct file *file, void *priv, > > struct v4l2_fmtdesc *f) > > { > > @@ -132,93 +265,66 @@ mtk_jpeg_get_q_data(struct mtk_jpeg_ctx *ctx, enum v4l2_buf_type type) > > return &ctx->cap_q; > > } > > > > -static struct mtk_jpeg_fmt *mtk_jpeg_find_format(struct mtk_jpeg_ctx *ctx, > > - u32 pixelformat, > > +static struct mtk_jpeg_fmt *mtk_jpeg_find_format(u32 pixelformat, > > unsigned int fmt_type) > > { > > - unsigned int k, fmt_flag; > > + unsigned int k; > > + struct mtk_jpeg_fmt *fmt; > > > > - fmt_flag = (fmt_type == MTK_JPEG_FMT_TYPE_OUTPUT) ? > > - MTK_JPEG_FMT_FLAG_DEC_OUTPUT : > > - MTK_JPEG_FMT_FLAG_DEC_CAPTURE; > > + for (k = 0; k < MTK_JPEG_ENC_NUM_FORMATS; k++) { > > + fmt = &mtk_jpeg_enc_formats[k]; > > + > > + if (fmt->fourcc == pixelformat && fmt->flags & fmt_type) > > + return fmt; > > + } > > > > for (k = 0; k < MTK_JPEG_DEC_NUM_FORMATS; k++) { > > - struct mtk_jpeg_fmt *fmt = &mtk_jpeg_dec_formats[k]; > > + fmt = &mtk_jpeg_dec_formats[k]; > > > > - if (fmt->fourcc == pixelformat && fmt->flags & fmt_flag) > > + if (fmt->fourcc == pixelformat && fmt->flags & fmt_type) > > return fmt; > > } > > We should only need to iterate through one of the arrays. My suggestion > above about making "formats" and "num_formats" a member of the match data > should take care of this one too. done. > > > > > return NULL; > > } > > > > -static void mtk_jpeg_adjust_fmt_mplane(struct mtk_jpeg_ctx *ctx, > > - struct v4l2_format *f) > > -{ > > - struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; > > - struct mtk_jpeg_q_data *q_data; > > - int i; > > - > > - q_data = mtk_jpeg_get_q_data(ctx, f->type); > > - > > - pix_mp->width = q_data->w; > > - pix_mp->height = q_data->h; > > - pix_mp->pixelformat = q_data->fmt->fourcc; > > - pix_mp->num_planes = q_data->fmt->colplanes; > > - > > - for (i = 0; i < pix_mp->num_planes; i++) { > > - pix_mp->plane_fmt[i].bytesperline = q_data->bytesperline[i]; > > - pix_mp->plane_fmt[i].sizeimage = q_data->sizeimage[i]; > > - } > > -} > > - > > -static int mtk_jpeg_try_fmt_mplane(struct v4l2_format *f, > > - struct mtk_jpeg_fmt *fmt, > > - struct mtk_jpeg_ctx *ctx, int q_type) > > +static int vidioc_try_fmt(struct v4l2_format *f, struct mtk_jpeg_fmt *fmt) > > The name is a bit misleading, because it's suggesting that it's the > vidioc_try_fmt callback, but it's just an internal helper. I think the > original name was fine. changed it to original name. > > > { > > struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; > > int i; > > > > pix_mp->field = V4L2_FIELD_NONE; > > - > > - if (ctx->state != MTK_JPEG_INIT) { > > - mtk_jpeg_adjust_fmt_mplane(ctx, f); > > - return 0; > > - } > > Is it okay to remove this? My understanding is that it prevented changing > the format while streaming, which should is as expected. mtk_jpeg_g_fmt_vid_mplane() does the same thing, so use it to replace mtk_jpeg_adjust_fmt_mplane. > > > - > > pix_mp->num_planes = fmt->colplanes; > > pix_mp->pixelformat = fmt->fourcc; > > > > - if (q_type == MTK_JPEG_FMT_TYPE_OUTPUT) { > > - struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[0]; > > - > > + if (fmt->fourcc == V4L2_PIX_FMT_JPEG) { > > pix_mp->height = clamp(pix_mp->height, MTK_JPEG_MIN_HEIGHT, > > MTK_JPEG_MAX_HEIGHT); > > pix_mp->width = clamp(pix_mp->width, MTK_JPEG_MIN_WIDTH, > > MTK_JPEG_MAX_WIDTH); > > - > > - pfmt->bytesperline = 0; > > - /* Source size must be aligned to 128 */ > > - pfmt->sizeimage = round_up(pfmt->sizeimage, 128); > > - if (pfmt->sizeimage == 0) > > - pfmt->sizeimage = MTK_JPEG_DEFAULT_SIZEIMAGE; > > - return 0; > > + pix_mp->plane_fmt[0].bytesperline = 0; > > + pix_mp->plane_fmt[0].sizeimage = > > + round_up(pix_mp->plane_fmt[0].sizeimage, 128); > > + if (pix_mp->plane_fmt[0].sizeimage == 0) > > + pix_mp->plane_fmt[0].sizeimage = > > + MTK_JPEG_DEFAULT_SIZEIMAGE; > > + } else { > > + pix_mp->height = clamp(round_up(pix_mp->height, fmt->v_align), > > + MTK_JPEG_MIN_HEIGHT, > > + MTK_JPEG_MAX_HEIGHT); > > + pix_mp->width = clamp(round_up(pix_mp->width, fmt->h_align), > > + MTK_JPEG_MIN_WIDTH, MTK_JPEG_MAX_WIDTH); > > + for (i = 0; i < pix_mp->num_planes; i++) { > > + struct v4l2_plane_pix_format *pfmt = > > + &pix_mp->plane_fmt[i]; > > + u32 stride = pix_mp->width * fmt->h_sample[i] / 4; > > + u32 h = pix_mp->height * fmt->v_sample[i] / 4; > > + > > + pfmt->bytesperline = stride; > > + pfmt->sizeimage = stride * h; > > + } > > } > > > > - /* type is MTK_JPEG_FMT_TYPE_CAPTURE */ > > - pix_mp->height = clamp(round_up(pix_mp->height, fmt->v_align), > > - MTK_JPEG_MIN_HEIGHT, MTK_JPEG_MAX_HEIGHT); > > - pix_mp->width = clamp(round_up(pix_mp->width, fmt->h_align), > > - MTK_JPEG_MIN_WIDTH, MTK_JPEG_MAX_WIDTH); > > - > > - for (i = 0; i < fmt->colplanes; i++) { > > - struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[i]; > > - u32 stride = pix_mp->width * fmt->h_sample[i] / 4; > > - u32 h = pix_mp->height * fmt->v_sample[i] / 4; > > - > > - pfmt->bytesperline = stride; > > - pfmt->sizeimage = stride * h; > > - } > > return 0; > > Are all the changes above needed for the encoder? If I'm looking correctly, > they're mostly refactoring and should be done in a separate patch. However, > I don't see any big issue with the existing coding style in this function, > so perhaps the refactoring could be avoided. In order to compatible jpeg encoder, use the fourcc to distinguish different types as you mentioned before. > > > } > > > > @@ -271,14 +377,35 @@ static int mtk_jpeg_g_fmt_vid_mplane(struct file *file, void *priv, > > return 0; > > } > > > > +static int mtk_jpeg_enc_try_fmt_vid_cap_mplane(struct file *file, void *priv, > > + struct v4l2_format *f) > > +{ > > + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); > > + struct mtk_jpeg_fmt *fmt; > > + > > + fmt = mtk_jpeg_find_format(f->fmt.pix_mp.pixelformat, > > + MTK_JPEG_FMT_FLAG_ENC_CAPTURE); > > + if (!fmt) > > + fmt = ctx->cap_q.fmt; > > + > > + v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n", > > + f->type, > > + (fmt->fourcc & 0xff), > > + (fmt->fourcc >> 8 & 0xff), > > + (fmt->fourcc >> 16 & 0xff), > > + (fmt->fourcc >> 24 & 0xff)); > > + > > + return vidioc_try_fmt(f, fmt); > > +} > > Is there really anything encoder-specific in this function? Could the same > function as the decoder be used instead? done. > > > + > > static int mtk_jpeg_dec_try_fmt_vid_cap_mplane(struct file *file, void *priv, > > struct v4l2_format *f) > > { > > struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); > > struct mtk_jpeg_fmt *fmt; > > > > - fmt = mtk_jpeg_find_format(ctx, f->fmt.pix_mp.pixelformat, > > - MTK_JPEG_FMT_TYPE_CAPTURE); > > + fmt = mtk_jpeg_find_format(f->fmt.pix_mp.pixelformat, > > + MTK_JPEG_FMT_FLAG_DEC_CAPTURE); > > if (!fmt) > > fmt = ctx->cap_q.fmt; > > > > @@ -289,7 +416,33 @@ static int mtk_jpeg_dec_try_fmt_vid_cap_mplane(struct file *file, void *priv, > > (fmt->fourcc >> 16 & 0xff), > > (fmt->fourcc >> 24 & 0xff)); > > > > - return mtk_jpeg_try_fmt_mplane(f, fmt, ctx, MTK_JPEG_FMT_TYPE_CAPTURE); > > + if (ctx->state != MTK_JPEG_INIT) { > > + mtk_jpeg_g_fmt_vid_mplane(file, priv, f); > > + return 0; > > + } > > Is this really limited to the decoder? In general currently we don't > support changing the resolution from the userspace when streaming is > started and it applies to both encoder and decoder. done. > > > + > > + return vidioc_try_fmt(f, fmt); > > +} > > + > > +static int mtk_jpeg_enc_try_fmt_vid_out_mplane(struct file *file, void *priv, > > + struct v4l2_format *f) > > +{ > > + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); > > + struct mtk_jpeg_fmt *fmt; > > + > > + fmt = mtk_jpeg_find_format(f->fmt.pix_mp.pixelformat, > > + MTK_JPEG_FMT_FLAG_ENC_OUTPUT); > > + if (!fmt) > > + fmt = ctx->out_q.fmt; > > + > > + v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n", > > + f->type, > > + (fmt->fourcc & 0xff), > > + (fmt->fourcc >> 8 & 0xff), > > + (fmt->fourcc >> 16 & 0xff), > > + (fmt->fourcc >> 24 & 0xff)); > > + > > + return vidioc_try_fmt(f, fmt); > > } > > Ditto. done. > > > > > static int mtk_jpeg_dec_try_fmt_vid_out_mplane(struct file *file, void *priv, > > @@ -298,8 +451,8 @@ static int mtk_jpeg_dec_try_fmt_vid_out_mplane(struct file *file, void *priv, > > struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); > > struct mtk_jpeg_fmt *fmt; > > > > - fmt = mtk_jpeg_find_format(ctx, f->fmt.pix_mp.pixelformat, > > - MTK_JPEG_FMT_TYPE_OUTPUT); > > + fmt = mtk_jpeg_find_format(f->fmt.pix_mp.pixelformat, > > + MTK_JPEG_FMT_FLAG_DEC_OUTPUT); > > if (!fmt) > > fmt = ctx->out_q.fmt; > > > > @@ -310,17 +463,21 @@ static int mtk_jpeg_dec_try_fmt_vid_out_mplane(struct file *file, void *priv, > > (fmt->fourcc >> 16 & 0xff), > > (fmt->fourcc >> 24 & 0xff)); > > > > - return mtk_jpeg_try_fmt_mplane(f, fmt, ctx, MTK_JPEG_FMT_TYPE_OUTPUT); > > + if (ctx->state != MTK_JPEG_INIT) { > > + mtk_jpeg_g_fmt_vid_mplane(file, priv, f); > > + return 0; > > + } > > Ditto. done. > > > + > > + return vidioc_try_fmt(f, fmt); > > } > > > > static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx, > > - struct v4l2_format *f) > > + struct v4l2_format *f, unsigned int fmt_type) > > { > > struct vb2_queue *vq; > > struct mtk_jpeg_q_data *q_data = NULL; > > struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; > > struct mtk_jpeg_dev *jpeg = ctx->jpeg; > > - unsigned int f_type; > > int i; > > > > vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); > > @@ -334,12 +491,11 @@ static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx, > > return -EBUSY; > > } > > > > - f_type = V4L2_TYPE_IS_OUTPUT(f->type) ? > > - MTK_JPEG_FMT_TYPE_OUTPUT : MTK_JPEG_FMT_TYPE_CAPTURE; > > - > > - q_data->fmt = mtk_jpeg_find_format(ctx, pix_mp->pixelformat, f_type); > > + q_data->fmt = mtk_jpeg_find_format(pix_mp->pixelformat, fmt_type); > > q_data->w = pix_mp->width; > > q_data->h = pix_mp->height; > > + q_data->crop_rect.width = pix_mp->width; > > + q_data->crop_rect.height = pix_mp->height; > > ctx->colorspace = pix_mp->colorspace; > > ctx->ycbcr_enc = pix_mp->ycbcr_enc; > > ctx->xfer_func = pix_mp->xfer_func; > > @@ -365,6 +521,19 @@ static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx, > > return 0; > > } > > > > +static int mtk_jpeg_enc_s_fmt_vid_out_mplane(struct file *file, void *priv, > > + struct v4l2_format *f) > > +{ > > + int ret; > > + > > + ret = mtk_jpeg_enc_try_fmt_vid_out_mplane(file, priv, f); > > + if (ret) > > + return ret; > > + > > + return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f, > > + MTK_JPEG_FMT_FLAG_ENC_OUTPUT); > > +} > > + > > static int mtk_jpeg_dec_s_fmt_vid_out_mplane(struct file *file, void *priv, > > struct v4l2_format *f) > > { > > @@ -374,7 +543,21 @@ static int mtk_jpeg_dec_s_fmt_vid_out_mplane(struct file *file, void *priv, > > if (ret) > > return ret; > > > > - return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f); > > + return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f, > > + MTK_JPEG_FMT_FLAG_DEC_OUTPUT); > > +} > > + > > +static int mtk_jpeg_enc_s_fmt_vid_cap_mplane(struct file *file, void *priv, > > + struct v4l2_format *f) > > +{ > > + int ret; > > + > > + ret = mtk_jpeg_enc_try_fmt_vid_cap_mplane(file, priv, f); > > + if (ret) > > + return ret; > > + > > + return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f, > > + MTK_JPEG_FMT_FLAG_ENC_CAPTURE); > > } > > > > static int mtk_jpeg_dec_s_fmt_vid_cap_mplane(struct file *file, void *priv, > > @@ -386,7 +569,8 @@ static int mtk_jpeg_dec_s_fmt_vid_cap_mplane(struct file *file, void *priv, > > if (ret) > > return ret; > > > > - return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f); > > + return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f, > > + MTK_JPEG_FMT_FLAG_DEC_CAPTURE); > > } > > Is it really necessary to have separate variants of the above functions for > decoder and encoder? done. > > > > > static void mtk_jpeg_queue_src_chg_event(struct mtk_jpeg_ctx *ctx) > > @@ -411,6 +595,29 @@ static int mtk_jpeg_subscribe_event(struct v4l2_fh *fh, > > return v4l2_ctrl_subscribe_event(fh, sub); > > } > > > > +static int mtk_jpeg_enc_g_selection(struct file *file, void *priv, > > + struct v4l2_selection *s) > > +{ > > + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); > > + > > + if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) > > + return -EINVAL; > > + > > + switch (s->target) { > > + case V4L2_SEL_TGT_CROP: > > + case V4L2_SEL_TGT_CROP_BOUNDS: > > + case V4L2_SEL_TGT_CROP_DEFAULT: > > + s->r.width = ctx->out_q.w; > > + s->r.height = ctx->out_q.h; > > + s->r.left = 0; > > + s->r.top = 0; > > Is this really correct? The function seems to be returning the full frame > size regardless of the selection target. For BOUNDS and DEFAULTS this would > be the correct behavior indeed, but CROP should return the active crop > rectangle, as set by S_SELECTION. done. > > > + break; > > + default: > > + return -EINVAL; > > + } > > + return 0; > > +} > > + > > static int mtk_jpeg_dec_g_selection(struct file *file, void *priv, > > struct v4l2_selection *s) > > { > > @@ -440,6 +647,29 @@ static int mtk_jpeg_dec_g_selection(struct file *file, void *priv, > > return 0; > > } > > > > +static int mtk_jpeg_enc_s_selection(struct file *file, void *priv, > > + struct v4l2_selection *s) > > +{ > > + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); > > + > > + if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) > > + return -EINVAL; > > + > > + switch (s->target) { > > + case V4L2_SEL_TGT_CROP: > > + s->r.left = 0; > > + s->r.top = 0; > > + s->r.width = min(s->r.width, ctx->out_q.w); > > + s->r.height = min(s->r.height, ctx->out_q.h); > > + ctx->out_q.crop_rect = s->r; > > + break; > > + default: > > + return -EINVAL; > > + } > > + > > + return 0; > > +} > > + > > static int mtk_jpeg_dec_s_selection(struct file *file, void *priv, > > struct v4l2_selection *s) > > { > > @@ -484,6 +714,33 @@ static int mtk_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) > > return v4l2_m2m_qbuf(file, fh->m2m_ctx, buf); > > } > > > > +static const struct v4l2_ioctl_ops mtk_jpeg_enc_ioctl_ops = { > > + .vidioc_querycap = mtk_jpeg_enc_querycap, > > + .vidioc_enum_fmt_vid_cap = mtk_jpeg_enc_enum_fmt_vid_cap, > > + .vidioc_enum_fmt_vid_out = mtk_jpeg_enc_enum_fmt_vid_out, > > + .vidioc_try_fmt_vid_cap_mplane = mtk_jpeg_enc_try_fmt_vid_cap_mplane, > > + .vidioc_try_fmt_vid_out_mplane = mtk_jpeg_enc_try_fmt_vid_out_mplane, > > + .vidioc_g_fmt_vid_cap_mplane = mtk_jpeg_g_fmt_vid_mplane, > > + .vidioc_g_fmt_vid_out_mplane = mtk_jpeg_g_fmt_vid_mplane, > > + .vidioc_s_fmt_vid_cap_mplane = mtk_jpeg_enc_s_fmt_vid_cap_mplane, > > + .vidioc_s_fmt_vid_out_mplane = mtk_jpeg_enc_s_fmt_vid_out_mplane, > > + .vidioc_qbuf = mtk_jpeg_qbuf, > > Not directly a comment for this patch, but since the previous patch removed > the LAST_FRAME handling, wouldn't it be enough to just use v4l2_m2m_qbuf() > as this callback? yes,done. > > [snip] > > +static void mtk_jpeg_enc_buf_queue(struct vb2_buffer *vb) > > +{ > > + struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); > > + struct mtk_jpeg_dev *jpeg = ctx->jpeg; > > + > > + v4l2_dbg(2, debug, &jpeg->v4l2_dev, "(%d) buf_q id=%d, vb=%p\n", > > + vb->vb2_queue->type, vb->index, vb); > > + > > + v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, to_vb2_v4l2_buffer(vb)); > > +} > > + > > static void mtk_jpeg_dec_buf_queue(struct vb2_buffer *vb) > > { > > struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); > > @@ -664,6 +932,15 @@ static struct vb2_v4l2_buffer *mtk_jpeg_buf_remove(struct mtk_jpeg_ctx *ctx, > > return v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); > > } > > > > +static void mtk_jpeg_enc_stop_streaming(struct vb2_queue *q) > > +{ > > + struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q); > > + struct vb2_v4l2_buffer *vb; > > + > > + while ((vb = mtk_jpeg_buf_remove(ctx, q->type))) > > + v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); > > +} > > + > > static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q) > > { > > struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q); > > @@ -699,6 +976,15 @@ static const struct vb2_ops mtk_jpeg_dec_qops = { > > .stop_streaming = mtk_jpeg_dec_stop_streaming, > > }; > > > > +static const struct vb2_ops mtk_jpeg_enc_qops = { > > + .queue_setup = mtk_jpeg_queue_setup, > > + .buf_prepare = mtk_jpeg_buf_prepare, > > + .buf_queue = mtk_jpeg_enc_buf_queue, > > + .wait_prepare = vb2_ops_wait_prepare, > > + .wait_finish = vb2_ops_wait_finish, > > + .stop_streaming = mtk_jpeg_enc_stop_streaming, > > +}; > > + > > static void mtk_jpeg_set_dec_src(struct mtk_jpeg_ctx *ctx, > > struct vb2_buffer *src_buf, > > struct mtk_jpeg_bs *bs) > > @@ -736,6 +1022,85 @@ static int mtk_jpeg_set_dec_dst(struct mtk_jpeg_ctx *ctx, > > return 0; > > } > > > > +static void mtk_jpeg_set_enc_dst(struct mtk_jpeg_ctx *ctx, void __iomem *base, > > + struct vb2_buffer *dst_buf, > > + struct mtk_jpeg_enc_bs *bs) > > +{ > > + bs->dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); > > + bs->dma_addr_offset = ctx->enable_exif ? MTK_JPEG_MAX_EXIF_SIZE : 0; > > + bs->dma_addr_offsetmask = bs->dma_addr & JPEG_ENC_DST_ADDR_OFFSET_MASK; > > + bs->size = vb2_plane_size(dst_buf, 0); > > We're computing these values and then writing to the hardware straightaway. > Do we need to save these values to the bs struct? If no, do we need the bs > struct at all? yes, removed this structure. > > > + > > + mtk_jpeg_enc_set_dst_addr(base, bs->dma_addr, bs->size, > > + bs->dma_addr_offset, > > + bs->dma_addr_offsetmask); > > +} > > + > > +static void mtk_jpeg_set_enc_src(struct mtk_jpeg_ctx *ctx, void __iomem *base, > > + struct vb2_buffer *src_buf) > > +{ > > + int i; > > + dma_addr_t dma_addr; > > nit: Only one space should be between variable type and name. done. > > > + > > + mtk_jpeg_enc_set_img_size(base, ctx->out_q.crop_rect.width, > > + ctx->out_q.crop_rect.height); > > + mtk_jpeg_enc_set_blk_num(base, ctx->out_q.fmt->fourcc, > > + ctx->out_q.crop_rect.width, > > + ctx->out_q.crop_rect.height); > > + mtk_jpeg_enc_set_stride(base, ctx->out_q.fmt->fourcc, ctx->out_q.w, > > + ctx->out_q.h, ctx->out_q.bytesperline[0]); > > + > > + for (i = 0; i < src_buf->num_planes; i++) { > > + dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, i) + > > + src_buf->planes[i].data_offset; > > + mtk_jpeg_enc_set_src_addr(base, dma_addr, i); > > + } > > +} > > + > > +static void mtk_jpeg_enc_device_run(void *priv) > > +{ > > + struct mtk_jpeg_ctx *ctx = priv; > > + struct mtk_jpeg_dev *jpeg = ctx->jpeg; > > + struct vb2_v4l2_buffer *src_buf, *dst_buf; > > + enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; > > + unsigned long flags; > > + struct mtk_jpeg_src_buf *jpeg_src_buf; > > + struct mtk_jpeg_enc_bs enc_bs; > > + int ret; > > + > > + src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); > > + dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); > > + jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf); > > + > > + ret = pm_runtime_get_sync(jpeg->dev); > > + if (ret < 0) > > + goto enc_end; > > + > > + spin_lock_irqsave(&jpeg->hw_lock, flags); > > + > > + /* > > + * Resetting the hardware every frame is to ensure that all the > > + * registers are cleared. This is a hardware requirement. > > + */ > > + mtk_jpeg_enc_reset(jpeg->reg_base); > > + > > + mtk_jpeg_set_enc_dst(ctx, jpeg->reg_base, &dst_buf->vb2_buf, &enc_bs); > > + mtk_jpeg_set_enc_src(ctx, jpeg->reg_base, &src_buf->vb2_buf); > > + mtk_jpeg_enc_set_config(jpeg->reg_base, ctx->out_q.fmt->hw_format, > > + ctx->enable_exif, ctx->enc_quality, > > + ctx->restart_interval); > > + mtk_jpeg_enc_start(jpeg->reg_base); > > Could we just move the above 5 functions into one function inside > mtk_jpeg_enc_hw.c that takes mtk_jpeg_dev pointer as its argument, let's > say mtk_jpeg_enc_hw_run() and simply program all the data to the registers > directly, without the extra level of abstractions? done. > > > + spin_unlock_irqrestore(&jpeg->hw_lock, flags); > > + return; > > + > > +enc_end: > > + v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); > > + v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); > > + v4l2_m2m_buf_done(src_buf, buf_state); > > + v4l2_m2m_buf_done(dst_buf, buf_state); > > + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); > > +} > > + > > static void mtk_jpeg_dec_device_run(void *priv) > > { > > struct mtk_jpeg_ctx *ctx = priv; > > @@ -785,6 +1150,11 @@ static void mtk_jpeg_dec_device_run(void *priv) > > v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); > > } > > > > +static int mtk_jpeg_enc_job_ready(void *priv) > > +{ > > + return 1; > > +} > > + > > The callback is optional, so can be just removed if it always returns 1. done. > > > static int mtk_jpeg_dec_job_ready(void *priv) > > { > > struct mtk_jpeg_ctx *ctx = priv; > > @@ -792,6 +1162,11 @@ static int mtk_jpeg_dec_job_ready(void *priv) > > return (ctx->state == MTK_JPEG_RUNNING) ? 1 : 0; > > } > > > > +static const struct v4l2_m2m_ops mtk_jpeg_enc_m2m_ops = { > > + .device_run = mtk_jpeg_enc_device_run, > > + .job_ready = mtk_jpeg_enc_job_ready, > > +}; > > + > > static const struct v4l2_m2m_ops mtk_jpeg_dec_m2m_ops = { > > .device_run = mtk_jpeg_dec_device_run, > > .job_ready = mtk_jpeg_dec_job_ready, > > @@ -830,24 +1205,109 @@ static int mtk_jpeg_dec_queue_init(void *priv, struct vb2_queue *src_vq, > > return ret; > > } > > > > -static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg) > > +static int mtk_jpeg_enc_queue_init(void *priv, struct vb2_queue *src_vq, > > + struct vb2_queue *dst_vq) > > { > > + struct mtk_jpeg_ctx *ctx = priv; > > int ret; > > > > + src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; > > + src_vq->io_modes = VB2_DMABUF | VB2_MMAP; > > + src_vq->drv_priv = ctx; > > + src_vq->buf_struct_size = sizeof(struct mtk_jpeg_src_buf); > > + src_vq->ops = &mtk_jpeg_enc_qops; > > + src_vq->mem_ops = &vb2_dma_contig_memops; > > + src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; > > + src_vq->lock = &ctx->jpeg->lock; > > + src_vq->dev = ctx->jpeg->dev; > > + ret = vb2_queue_init(src_vq); > > + if (ret) > > + return ret; > > + > > + dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; > > + dst_vq->io_modes = VB2_DMABUF | VB2_MMAP; > > + dst_vq->drv_priv = ctx; > > + dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); > > + dst_vq->ops = &mtk_jpeg_enc_qops; > > + dst_vq->mem_ops = &vb2_dma_contig_memops; > > + dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; > > + dst_vq->lock = &ctx->jpeg->lock; > > + dst_vq->dev = ctx->jpeg->dev; > > + ret = vb2_queue_init(dst_vq); > > + > > + return ret; > > +} > > This only differs in "ops" from the decoder implementation. Perhaps > both functions could be merged? done. > > > + > > +static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg) > > +{ > > + int ret, i; > > + > > ret = mtk_smi_larb_get(jpeg->larb); > > if (ret) > > dev_err(jpeg->dev, "mtk_smi_larb_get larbvdec fail %d\n", ret); > > - clk_prepare_enable(jpeg->clk_jdec_smi); > > - clk_prepare_enable(jpeg->clk_jdec); > > + > > + for (i = 0; i < jpeg->variant->num_clocks; i++) { > > + ret = clk_prepare_enable(jpeg->clocks[i]); > > Instead of an open coded loop, could the clk_bulk_*() helpers be used > instead? (Look for devm_clk_bulk_get() and devm_clk_bulk_prepare_enable().) > > > + if (ret) { > > + while (--i >= 0) > > + clk_disable_unprepare(jpeg->clocks[i]); > > nit: The typical convention is to do error handling in an error path on the > bottom of the function. done > > Also, it would be nice to print an error message. done. > > > + } > > + } > > } > > > > static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg) > > { > > - clk_disable_unprepare(jpeg->clk_jdec); > > - clk_disable_unprepare(jpeg->clk_jdec_smi); > > + int i; > > + > > + for (i = jpeg->variant->num_clocks - 1; i >= 0; i--) > > + clk_disable_unprepare(jpeg->clocks[i]); > > Ditto. done. > > > mtk_smi_larb_put(jpeg->larb); > > } > > > > +static irqreturn_t mtk_jpeg_enc_irq(int irq, void *priv) > > +{ > > + struct mtk_jpeg_dev *jpeg = priv; > > + struct mtk_jpeg_ctx *ctx; > > + struct vb2_v4l2_buffer *src_buf, *dst_buf; > > + struct mtk_jpeg_src_buf *jpeg_src_buf; > > + enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; > > + u32 enc_irq_ret; > > + u32 enc_ret, result_size; > > + > > + ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); > > + if (!ctx) { > > + v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n"); > > + return IRQ_HANDLED; > > + } > > + > > + src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); > > + dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); > > + jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf); > > + > > + enc_ret = mtk_jpeg_enc_get_and_clear_int_status(jpeg->reg_base); > > We should check the interrupt status at the beginning of the function and > return IRQ_NONE if there wasn't any flag set. done. > > > + enc_irq_ret = mtk_jpeg_enc_enum_result(jpeg->reg_base, enc_ret); > > + > > + if (enc_irq_ret >= MTK_JPEG_ENC_RESULT_STALL) > > + mtk_jpeg_enc_reset(jpeg->reg_base); > > + > > + if (enc_irq_ret != MTK_JPEG_ENC_RESULT_DONE) { > > + dev_err(jpeg->dev, "encode failed\n"); > > + goto enc_end; > > + } > > As I suggested before, it would have been much more clear if the interrupt > status bits were just directly read and checked in this function, without > introducing the additional abstraction. done. > > > + > > + result_size = mtk_jpeg_enc_get_file_size(jpeg->reg_base); > > + vb2_set_plane_payload(&dst_buf->vb2_buf, 0, result_size); > > + > > + buf_state = VB2_BUF_STATE_DONE; > > + > > +enc_end: > > + v4l2_m2m_buf_done(src_buf, buf_state); > > + v4l2_m2m_buf_done(dst_buf, buf_state); > > + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); > > + pm_runtime_put(ctx->jpeg->dev); > > + return IRQ_HANDLED; > > +} > > + > > static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) > > { > > struct mtk_jpeg_dev *jpeg = priv; > > @@ -893,36 +1353,130 @@ static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) > > return IRQ_HANDLED; > > } > > > > +static void mtk_jpeg_set_enc_default_params(struct mtk_jpeg_ctx *ctx) > > +{ > > + struct mtk_jpeg_q_data *q = &ctx->out_q; > > + struct v4l2_pix_format_mplane *pix_mp; > > + > > + pix_mp = kmalloc(sizeof(*pix_mp), GFP_KERNEL); > > Do we need to allocate this pix_mp? Could we instead just embed it inside > ctx? > > Also, this is actually a memory leak, because I don't see this structure > saved anywhere or freed. > > > + > > + ctx->fh.ctrl_handler = &ctx->ctrl_hdl; > > + ctx->colorspace = V4L2_COLORSPACE_JPEG, > > + ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; > > + ctx->quantization = V4L2_QUANTIZATION_DEFAULT; > > + ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT; > > Since we already have a v4l2_pix_format_mplane struct which has fields for > the above 4 values, could we just store them there? > > Also, I don't see this driver handling the colorspaces in any way, but it > seems to allow changing them from the userspace. This is incorrect, because > the userspace has no way to know that the colorspace is not handled. > Instead, the try_fmt implementation should always override the > userspace-provided colorspace configuration with the ones that the driver > assumes. did as what we discussed earlier. > > > + pix_mp->width = MTK_JPEG_MIN_WIDTH; > > + pix_mp->height = MTK_JPEG_MIN_HEIGHT; > > + > > + q->fmt = mtk_jpeg_find_format(V4L2_PIX_FMT_YUYV, > > + MTK_JPEG_FMT_FLAG_ENC_OUTPUT); > > + vidioc_try_fmt(container_of(pix_mp, struct v4l2_format, > > + fmt.pix_mp), q->fmt); > > + q->w = pix_mp->width; > > + q->h = pix_mp->height; > > + q->crop_rect.width = pix_mp->width; > > + q->crop_rect.height = pix_mp->height; > > + q->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage; > > + q->bytesperline[0] = pix_mp->plane_fmt[0].bytesperline; > > Actually, do we need this custom mtk_jpeg_q_data struct? Why couldn't we > just keep the same values inside the standard v4l2_pix_format_mplane > struct? > > In general it's preferred to use the standard kernel structures as much as > possible and only introduce local driver structures for data that can't be > stored in generic ones. did as what we discussed earlier. > > > + > > + q = &ctx->cap_q; > > + q->fmt = mtk_jpeg_find_format(V4L2_PIX_FMT_JPEG, > > + MTK_JPEG_FMT_FLAG_ENC_CAPTURE); > > + pix_mp->width = MTK_JPEG_MIN_WIDTH; > > + pix_mp->height = MTK_JPEG_MIN_HEIGHT; > > + vidioc_try_fmt(container_of(pix_mp, struct v4l2_format, > > + fmt.pix_mp), q->fmt); > > + q->w = pix_mp->width; > > + q->h = pix_mp->height; > > + q->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage; > > + q->bytesperline[0] = pix_mp->plane_fmt[0].bytesperline; > > Ditto. done. > > > +} > > + > > static void mtk_jpeg_set_dec_default_params(struct mtk_jpeg_ctx *ctx) > > { > > struct mtk_jpeg_q_data *q = &ctx->out_q; > > + struct v4l2_pix_format_mplane *pix_mp; > > int i; > > > > + pix_mp = kmalloc(sizeof(*pix_mp), GFP_KERNEL); > > + > > + ctx->fh.ctrl_handler = &ctx->ctrl_hdl; > > ctx->colorspace = V4L2_COLORSPACE_JPEG, > > ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; > > ctx->quantization = V4L2_QUANTIZATION_DEFAULT; > > ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT; > > - > > - q->fmt = mtk_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG, > > - MTK_JPEG_FMT_TYPE_OUTPUT); > > - q->w = MTK_JPEG_MIN_WIDTH; > > - q->h = MTK_JPEG_MIN_HEIGHT; > > - q->bytesperline[0] = 0; > > - q->sizeimage[0] = MTK_JPEG_DEFAULT_SIZEIMAGE; > > + pix_mp->width = MTK_JPEG_MIN_WIDTH; > > + pix_mp->height = MTK_JPEG_MIN_HEIGHT; > > + > > + q->fmt = mtk_jpeg_find_format(V4L2_PIX_FMT_JPEG, > > + MTK_JPEG_FMT_FLAG_DEC_OUTPUT); > > + vidioc_try_fmt(container_of(pix_mp, struct v4l2_format, > > + fmt.pix_mp), q->fmt); > > + q->w = pix_mp->width; > > + q->h = pix_mp->height; > > + q->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage; > > + q->bytesperline[0] = pix_mp->plane_fmt[0].bytesperline; > > > > q = &ctx->cap_q; > > - q->fmt = mtk_jpeg_find_format(ctx, V4L2_PIX_FMT_YUV420M, > > - MTK_JPEG_FMT_TYPE_CAPTURE); > > - q->w = MTK_JPEG_MIN_WIDTH; > > - q->h = MTK_JPEG_MIN_HEIGHT; > > - > > + q->fmt = mtk_jpeg_find_format(V4L2_PIX_FMT_YUV420M, > > + MTK_JPEG_FMT_FLAG_DEC_CAPTURE); > > + pix_mp->width = MTK_JPEG_MIN_WIDTH; > > + pix_mp->height = MTK_JPEG_MIN_HEIGHT; > > + vidioc_try_fmt(container_of(pix_mp, struct v4l2_format, > > + fmt.pix_mp), q->fmt); > > + q->w = pix_mp->width; > > + q->h = pix_mp->height; > > for (i = 0; i < q->fmt->colplanes; i++) { > > - u32 stride = q->w * q->fmt->h_sample[i] / 4; > > - u32 h = q->h * q->fmt->v_sample[i] / 4; > > + q->sizeimage[i] = pix_mp->plane_fmt[i].sizeimage; > > + q->bytesperline[i] = pix_mp->plane_fmt[i].bytesperline; > > + } > > +} > > > > Same comments as for the encoder version. > > On top of that, both functions are almost identical and it should be > possible to merge them. done. > > > - q->bytesperline[i] = stride; > > - q->sizeimage[i] = stride * h; > > +static int mtk_jpeg_enc_open(struct file *file) > > +{ > > + struct mtk_jpeg_dev *jpeg = video_drvdata(file); > > + struct video_device *vfd = video_devdata(file); > > + struct mtk_jpeg_ctx *ctx; > > + int ret = 0; > > + > > + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); > > + if (!ctx) > > + return -ENOMEM; > > + > > + if (mutex_lock_interruptible(&jpeg->lock)) { > > + ret = -ERESTARTSYS; > > + goto free; > > + } > > + > > + v4l2_fh_init(&ctx->fh, vfd); > > + file->private_data = &ctx->fh; > > + v4l2_fh_add(&ctx->fh); > > + > > + ctx->jpeg = jpeg; > > + ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, > > + mtk_jpeg_enc_queue_init); > > + if (IS_ERR(ctx->fh.m2m_ctx)) { > > + ret = PTR_ERR(ctx->fh.m2m_ctx); > > + goto error; > > } > > + > > + ret = mtk_jpeg_enc_ctrls_setup(ctx); > > + if (ret) { > > + v4l2_err(&jpeg->v4l2_dev, "Failed to setup jpeg enc controls\n"); > > + goto error; > > + } > > + mtk_jpeg_set_enc_default_params(ctx); > > + > > + mutex_unlock(&jpeg->lock); > > + return 0; > > + > > +error: > > + v4l2_fh_del(&ctx->fh); > > + v4l2_fh_exit(&ctx->fh); > > + mutex_unlock(&jpeg->lock); > > +free: > > + kfree(ctx); > > + return ret; > > } > > It looks like the queue_init argument to v4l2_m2m_ctx_init() and control > handling would be the only differences from the decoder version. Perhaps > the functions can be merged? done. > > > > > static int mtk_jpeg_dec_open(struct file *file) > > @@ -953,6 +1507,12 @@ static int mtk_jpeg_dec_open(struct file *file) > > goto error; > > } > > > > + v4l2_ctrl_handler_init(&ctx->ctrl_hdl, 0); > > + ret = v4l2_ctrl_handler_setup(&ctx->ctrl_hdl); > > + if (ret) { > > + v4l2_err(&jpeg->v4l2_dev, "Failed to setup jpeg dec controls\n"); > > + goto error; > > + } > > There are no controls for the decoder, so there should be no need to set up > a control handler. done. > > > mtk_jpeg_set_dec_default_params(ctx); > > mutex_unlock(&jpeg->lock); > > return 0; > > @@ -973,6 +1533,7 @@ static int mtk_jpeg_release(struct file *file) > > > > mutex_lock(&jpeg->lock); > > v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); > > + v4l2_ctrl_handler_free(&ctx->ctrl_hdl); > > v4l2_fh_del(&ctx->fh); > > v4l2_fh_exit(&ctx->fh); > > kfree(ctx); > > @@ -980,6 +1541,15 @@ static int mtk_jpeg_release(struct file *file) > > return 0; > > } > > > > +static const struct v4l2_file_operations mtk_jpeg_enc_fops = { > > + .owner = THIS_MODULE, > > + .open = mtk_jpeg_enc_open, > > + .release = mtk_jpeg_release, > > + .poll = v4l2_m2m_fop_poll, > > + .unlocked_ioctl = video_ioctl2, > > + .mmap = v4l2_m2m_fop_mmap, > > +}; > > + > > If we merge the .open() implementation, the same struct could be used for > both decoder and encoder. done. > > [snip] > > @@ -1042,8 +1619,12 @@ static int mtk_jpeg_probe(struct platform_device *pdev) > > return jpeg_irq; > > } > > > > - ret = devm_request_irq(&pdev->dev, jpeg_irq, mtk_jpeg_dec_irq, 0, > > - pdev->name, jpeg); > > + if (jpeg->variant->is_encoder) > > + ret = devm_request_irq(&pdev->dev, jpeg_irq, mtk_jpeg_enc_irq, > > + 0, pdev->name, jpeg); > > + else > > + ret = devm_request_irq(&pdev->dev, jpeg_irq, mtk_jpeg_dec_irq, > > + 0, pdev->name, jpeg); > > Rather than having "is_encoder" in the variant struct, would it make more > sense to have "irq_handler" instead? That would avoid the explicit if. done. > > > if (ret) { > > dev_err(&pdev->dev, "Failed to request jpeg_irq %d (%d)\n", > > jpeg_irq, ret); > > @@ -1063,7 +1644,10 @@ static int mtk_jpeg_probe(struct platform_device *pdev) > > goto err_dev_register; > > } > > > > - jpeg->m2m_dev = v4l2_m2m_init(&mtk_jpeg_dec_m2m_ops); > > + if (jpeg->variant->is_encoder) > > + jpeg->m2m_dev = v4l2_m2m_init(&mtk_jpeg_enc_m2m_ops); > > + else > > + jpeg->m2m_dev = v4l2_m2m_init(&mtk_jpeg_dec_m2m_ops); > > Same here. The variant struct could have a "m2m_ops" pointer. done. > > > if (IS_ERR(jpeg->m2m_dev)) { > > v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n"); > > ret = PTR_ERR(jpeg->m2m_dev); > > @@ -1076,9 +1660,15 @@ static int mtk_jpeg_probe(struct platform_device *pdev) > > goto err_vfd_jpeg_alloc; > > } > > snprintf(jpeg->vdev->name, sizeof(jpeg->vdev->name), > > - "%s-dec", MTK_JPEG_NAME); > > - jpeg->vdev->fops = &mtk_jpeg_dec_fops; > > - jpeg->vdev->ioctl_ops = &mtk_jpeg_dec_ioctl_ops; > > + "%s-%s", MTK_JPEG_NAME, > > + jpeg->variant->is_encoder ? "enc" : "dec"); > > + if (jpeg->variant->is_encoder) { > > + jpeg->vdev->fops = &mtk_jpeg_enc_fops; > > + jpeg->vdev->ioctl_ops = &mtk_jpeg_enc_ioctl_ops; > > + } else { > > + jpeg->vdev->fops = &mtk_jpeg_dec_fops; > > + jpeg->vdev->ioctl_ops = &mtk_jpeg_dec_ioctl_ops; > > + } > > Similarly here. done. > > [snip] > > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h > > index 0b59e48495d5..9ec2c3350a16 100644 > > --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h > > +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h > > @@ -3,6 +3,7 @@ > > * Copyright (c) 2016 MediaTek Inc. > > * Author: Ming Hsiu Tsai > > * Rick Chang > > + * Xia Jiang > > */ > > > > #ifndef _MTK_JPEG_CORE_H > > @@ -16,19 +17,21 @@ > > #define MTK_JPEG_NAME "mtk-jpeg" > > > > #define MTK_JPEG_COMP_MAX 3 > > +#define MTK_JPEG_MAX_CLOCKS 2 > > + > > > > Duplicate blank line. removed. > > > #define MTK_JPEG_FMT_FLAG_DEC_OUTPUT BIT(0) > > #define MTK_JPEG_FMT_FLAG_DEC_CAPTURE BIT(1) > > - > > -#define MTK_JPEG_FMT_TYPE_OUTPUT 1 > > -#define MTK_JPEG_FMT_TYPE_CAPTURE 2 > > +#define MTK_JPEG_FMT_FLAG_ENC_OUTPUT BIT(2) > > +#define MTK_JPEG_FMT_FLAG_ENC_CAPTURE BIT(3) > > Do we need separate bits for decoder and encoder? no need, I have removed it. > > > > > #define MTK_JPEG_MIN_WIDTH 32U > > #define MTK_JPEG_MIN_HEIGHT 32U > > -#define MTK_JPEG_MAX_WIDTH 8192U > > -#define MTK_JPEG_MAX_HEIGHT 8192U > > +#define MTK_JPEG_MAX_WIDTH 65535U > > +#define MTK_JPEG_MAX_HEIGHT 65535U > > If this is a change valid for the decoder too, it should be a separate > patch. done. > > > > > #define MTK_JPEG_DEFAULT_SIZEIMAGE (1 * 1024 * 1024) > > +#define MTK_JPEG_MAX_EXIF_SIZE (64 * 1024) > > There is one thing that I realized now. If the EXIF mode is enabled, the > driver needs to ensure that the buffer is big enough to hold the EXIF data. > The vb2 .buf_prepare callback would be the right place to do that. done. > > > > > /** > > * enum mtk_jpeg_ctx_state - states of the context state machine > > @@ -42,6 +45,18 @@ enum mtk_jpeg_ctx_state { > > MTK_JPEG_SOURCE_CHANGE, > > }; > > > > +/** > > + * mtk_jpeg_variant - mtk jpeg driver variant > > + * @is_encoder: driver mode is jpeg encoder > > + * @clk_names: clock names > > + * @num_clocks: numbers of clock > > + */ > > +struct mtk_jpeg_variant { > > + bool is_encoder; > > + const char *clk_names[MTK_JPEG_MAX_CLOCKS]; > > + int num_clocks; > > hint: Please avoid tabs between types and names, as it makes it difficult > to add new fields later (the number of tabs might need to change for all > members). done. > > [snip] > > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c > > new file mode 100644 > > index 000000000000..7fc1de920a75 > > --- /dev/null > > +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c > > @@ -0,0 +1,193 @@ > > +// SPDX-License-Identifier: GPL-2.0-only > > +/* > > + * Copyright (c) 2019 MediaTek Inc. > > + * Author: Xia Jiang > > + * > > + */ > > + > > +#include > > +#include > > +#include > > + > > +#include "mtk_jpeg_enc_hw.h" > > + > > +static const struct mtk_jpeg_enc_qlt mtk_jpeg_enc_quality[] = { > > + {.quality_param = 34, .hardware_value = JPEG_ENC_QUALITY_Q34}, > > + {.quality_param = 39, .hardware_value = JPEG_ENC_QUALITY_Q39}, > > + {.quality_param = 48, .hardware_value = JPEG_ENC_QUALITY_Q48}, > > + {.quality_param = 60, .hardware_value = JPEG_ENC_QUALITY_Q60}, > > + {.quality_param = 64, .hardware_value = JPEG_ENC_QUALITY_Q64}, > > + {.quality_param = 68, .hardware_value = JPEG_ENC_QUALITY_Q68}, > > + {.quality_param = 74, .hardware_value = JPEG_ENC_QUALITY_Q74}, > > + {.quality_param = 80, .hardware_value = JPEG_ENC_QUALITY_Q80}, > > + {.quality_param = 82, .hardware_value = JPEG_ENC_QUALITY_Q82}, > > + {.quality_param = 84, .hardware_value = JPEG_ENC_QUALITY_Q84}, > > + {.quality_param = 87, .hardware_value = JPEG_ENC_QUALITY_Q87}, > > + {.quality_param = 90, .hardware_value = JPEG_ENC_QUALITY_Q90}, > > + {.quality_param = 92, .hardware_value = JPEG_ENC_QUALITY_Q92}, > > + {.quality_param = 95, .hardware_value = JPEG_ENC_QUALITY_Q95}, > > + {.quality_param = 97, .hardware_value = JPEG_ENC_QUALITY_Q97}, > > +}; > > + > > +void mtk_jpeg_enc_reset(void __iomem *base) > > I'd suggest passing struct mtk_jpeg_dev pointer to all these functions, in > case more data about the hardware is needed in the future. > > > +{ > > + writel(0x00, base + JPEG_ENC_RSTB); > > nit: Just 0 is enough. done. > > > + writel(JPEG_ENC_RESET_BIT, base + JPEG_ENC_RSTB); > > + writel(0x00, base + JPEG_ENC_CODEC_SEL); > > Ditto. done. > > > +} > > + > > +u32 mtk_jpeg_enc_get_and_clear_int_status(void __iomem *base) > > +{ > > + u32 ret; > > + > > + ret = readl(base + JPEG_ENC_INT_STS) & > > + JPEG_ENC_INT_STATUS_MASK_ALLIRQ; > > + if (ret) > > + writel(0, base + JPEG_ENC_INT_STS); > > + > > + return ret; > > +} > > + > > +u32 mtk_jpeg_enc_get_file_size(void __iomem *base) > > +{ > > + return readl(base + JPEG_ENC_DMA_ADDR0) - > > + readl(base + JPEG_ENC_DST_ADDR0); > > +} > > + > > +u32 mtk_jpeg_enc_enum_result(void __iomem *base, u32 irq_status) > > +{ > > + if (irq_status & JPEG_ENC_INT_STATUS_DONE) > > + return MTK_JPEG_ENC_RESULT_DONE; > > + else if (irq_status & JPEG_ENC_INT_STATUS_STALL) > > + return MTK_JPEG_ENC_RESULT_STALL; > > + else > > + return MTK_JPEG_ENC_RESULT_VCODEC_IRQ; > > +} > > It looks like the driver only cares about 2 cases: DONE and anything else. > Actually it also cares about a case where no bits are set in irq_status, > which could be an interrupt controller misconfiguration or an interrupt > generated by another device on the same shared IRQ line, which should be > handled by returning IRQ_NONE. Since interrupt handling is a low level > hardware operation, I'd suggest another design: > - put the irq_handler_t function here in this file and have it directly > access the hardware registers and check the interrupt bits, > - add an mtk_jpeg_enc_done(..., enum vb2_buffer_state state, size_t > payload), which would be called from this low level interrupt handler and > do the V4L2 buffer and M2M job handling. > > WDYT? done. > > > + > > +void mtk_jpeg_enc_set_img_size(void __iomem *base, u32 width, u32 height) > > If we pass struct mtk_jpeg_dev to this function, the width and height > arguments wouldn't be necessary, as they could be directly retrieved from > the driver state. > > Similar advice applies to the other functions in this file. done. > > > +{ > > + u32 value; > > + > > + value = width << 16 | height; > > + writel(value, base + JPEG_ENC_IMG_SIZE); > > +} > > + > > +void mtk_jpeg_enc_set_blk_num(void __iomem *base, u32 enc_format, u32 width, > > + u32 height) > > +{ > > + u32 blk_num; > > + u32 is_420; > > + u32 padding_width; > > + u32 padding_height; > > + u32 luma_blocks; > > + u32 chroma_blocks; > > + > > + is_420 = (enc_format == V4L2_PIX_FMT_NV12M || > > + enc_format == V4L2_PIX_FMT_NV21M) ? 1 : 0; > > + padding_width = round_up(width, 16); > > + padding_height = round_up(height, is_420 ? 16 : 8); > > + > > + luma_blocks = padding_width / 8 * padding_height / 8; > > + if (is_420) > > + chroma_blocks = luma_blocks / 4; > > + else > > + chroma_blocks = luma_blocks / 2; > > + > > + blk_num = luma_blocks + 2 * chroma_blocks - 1; > > + > > + writel(blk_num, base + JPEG_ENC_BLK_NUM); > > +} > > My comments for this function from v7 haven't been addressed. done. > > > + > > +void mtk_jpeg_enc_set_stride(void __iomem *base, u32 enc_format, u32 width, > > + u32 height, u32 bytesperline) > > +{ > > + u32 img_stride; > > + u32 mem_stride; > > + > > + if (enc_format == V4L2_PIX_FMT_NV12M || > > + enc_format == V4L2_PIX_FMT_NV21M) { > > + img_stride = round_up(width, 16); > > + mem_stride = bytesperline; > > + } else { > > + img_stride = round_up(width * 2, 32); > > + mem_stride = img_stride; > > + } > > + > > + writel(img_stride, base + JPEG_ENC_IMG_STRIDE); > > + writel(mem_stride, base + JPEG_ENC_STRIDE); > > +} > > + > > My comments for this function from v7 haven't been addressed. done. > > > +void mtk_jpeg_enc_set_src_addr(void __iomem *base, u32 src_addr, > > + u32 plane_index) > > +{ > > + if (!plane_index) > > + writel(src_addr, base + JPEG_ENC_SRC_LUMA_ADDR); > > + else > > + writel(src_addr, base + JPEG_ENC_SRC_CHROMA_ADDR); > > Do we need this plane_index if we only have 2 planes? Also, for interleaved > formats, like YUYV, what should the LUMA and CHROMA registers be set to? If the format is YUYV, there is no need to set CHROMA register. Hardware can compute the CHROMA address from the LUMA address itself. > > > +} > > + > > +void mtk_jpeg_enc_set_dst_addr(void __iomem *base, u32 dst_addr, > > + u32 stall_size, u32 init_offset, > > + u32 offset_mask) > > +{ > > + writel(init_offset & ~0xf, base + JPEG_ENC_OFFSET_ADDR); > > + writel(offset_mask & 0xf, base + JPEG_ENC_BYTE_OFFSET_MASK); > > + writel(dst_addr & ~0xf, base + JPEG_ENC_DST_ADDR0); > > + writel((dst_addr + stall_size) & ~0xf, base + JPEG_ENC_STALL_ADDR0); > > +} > > + > > +static void mtk_jpeg_enc_set_quality(void __iomem *base, u32 quality) > > +{ > > + u32 value; > > + u32 i, enc_quality; > > + > > + enc_quality = mtk_jpeg_enc_quality[0].hardware_value; > > + for (i = 0; i < ARRAY_SIZE(mtk_jpeg_enc_quality); i++) { > > + if (quality <= mtk_jpeg_enc_quality[i].quality_param) { > > + enc_quality = mtk_jpeg_enc_quality[i].hardware_value; > > + break; > > + } > > + } > > + > > + value = readl(base + JPEG_ENC_QUALITY); > > nit: Is it still necessary to read the register here? Typically the reserved > bits would be defined as SBZ (should be zero) and it should be safe to just > write 0 to them. yes,removed it. > > > + value = (value & JPEG_ENC_QUALITY_MASK) | enc_quality; > > + writel(value, base + JPEG_ENC_QUALITY); > > +} > > + > > +static void mtk_jpeg_enc_set_ctrl(void __iomem *base, u32 enc_format, > > + bool exif_en, u32 restart_interval) > > +{ > > + u32 value; > > + > > + value = readl(base + JPEG_ENC_CTRL); > > nit: Is it still necessary to read the register here? I think it is necessary to read this register.Because that the default value of JPEG_ENC_CTRL's bit[2](enable interrupt) is 1. > > > + value &= ~JPEG_ENC_CTRL_YUV_FORMAT_MASK; > > + value |= (enc_format & 3) << 3; > > + if (exif_en) > > + value |= JPEG_ENC_CTRL_FILE_FORMAT_BIT; > > + else > > + value &= ~JPEG_ENC_CTRL_FILE_FORMAT_BIT; > > + if (restart_interval) > > + value |= JPEG_ENC_CTRL_RESTART_EN_BIT; > > + else > > + value &= ~JPEG_ENC_CTRL_RESTART_EN_BIT; > > + writel(value, base + JPEG_ENC_CTRL); > > +} > > + > > Best regards, > Tomasz Best Regards, Xia Jiang _______________________________________________ Linux-mediatek mailing list Linux-mediatek@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-mediatek From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-11.5 required=3.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY, URIBL_BLOCKED,USER_AGENT_SANE_2 autolearn=unavailable autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 48A5FC433DF for ; Fri, 24 Jul 2020 10:00:04 +0000 (UTC) Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id EE2CE20674 for ; Fri, 24 Jul 2020 10:00:03 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (2048-bit key) header.d=lists.infradead.org header.i=@lists.infradead.org header.b="JqiP6rj8"; dkim=fail reason="signature verification failed" (1024-bit key) header.d=mediatek.com header.i=@mediatek.com header.b="svDIOula" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org EE2CE20674 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=mediatek.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=lists.infradead.org; s=merlin.20170209; h=Sender:Content-Transfer-Encoding: Content-Type:Cc:List-Subscribe:List-Help:List-Post:List-Archive: List-Unsubscribe:List-Id:MIME-Version:References:In-Reply-To:Date:To:From: Subject:Message-ID:Reply-To:Content-ID:Content-Description:Resent-Date: Resent-From:Resent-Sender:Resent-To:Resent-Cc:Resent-Message-ID:List-Owner; bh=cV/VSrY/loPh3/q11ZLT4keIziJB9czy1UKu2/G1spI=; b=JqiP6rj8aUuwMCe5AuPITjFbH dQdvDsPB3LZBOn8AupkDTQniIK64H38lLmEd5OP29b/oqCuzNZrkxxnSCgXB1n7jeCt/21vvRKxre +2ILoKtmJI/NcJLPdbkMA0zUmtNeGpLPHbzsLnK+6zwoH3lt6WvzOEHSDRCRpLqJOTXbGpFrcVfsk CT6uhQdyEMS3S7spCuHtymt4RAiG2wmHgb0yXrxse7ipzRVwt8ZL6JJ4gB/3jCvIUjqzbbLbFK9sN 0tIGugnw9YcsUSmf+SYpzY21cwXaL0NCqfoP+Te5hLB9wYS0on/KY57QP9M0RXZ429Fz6cZz01Szo 7Xg/2ALXA==; Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.92.3 #3 (Red Hat Linux)) id 1jyuT3-0005hx-Um; Fri, 24 Jul 2020 09:58:18 +0000 Received: from mailgw02.mediatek.com ([216.200.240.185]) by merlin.infradead.org with esmtps (Exim 4.92.3 #3 (Red Hat Linux)) id 1jyuSx-0005g9-Tf; Fri, 24 Jul 2020 09:58:14 +0000 X-UUID: ca46aa9e6e394bc5a6e3366ad7496073-20200724 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=mediatek.com; s=dk; h=Content-Transfer-Encoding:MIME-Version:Content-Type:References:In-Reply-To:Date:CC:To:From:Subject:Message-ID; bh=X91yDgTfDA2byKhgCyPcKRjLhJli3RxZLlwdVJHhJRM=; b=svDIOulaCtcBzwjEaNKnOl8m7+hmPJiFtjOF0yeU4mQ8aDAppB87Kk+gGtS3tdfqMyecZ3/yAfZL4EQvt8ZoAgqFKVTI/cVSEYbg/0h9Ha3xx/bLWpAYI+2NinXdqSFE2cT/kVetS2vnVd5Z7x/OIajrJ5w9fMllXmouZEglq5I=; X-UUID: ca46aa9e6e394bc5a6e3366ad7496073-20200724 Received: from mtkcas66.mediatek.inc [(172.29.193.44)] by mailgw02.mediatek.com (envelope-from ) (musrelay.mediatek.com ESMTP with TLS) with ESMTP id 2027073142; Fri, 24 Jul 2020 01:57:40 -0800 Received: from MTKMBS31N1.mediatek.inc (172.27.4.69) by MTKMBS62N1.mediatek.inc (172.29.193.41) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 24 Jul 2020 02:55:40 -0700 Received: from MTKCAS32.mediatek.inc (172.27.4.184) by MTKMBS31N1.mediatek.inc (172.27.4.69) with Microsoft SMTP Server (TLS) id 15.0.1497.2; Fri, 24 Jul 2020 17:55:38 +0800 Received: from [10.17.3.153] (10.17.3.153) by MTKCAS32.mediatek.inc (172.27.4.170) with Microsoft SMTP Server id 15.0.1497.2 via Frontend Transport; Fri, 24 Jul 2020 17:55:37 +0800 Message-ID: <1595584468.27238.43.camel@mhfsdcap03> Subject: Re: [PATCH RESEND v9 18/18] media: platform: Add jpeg enc feature From: Xia Jiang To: Tomasz Figa Date: Fri, 24 Jul 2020 17:54:28 +0800 In-Reply-To: <20200611184640.GC8694@chromium.org> References: <20200604090553.10861-1-xia.jiang@mediatek.com> <20200604090553.10861-20-xia.jiang@mediatek.com> <20200611184640.GC8694@chromium.org> X-Mailer: Evolution 3.10.4-0ubuntu2 MIME-Version: 1.0 X-TM-SNTS-SMTP: 02F87A8808ED5D525EB80BC28A01270FA46BF0D424768C6E6D17C33DD07B58E32000:8 X-MTK: N X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20200724_055812_225117_21210B92 X-CRM114-Status: GOOD ( 34.78 ) X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: drinkcat@chromium.org, devicetree@vger.kernel.org, mojahsu@chromium.org, srv_heupstream@mediatek.com, Rick Chang , senozhatsky@chromium.org, linux-kernel@vger.kernel.org, maoguang.meng@mediatek.com, Mauro Carvalho Chehab , sj.huang@mediatek.com, Rob Herring , Matthias Brugger , Hans Verkuil , linux-mediatek@lists.infradead.org, Marek Szyprowski , linux-arm-kernel@lists.infradead.org, linux-media@vger.kernel.org Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Sender: "linux-arm-kernel" Errors-To: linux-arm-kernel-bounces+linux-arm-kernel=archiver.kernel.org@lists.infradead.org On Thu, 2020-06-11 at 18:46 +0000, Tomasz Figa wrote: > Hi Xia, > > On Thu, Jun 04, 2020 at 05:05:53PM +0800, Xia Jiang wrote: > > Add mtk jpeg encode v4l2 driver based on jpeg decode, because that jpeg > > decode and encode have great similarities with function operation. > > > > Signed-off-by: Xia Jiang > > --- > > v9: add member variable(struct v4l2_rect) in out_q structure for storing > > the active crop information. > > move the renaming exsting functions/defines/variables to a separate patch. > > --- > > drivers/media/platform/mtk-jpeg/Makefile | 5 +- > > .../media/platform/mtk-jpeg/mtk_jpeg_core.c | 845 +++++++++++++++--- > > .../media/platform/mtk-jpeg/mtk_jpeg_core.h | 44 +- > > .../media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c | 193 ++++ > > .../media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h | 123 +++ > > 5 files changed, 1084 insertions(+), 126 deletions(-) > > create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c > > create mode 100644 drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.h > > > > Thank you for the patch. Please see my comments inline. Dear Tomasz, Thank you for your comments. I have uploaded the v10 version which contains the changes you mentioned. > > [snip] > > +static int mtk_jpeg_enc_querycap(struct file *file, void *priv, > > + struct v4l2_capability *cap) > > +{ > > + struct mtk_jpeg_dev *jpeg = video_drvdata(file); > > + > > + strscpy(cap->driver, MTK_JPEG_NAME, sizeof(cap->driver)); > > + strscpy(cap->card, MTK_JPEG_NAME " encoder", sizeof(cap->card)); > > + snprintf(cap->bus_info, sizeof(cap->bus_info), "platform:%s", > > + dev_name(jpeg->dev)); > > + > > + return 0; > > +} > > I can see that this function differs from mtk_jpeg_dec_querycap() only with > the " encoder" string. Perhaps they could be merged? done. > > > + > > static int mtk_jpeg_dec_querycap(struct file *file, void *priv, > > struct v4l2_capability *cap) > > { > > @@ -88,6 +157,54 @@ static int mtk_jpeg_dec_querycap(struct file *file, void *priv, > > return 0; > > } > > > > +static int vidioc_jpeg_enc_s_ctrl(struct v4l2_ctrl *ctrl) > > +{ > > + struct mtk_jpeg_ctx *ctx = ctrl_to_ctx(ctrl); > > + > > + switch (ctrl->id) { > > + case V4L2_CID_JPEG_RESTART_INTERVAL: > > + ctx->restart_interval = ctrl->val; > > + break; > > + case V4L2_CID_JPEG_COMPRESSION_QUALITY: > > + ctx->enc_quality = ctrl->val; > > + break; > > + case V4L2_CID_JPEG_ACTIVE_MARKER: > > + ctx->enable_exif = ctrl->val & V4L2_JPEG_ACTIVE_MARKER_APP1 ? > > + true : false; > > nit: If ctx->enable_exif is of the bool type, the ternary operator could be > removed, because any non-zero value is implicitly turned into 1, as per [1]. > > [1] https://www.kernel.org/doc/html/v5.6/process/coding-style.html#using-bool done. > > [snip] > > +static int mtk_jpeg_enc_enum_fmt_vid_cap(struct file *file, void *priv, > > + struct v4l2_fmtdesc *f) > > +{ > > + return mtk_jpeg_enum_fmt(mtk_jpeg_enc_formats, > > + MTK_JPEG_ENC_NUM_FORMATS, f, > > + MTK_JPEG_FMT_FLAG_ENC_CAPTURE); > > +} > > + > > static int mtk_jpeg_dec_enum_fmt_vid_cap(struct file *file, void *priv, > > struct v4l2_fmtdesc *f) > > { > > @@ -117,6 +242,14 @@ static int mtk_jpeg_dec_enum_fmt_vid_cap(struct file *file, void *priv, > > MTK_JPEG_FMT_FLAG_DEC_CAPTURE); > > } > > > > +static int mtk_jpeg_enc_enum_fmt_vid_out(struct file *file, void *priv, > > + struct v4l2_fmtdesc *f) > > +{ > > + return mtk_jpeg_enum_fmt(mtk_jpeg_enc_formats, > > + MTK_JPEG_ENC_NUM_FORMATS, f, > > + MTK_JPEG_FMT_FLAG_ENC_OUTPUT); > > Do we need separate implementations of these? "formats" and "num_formats" > could be specified by the match data struct and used in a generic function. done. > > Also, do we need separate flags for ENC_OUTPUT/CAPTURE and > DEC_OUTPUT/CAPTURE? done > > > +} > > + > > static int mtk_jpeg_dec_enum_fmt_vid_out(struct file *file, void *priv, > > struct v4l2_fmtdesc *f) > > { > > @@ -132,93 +265,66 @@ mtk_jpeg_get_q_data(struct mtk_jpeg_ctx *ctx, enum v4l2_buf_type type) > > return &ctx->cap_q; > > } > > > > -static struct mtk_jpeg_fmt *mtk_jpeg_find_format(struct mtk_jpeg_ctx *ctx, > > - u32 pixelformat, > > +static struct mtk_jpeg_fmt *mtk_jpeg_find_format(u32 pixelformat, > > unsigned int fmt_type) > > { > > - unsigned int k, fmt_flag; > > + unsigned int k; > > + struct mtk_jpeg_fmt *fmt; > > > > - fmt_flag = (fmt_type == MTK_JPEG_FMT_TYPE_OUTPUT) ? > > - MTK_JPEG_FMT_FLAG_DEC_OUTPUT : > > - MTK_JPEG_FMT_FLAG_DEC_CAPTURE; > > + for (k = 0; k < MTK_JPEG_ENC_NUM_FORMATS; k++) { > > + fmt = &mtk_jpeg_enc_formats[k]; > > + > > + if (fmt->fourcc == pixelformat && fmt->flags & fmt_type) > > + return fmt; > > + } > > > > for (k = 0; k < MTK_JPEG_DEC_NUM_FORMATS; k++) { > > - struct mtk_jpeg_fmt *fmt = &mtk_jpeg_dec_formats[k]; > > + fmt = &mtk_jpeg_dec_formats[k]; > > > > - if (fmt->fourcc == pixelformat && fmt->flags & fmt_flag) > > + if (fmt->fourcc == pixelformat && fmt->flags & fmt_type) > > return fmt; > > } > > We should only need to iterate through one of the arrays. My suggestion > above about making "formats" and "num_formats" a member of the match data > should take care of this one too. done. > > > > > return NULL; > > } > > > > -static void mtk_jpeg_adjust_fmt_mplane(struct mtk_jpeg_ctx *ctx, > > - struct v4l2_format *f) > > -{ > > - struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; > > - struct mtk_jpeg_q_data *q_data; > > - int i; > > - > > - q_data = mtk_jpeg_get_q_data(ctx, f->type); > > - > > - pix_mp->width = q_data->w; > > - pix_mp->height = q_data->h; > > - pix_mp->pixelformat = q_data->fmt->fourcc; > > - pix_mp->num_planes = q_data->fmt->colplanes; > > - > > - for (i = 0; i < pix_mp->num_planes; i++) { > > - pix_mp->plane_fmt[i].bytesperline = q_data->bytesperline[i]; > > - pix_mp->plane_fmt[i].sizeimage = q_data->sizeimage[i]; > > - } > > -} > > - > > -static int mtk_jpeg_try_fmt_mplane(struct v4l2_format *f, > > - struct mtk_jpeg_fmt *fmt, > > - struct mtk_jpeg_ctx *ctx, int q_type) > > +static int vidioc_try_fmt(struct v4l2_format *f, struct mtk_jpeg_fmt *fmt) > > The name is a bit misleading, because it's suggesting that it's the > vidioc_try_fmt callback, but it's just an internal helper. I think the > original name was fine. changed it to original name. > > > { > > struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; > > int i; > > > > pix_mp->field = V4L2_FIELD_NONE; > > - > > - if (ctx->state != MTK_JPEG_INIT) { > > - mtk_jpeg_adjust_fmt_mplane(ctx, f); > > - return 0; > > - } > > Is it okay to remove this? My understanding is that it prevented changing > the format while streaming, which should is as expected. mtk_jpeg_g_fmt_vid_mplane() does the same thing, so use it to replace mtk_jpeg_adjust_fmt_mplane. > > > - > > pix_mp->num_planes = fmt->colplanes; > > pix_mp->pixelformat = fmt->fourcc; > > > > - if (q_type == MTK_JPEG_FMT_TYPE_OUTPUT) { > > - struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[0]; > > - > > + if (fmt->fourcc == V4L2_PIX_FMT_JPEG) { > > pix_mp->height = clamp(pix_mp->height, MTK_JPEG_MIN_HEIGHT, > > MTK_JPEG_MAX_HEIGHT); > > pix_mp->width = clamp(pix_mp->width, MTK_JPEG_MIN_WIDTH, > > MTK_JPEG_MAX_WIDTH); > > - > > - pfmt->bytesperline = 0; > > - /* Source size must be aligned to 128 */ > > - pfmt->sizeimage = round_up(pfmt->sizeimage, 128); > > - if (pfmt->sizeimage == 0) > > - pfmt->sizeimage = MTK_JPEG_DEFAULT_SIZEIMAGE; > > - return 0; > > + pix_mp->plane_fmt[0].bytesperline = 0; > > + pix_mp->plane_fmt[0].sizeimage = > > + round_up(pix_mp->plane_fmt[0].sizeimage, 128); > > + if (pix_mp->plane_fmt[0].sizeimage == 0) > > + pix_mp->plane_fmt[0].sizeimage = > > + MTK_JPEG_DEFAULT_SIZEIMAGE; > > + } else { > > + pix_mp->height = clamp(round_up(pix_mp->height, fmt->v_align), > > + MTK_JPEG_MIN_HEIGHT, > > + MTK_JPEG_MAX_HEIGHT); > > + pix_mp->width = clamp(round_up(pix_mp->width, fmt->h_align), > > + MTK_JPEG_MIN_WIDTH, MTK_JPEG_MAX_WIDTH); > > + for (i = 0; i < pix_mp->num_planes; i++) { > > + struct v4l2_plane_pix_format *pfmt = > > + &pix_mp->plane_fmt[i]; > > + u32 stride = pix_mp->width * fmt->h_sample[i] / 4; > > + u32 h = pix_mp->height * fmt->v_sample[i] / 4; > > + > > + pfmt->bytesperline = stride; > > + pfmt->sizeimage = stride * h; > > + } > > } > > > > - /* type is MTK_JPEG_FMT_TYPE_CAPTURE */ > > - pix_mp->height = clamp(round_up(pix_mp->height, fmt->v_align), > > - MTK_JPEG_MIN_HEIGHT, MTK_JPEG_MAX_HEIGHT); > > - pix_mp->width = clamp(round_up(pix_mp->width, fmt->h_align), > > - MTK_JPEG_MIN_WIDTH, MTK_JPEG_MAX_WIDTH); > > - > > - for (i = 0; i < fmt->colplanes; i++) { > > - struct v4l2_plane_pix_format *pfmt = &pix_mp->plane_fmt[i]; > > - u32 stride = pix_mp->width * fmt->h_sample[i] / 4; > > - u32 h = pix_mp->height * fmt->v_sample[i] / 4; > > - > > - pfmt->bytesperline = stride; > > - pfmt->sizeimage = stride * h; > > - } > > return 0; > > Are all the changes above needed for the encoder? If I'm looking correctly, > they're mostly refactoring and should be done in a separate patch. However, > I don't see any big issue with the existing coding style in this function, > so perhaps the refactoring could be avoided. In order to compatible jpeg encoder, use the fourcc to distinguish different types as you mentioned before. > > > } > > > > @@ -271,14 +377,35 @@ static int mtk_jpeg_g_fmt_vid_mplane(struct file *file, void *priv, > > return 0; > > } > > > > +static int mtk_jpeg_enc_try_fmt_vid_cap_mplane(struct file *file, void *priv, > > + struct v4l2_format *f) > > +{ > > + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); > > + struct mtk_jpeg_fmt *fmt; > > + > > + fmt = mtk_jpeg_find_format(f->fmt.pix_mp.pixelformat, > > + MTK_JPEG_FMT_FLAG_ENC_CAPTURE); > > + if (!fmt) > > + fmt = ctx->cap_q.fmt; > > + > > + v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n", > > + f->type, > > + (fmt->fourcc & 0xff), > > + (fmt->fourcc >> 8 & 0xff), > > + (fmt->fourcc >> 16 & 0xff), > > + (fmt->fourcc >> 24 & 0xff)); > > + > > + return vidioc_try_fmt(f, fmt); > > +} > > Is there really anything encoder-specific in this function? Could the same > function as the decoder be used instead? done. > > > + > > static int mtk_jpeg_dec_try_fmt_vid_cap_mplane(struct file *file, void *priv, > > struct v4l2_format *f) > > { > > struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); > > struct mtk_jpeg_fmt *fmt; > > > > - fmt = mtk_jpeg_find_format(ctx, f->fmt.pix_mp.pixelformat, > > - MTK_JPEG_FMT_TYPE_CAPTURE); > > + fmt = mtk_jpeg_find_format(f->fmt.pix_mp.pixelformat, > > + MTK_JPEG_FMT_FLAG_DEC_CAPTURE); > > if (!fmt) > > fmt = ctx->cap_q.fmt; > > > > @@ -289,7 +416,33 @@ static int mtk_jpeg_dec_try_fmt_vid_cap_mplane(struct file *file, void *priv, > > (fmt->fourcc >> 16 & 0xff), > > (fmt->fourcc >> 24 & 0xff)); > > > > - return mtk_jpeg_try_fmt_mplane(f, fmt, ctx, MTK_JPEG_FMT_TYPE_CAPTURE); > > + if (ctx->state != MTK_JPEG_INIT) { > > + mtk_jpeg_g_fmt_vid_mplane(file, priv, f); > > + return 0; > > + } > > Is this really limited to the decoder? In general currently we don't > support changing the resolution from the userspace when streaming is > started and it applies to both encoder and decoder. done. > > > + > > + return vidioc_try_fmt(f, fmt); > > +} > > + > > +static int mtk_jpeg_enc_try_fmt_vid_out_mplane(struct file *file, void *priv, > > + struct v4l2_format *f) > > +{ > > + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); > > + struct mtk_jpeg_fmt *fmt; > > + > > + fmt = mtk_jpeg_find_format(f->fmt.pix_mp.pixelformat, > > + MTK_JPEG_FMT_FLAG_ENC_OUTPUT); > > + if (!fmt) > > + fmt = ctx->out_q.fmt; > > + > > + v4l2_dbg(2, debug, &ctx->jpeg->v4l2_dev, "(%d) try_fmt:%c%c%c%c\n", > > + f->type, > > + (fmt->fourcc & 0xff), > > + (fmt->fourcc >> 8 & 0xff), > > + (fmt->fourcc >> 16 & 0xff), > > + (fmt->fourcc >> 24 & 0xff)); > > + > > + return vidioc_try_fmt(f, fmt); > > } > > Ditto. done. > > > > > static int mtk_jpeg_dec_try_fmt_vid_out_mplane(struct file *file, void *priv, > > @@ -298,8 +451,8 @@ static int mtk_jpeg_dec_try_fmt_vid_out_mplane(struct file *file, void *priv, > > struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); > > struct mtk_jpeg_fmt *fmt; > > > > - fmt = mtk_jpeg_find_format(ctx, f->fmt.pix_mp.pixelformat, > > - MTK_JPEG_FMT_TYPE_OUTPUT); > > + fmt = mtk_jpeg_find_format(f->fmt.pix_mp.pixelformat, > > + MTK_JPEG_FMT_FLAG_DEC_OUTPUT); > > if (!fmt) > > fmt = ctx->out_q.fmt; > > > > @@ -310,17 +463,21 @@ static int mtk_jpeg_dec_try_fmt_vid_out_mplane(struct file *file, void *priv, > > (fmt->fourcc >> 16 & 0xff), > > (fmt->fourcc >> 24 & 0xff)); > > > > - return mtk_jpeg_try_fmt_mplane(f, fmt, ctx, MTK_JPEG_FMT_TYPE_OUTPUT); > > + if (ctx->state != MTK_JPEG_INIT) { > > + mtk_jpeg_g_fmt_vid_mplane(file, priv, f); > > + return 0; > > + } > > Ditto. done. > > > + > > + return vidioc_try_fmt(f, fmt); > > } > > > > static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx, > > - struct v4l2_format *f) > > + struct v4l2_format *f, unsigned int fmt_type) > > { > > struct vb2_queue *vq; > > struct mtk_jpeg_q_data *q_data = NULL; > > struct v4l2_pix_format_mplane *pix_mp = &f->fmt.pix_mp; > > struct mtk_jpeg_dev *jpeg = ctx->jpeg; > > - unsigned int f_type; > > int i; > > > > vq = v4l2_m2m_get_vq(ctx->fh.m2m_ctx, f->type); > > @@ -334,12 +491,11 @@ static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx, > > return -EBUSY; > > } > > > > - f_type = V4L2_TYPE_IS_OUTPUT(f->type) ? > > - MTK_JPEG_FMT_TYPE_OUTPUT : MTK_JPEG_FMT_TYPE_CAPTURE; > > - > > - q_data->fmt = mtk_jpeg_find_format(ctx, pix_mp->pixelformat, f_type); > > + q_data->fmt = mtk_jpeg_find_format(pix_mp->pixelformat, fmt_type); > > q_data->w = pix_mp->width; > > q_data->h = pix_mp->height; > > + q_data->crop_rect.width = pix_mp->width; > > + q_data->crop_rect.height = pix_mp->height; > > ctx->colorspace = pix_mp->colorspace; > > ctx->ycbcr_enc = pix_mp->ycbcr_enc; > > ctx->xfer_func = pix_mp->xfer_func; > > @@ -365,6 +521,19 @@ static int mtk_jpeg_s_fmt_mplane(struct mtk_jpeg_ctx *ctx, > > return 0; > > } > > > > +static int mtk_jpeg_enc_s_fmt_vid_out_mplane(struct file *file, void *priv, > > + struct v4l2_format *f) > > +{ > > + int ret; > > + > > + ret = mtk_jpeg_enc_try_fmt_vid_out_mplane(file, priv, f); > > + if (ret) > > + return ret; > > + > > + return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f, > > + MTK_JPEG_FMT_FLAG_ENC_OUTPUT); > > +} > > + > > static int mtk_jpeg_dec_s_fmt_vid_out_mplane(struct file *file, void *priv, > > struct v4l2_format *f) > > { > > @@ -374,7 +543,21 @@ static int mtk_jpeg_dec_s_fmt_vid_out_mplane(struct file *file, void *priv, > > if (ret) > > return ret; > > > > - return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f); > > + return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f, > > + MTK_JPEG_FMT_FLAG_DEC_OUTPUT); > > +} > > + > > +static int mtk_jpeg_enc_s_fmt_vid_cap_mplane(struct file *file, void *priv, > > + struct v4l2_format *f) > > +{ > > + int ret; > > + > > + ret = mtk_jpeg_enc_try_fmt_vid_cap_mplane(file, priv, f); > > + if (ret) > > + return ret; > > + > > + return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f, > > + MTK_JPEG_FMT_FLAG_ENC_CAPTURE); > > } > > > > static int mtk_jpeg_dec_s_fmt_vid_cap_mplane(struct file *file, void *priv, > > @@ -386,7 +569,8 @@ static int mtk_jpeg_dec_s_fmt_vid_cap_mplane(struct file *file, void *priv, > > if (ret) > > return ret; > > > > - return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f); > > + return mtk_jpeg_s_fmt_mplane(mtk_jpeg_fh_to_ctx(priv), f, > > + MTK_JPEG_FMT_FLAG_DEC_CAPTURE); > > } > > Is it really necessary to have separate variants of the above functions for > decoder and encoder? done. > > > > > static void mtk_jpeg_queue_src_chg_event(struct mtk_jpeg_ctx *ctx) > > @@ -411,6 +595,29 @@ static int mtk_jpeg_subscribe_event(struct v4l2_fh *fh, > > return v4l2_ctrl_subscribe_event(fh, sub); > > } > > > > +static int mtk_jpeg_enc_g_selection(struct file *file, void *priv, > > + struct v4l2_selection *s) > > +{ > > + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); > > + > > + if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) > > + return -EINVAL; > > + > > + switch (s->target) { > > + case V4L2_SEL_TGT_CROP: > > + case V4L2_SEL_TGT_CROP_BOUNDS: > > + case V4L2_SEL_TGT_CROP_DEFAULT: > > + s->r.width = ctx->out_q.w; > > + s->r.height = ctx->out_q.h; > > + s->r.left = 0; > > + s->r.top = 0; > > Is this really correct? The function seems to be returning the full frame > size regardless of the selection target. For BOUNDS and DEFAULTS this would > be the correct behavior indeed, but CROP should return the active crop > rectangle, as set by S_SELECTION. done. > > > + break; > > + default: > > + return -EINVAL; > > + } > > + return 0; > > +} > > + > > static int mtk_jpeg_dec_g_selection(struct file *file, void *priv, > > struct v4l2_selection *s) > > { > > @@ -440,6 +647,29 @@ static int mtk_jpeg_dec_g_selection(struct file *file, void *priv, > > return 0; > > } > > > > +static int mtk_jpeg_enc_s_selection(struct file *file, void *priv, > > + struct v4l2_selection *s) > > +{ > > + struct mtk_jpeg_ctx *ctx = mtk_jpeg_fh_to_ctx(priv); > > + > > + if (s->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) > > + return -EINVAL; > > + > > + switch (s->target) { > > + case V4L2_SEL_TGT_CROP: > > + s->r.left = 0; > > + s->r.top = 0; > > + s->r.width = min(s->r.width, ctx->out_q.w); > > + s->r.height = min(s->r.height, ctx->out_q.h); > > + ctx->out_q.crop_rect = s->r; > > + break; > > + default: > > + return -EINVAL; > > + } > > + > > + return 0; > > +} > > + > > static int mtk_jpeg_dec_s_selection(struct file *file, void *priv, > > struct v4l2_selection *s) > > { > > @@ -484,6 +714,33 @@ static int mtk_jpeg_qbuf(struct file *file, void *priv, struct v4l2_buffer *buf) > > return v4l2_m2m_qbuf(file, fh->m2m_ctx, buf); > > } > > > > +static const struct v4l2_ioctl_ops mtk_jpeg_enc_ioctl_ops = { > > + .vidioc_querycap = mtk_jpeg_enc_querycap, > > + .vidioc_enum_fmt_vid_cap = mtk_jpeg_enc_enum_fmt_vid_cap, > > + .vidioc_enum_fmt_vid_out = mtk_jpeg_enc_enum_fmt_vid_out, > > + .vidioc_try_fmt_vid_cap_mplane = mtk_jpeg_enc_try_fmt_vid_cap_mplane, > > + .vidioc_try_fmt_vid_out_mplane = mtk_jpeg_enc_try_fmt_vid_out_mplane, > > + .vidioc_g_fmt_vid_cap_mplane = mtk_jpeg_g_fmt_vid_mplane, > > + .vidioc_g_fmt_vid_out_mplane = mtk_jpeg_g_fmt_vid_mplane, > > + .vidioc_s_fmt_vid_cap_mplane = mtk_jpeg_enc_s_fmt_vid_cap_mplane, > > + .vidioc_s_fmt_vid_out_mplane = mtk_jpeg_enc_s_fmt_vid_out_mplane, > > + .vidioc_qbuf = mtk_jpeg_qbuf, > > Not directly a comment for this patch, but since the previous patch removed > the LAST_FRAME handling, wouldn't it be enough to just use v4l2_m2m_qbuf() > as this callback? yes,done. > > [snip] > > +static void mtk_jpeg_enc_buf_queue(struct vb2_buffer *vb) > > +{ > > + struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); > > + struct mtk_jpeg_dev *jpeg = ctx->jpeg; > > + > > + v4l2_dbg(2, debug, &jpeg->v4l2_dev, "(%d) buf_q id=%d, vb=%p\n", > > + vb->vb2_queue->type, vb->index, vb); > > + > > + v4l2_m2m_buf_queue(ctx->fh.m2m_ctx, to_vb2_v4l2_buffer(vb)); > > +} > > + > > static void mtk_jpeg_dec_buf_queue(struct vb2_buffer *vb) > > { > > struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(vb->vb2_queue); > > @@ -664,6 +932,15 @@ static struct vb2_v4l2_buffer *mtk_jpeg_buf_remove(struct mtk_jpeg_ctx *ctx, > > return v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); > > } > > > > +static void mtk_jpeg_enc_stop_streaming(struct vb2_queue *q) > > +{ > > + struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q); > > + struct vb2_v4l2_buffer *vb; > > + > > + while ((vb = mtk_jpeg_buf_remove(ctx, q->type))) > > + v4l2_m2m_buf_done(vb, VB2_BUF_STATE_ERROR); > > +} > > + > > static void mtk_jpeg_dec_stop_streaming(struct vb2_queue *q) > > { > > struct mtk_jpeg_ctx *ctx = vb2_get_drv_priv(q); > > @@ -699,6 +976,15 @@ static const struct vb2_ops mtk_jpeg_dec_qops = { > > .stop_streaming = mtk_jpeg_dec_stop_streaming, > > }; > > > > +static const struct vb2_ops mtk_jpeg_enc_qops = { > > + .queue_setup = mtk_jpeg_queue_setup, > > + .buf_prepare = mtk_jpeg_buf_prepare, > > + .buf_queue = mtk_jpeg_enc_buf_queue, > > + .wait_prepare = vb2_ops_wait_prepare, > > + .wait_finish = vb2_ops_wait_finish, > > + .stop_streaming = mtk_jpeg_enc_stop_streaming, > > +}; > > + > > static void mtk_jpeg_set_dec_src(struct mtk_jpeg_ctx *ctx, > > struct vb2_buffer *src_buf, > > struct mtk_jpeg_bs *bs) > > @@ -736,6 +1022,85 @@ static int mtk_jpeg_set_dec_dst(struct mtk_jpeg_ctx *ctx, > > return 0; > > } > > > > +static void mtk_jpeg_set_enc_dst(struct mtk_jpeg_ctx *ctx, void __iomem *base, > > + struct vb2_buffer *dst_buf, > > + struct mtk_jpeg_enc_bs *bs) > > +{ > > + bs->dma_addr = vb2_dma_contig_plane_dma_addr(dst_buf, 0); > > + bs->dma_addr_offset = ctx->enable_exif ? MTK_JPEG_MAX_EXIF_SIZE : 0; > > + bs->dma_addr_offsetmask = bs->dma_addr & JPEG_ENC_DST_ADDR_OFFSET_MASK; > > + bs->size = vb2_plane_size(dst_buf, 0); > > We're computing these values and then writing to the hardware straightaway. > Do we need to save these values to the bs struct? If no, do we need the bs > struct at all? yes, removed this structure. > > > + > > + mtk_jpeg_enc_set_dst_addr(base, bs->dma_addr, bs->size, > > + bs->dma_addr_offset, > > + bs->dma_addr_offsetmask); > > +} > > + > > +static void mtk_jpeg_set_enc_src(struct mtk_jpeg_ctx *ctx, void __iomem *base, > > + struct vb2_buffer *src_buf) > > +{ > > + int i; > > + dma_addr_t dma_addr; > > nit: Only one space should be between variable type and name. done. > > > + > > + mtk_jpeg_enc_set_img_size(base, ctx->out_q.crop_rect.width, > > + ctx->out_q.crop_rect.height); > > + mtk_jpeg_enc_set_blk_num(base, ctx->out_q.fmt->fourcc, > > + ctx->out_q.crop_rect.width, > > + ctx->out_q.crop_rect.height); > > + mtk_jpeg_enc_set_stride(base, ctx->out_q.fmt->fourcc, ctx->out_q.w, > > + ctx->out_q.h, ctx->out_q.bytesperline[0]); > > + > > + for (i = 0; i < src_buf->num_planes; i++) { > > + dma_addr = vb2_dma_contig_plane_dma_addr(src_buf, i) + > > + src_buf->planes[i].data_offset; > > + mtk_jpeg_enc_set_src_addr(base, dma_addr, i); > > + } > > +} > > + > > +static void mtk_jpeg_enc_device_run(void *priv) > > +{ > > + struct mtk_jpeg_ctx *ctx = priv; > > + struct mtk_jpeg_dev *jpeg = ctx->jpeg; > > + struct vb2_v4l2_buffer *src_buf, *dst_buf; > > + enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; > > + unsigned long flags; > > + struct mtk_jpeg_src_buf *jpeg_src_buf; > > + struct mtk_jpeg_enc_bs enc_bs; > > + int ret; > > + > > + src_buf = v4l2_m2m_next_src_buf(ctx->fh.m2m_ctx); > > + dst_buf = v4l2_m2m_next_dst_buf(ctx->fh.m2m_ctx); > > + jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf); > > + > > + ret = pm_runtime_get_sync(jpeg->dev); > > + if (ret < 0) > > + goto enc_end; > > + > > + spin_lock_irqsave(&jpeg->hw_lock, flags); > > + > > + /* > > + * Resetting the hardware every frame is to ensure that all the > > + * registers are cleared. This is a hardware requirement. > > + */ > > + mtk_jpeg_enc_reset(jpeg->reg_base); > > + > > + mtk_jpeg_set_enc_dst(ctx, jpeg->reg_base, &dst_buf->vb2_buf, &enc_bs); > > + mtk_jpeg_set_enc_src(ctx, jpeg->reg_base, &src_buf->vb2_buf); > > + mtk_jpeg_enc_set_config(jpeg->reg_base, ctx->out_q.fmt->hw_format, > > + ctx->enable_exif, ctx->enc_quality, > > + ctx->restart_interval); > > + mtk_jpeg_enc_start(jpeg->reg_base); > > Could we just move the above 5 functions into one function inside > mtk_jpeg_enc_hw.c that takes mtk_jpeg_dev pointer as its argument, let's > say mtk_jpeg_enc_hw_run() and simply program all the data to the registers > directly, without the extra level of abstractions? done. > > > + spin_unlock_irqrestore(&jpeg->hw_lock, flags); > > + return; > > + > > +enc_end: > > + v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); > > + v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); > > + v4l2_m2m_buf_done(src_buf, buf_state); > > + v4l2_m2m_buf_done(dst_buf, buf_state); > > + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); > > +} > > + > > static void mtk_jpeg_dec_device_run(void *priv) > > { > > struct mtk_jpeg_ctx *ctx = priv; > > @@ -785,6 +1150,11 @@ static void mtk_jpeg_dec_device_run(void *priv) > > v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); > > } > > > > +static int mtk_jpeg_enc_job_ready(void *priv) > > +{ > > + return 1; > > +} > > + > > The callback is optional, so can be just removed if it always returns 1. done. > > > static int mtk_jpeg_dec_job_ready(void *priv) > > { > > struct mtk_jpeg_ctx *ctx = priv; > > @@ -792,6 +1162,11 @@ static int mtk_jpeg_dec_job_ready(void *priv) > > return (ctx->state == MTK_JPEG_RUNNING) ? 1 : 0; > > } > > > > +static const struct v4l2_m2m_ops mtk_jpeg_enc_m2m_ops = { > > + .device_run = mtk_jpeg_enc_device_run, > > + .job_ready = mtk_jpeg_enc_job_ready, > > +}; > > + > > static const struct v4l2_m2m_ops mtk_jpeg_dec_m2m_ops = { > > .device_run = mtk_jpeg_dec_device_run, > > .job_ready = mtk_jpeg_dec_job_ready, > > @@ -830,24 +1205,109 @@ static int mtk_jpeg_dec_queue_init(void *priv, struct vb2_queue *src_vq, > > return ret; > > } > > > > -static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg) > > +static int mtk_jpeg_enc_queue_init(void *priv, struct vb2_queue *src_vq, > > + struct vb2_queue *dst_vq) > > { > > + struct mtk_jpeg_ctx *ctx = priv; > > int ret; > > > > + src_vq->type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE; > > + src_vq->io_modes = VB2_DMABUF | VB2_MMAP; > > + src_vq->drv_priv = ctx; > > + src_vq->buf_struct_size = sizeof(struct mtk_jpeg_src_buf); > > + src_vq->ops = &mtk_jpeg_enc_qops; > > + src_vq->mem_ops = &vb2_dma_contig_memops; > > + src_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; > > + src_vq->lock = &ctx->jpeg->lock; > > + src_vq->dev = ctx->jpeg->dev; > > + ret = vb2_queue_init(src_vq); > > + if (ret) > > + return ret; > > + > > + dst_vq->type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE; > > + dst_vq->io_modes = VB2_DMABUF | VB2_MMAP; > > + dst_vq->drv_priv = ctx; > > + dst_vq->buf_struct_size = sizeof(struct v4l2_m2m_buffer); > > + dst_vq->ops = &mtk_jpeg_enc_qops; > > + dst_vq->mem_ops = &vb2_dma_contig_memops; > > + dst_vq->timestamp_flags = V4L2_BUF_FLAG_TIMESTAMP_COPY; > > + dst_vq->lock = &ctx->jpeg->lock; > > + dst_vq->dev = ctx->jpeg->dev; > > + ret = vb2_queue_init(dst_vq); > > + > > + return ret; > > +} > > This only differs in "ops" from the decoder implementation. Perhaps > both functions could be merged? done. > > > + > > +static void mtk_jpeg_clk_on(struct mtk_jpeg_dev *jpeg) > > +{ > > + int ret, i; > > + > > ret = mtk_smi_larb_get(jpeg->larb); > > if (ret) > > dev_err(jpeg->dev, "mtk_smi_larb_get larbvdec fail %d\n", ret); > > - clk_prepare_enable(jpeg->clk_jdec_smi); > > - clk_prepare_enable(jpeg->clk_jdec); > > + > > + for (i = 0; i < jpeg->variant->num_clocks; i++) { > > + ret = clk_prepare_enable(jpeg->clocks[i]); > > Instead of an open coded loop, could the clk_bulk_*() helpers be used > instead? (Look for devm_clk_bulk_get() and devm_clk_bulk_prepare_enable().) > > > + if (ret) { > > + while (--i >= 0) > > + clk_disable_unprepare(jpeg->clocks[i]); > > nit: The typical convention is to do error handling in an error path on the > bottom of the function. done > > Also, it would be nice to print an error message. done. > > > + } > > + } > > } > > > > static void mtk_jpeg_clk_off(struct mtk_jpeg_dev *jpeg) > > { > > - clk_disable_unprepare(jpeg->clk_jdec); > > - clk_disable_unprepare(jpeg->clk_jdec_smi); > > + int i; > > + > > + for (i = jpeg->variant->num_clocks - 1; i >= 0; i--) > > + clk_disable_unprepare(jpeg->clocks[i]); > > Ditto. done. > > > mtk_smi_larb_put(jpeg->larb); > > } > > > > +static irqreturn_t mtk_jpeg_enc_irq(int irq, void *priv) > > +{ > > + struct mtk_jpeg_dev *jpeg = priv; > > + struct mtk_jpeg_ctx *ctx; > > + struct vb2_v4l2_buffer *src_buf, *dst_buf; > > + struct mtk_jpeg_src_buf *jpeg_src_buf; > > + enum vb2_buffer_state buf_state = VB2_BUF_STATE_ERROR; > > + u32 enc_irq_ret; > > + u32 enc_ret, result_size; > > + > > + ctx = v4l2_m2m_get_curr_priv(jpeg->m2m_dev); > > + if (!ctx) { > > + v4l2_err(&jpeg->v4l2_dev, "Context is NULL\n"); > > + return IRQ_HANDLED; > > + } > > + > > + src_buf = v4l2_m2m_src_buf_remove(ctx->fh.m2m_ctx); > > + dst_buf = v4l2_m2m_dst_buf_remove(ctx->fh.m2m_ctx); > > + jpeg_src_buf = mtk_jpeg_vb2_to_srcbuf(&src_buf->vb2_buf); > > + > > + enc_ret = mtk_jpeg_enc_get_and_clear_int_status(jpeg->reg_base); > > We should check the interrupt status at the beginning of the function and > return IRQ_NONE if there wasn't any flag set. done. > > > + enc_irq_ret = mtk_jpeg_enc_enum_result(jpeg->reg_base, enc_ret); > > + > > + if (enc_irq_ret >= MTK_JPEG_ENC_RESULT_STALL) > > + mtk_jpeg_enc_reset(jpeg->reg_base); > > + > > + if (enc_irq_ret != MTK_JPEG_ENC_RESULT_DONE) { > > + dev_err(jpeg->dev, "encode failed\n"); > > + goto enc_end; > > + } > > As I suggested before, it would have been much more clear if the interrupt > status bits were just directly read and checked in this function, without > introducing the additional abstraction. done. > > > + > > + result_size = mtk_jpeg_enc_get_file_size(jpeg->reg_base); > > + vb2_set_plane_payload(&dst_buf->vb2_buf, 0, result_size); > > + > > + buf_state = VB2_BUF_STATE_DONE; > > + > > +enc_end: > > + v4l2_m2m_buf_done(src_buf, buf_state); > > + v4l2_m2m_buf_done(dst_buf, buf_state); > > + v4l2_m2m_job_finish(jpeg->m2m_dev, ctx->fh.m2m_ctx); > > + pm_runtime_put(ctx->jpeg->dev); > > + return IRQ_HANDLED; > > +} > > + > > static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) > > { > > struct mtk_jpeg_dev *jpeg = priv; > > @@ -893,36 +1353,130 @@ static irqreturn_t mtk_jpeg_dec_irq(int irq, void *priv) > > return IRQ_HANDLED; > > } > > > > +static void mtk_jpeg_set_enc_default_params(struct mtk_jpeg_ctx *ctx) > > +{ > > + struct mtk_jpeg_q_data *q = &ctx->out_q; > > + struct v4l2_pix_format_mplane *pix_mp; > > + > > + pix_mp = kmalloc(sizeof(*pix_mp), GFP_KERNEL); > > Do we need to allocate this pix_mp? Could we instead just embed it inside > ctx? > > Also, this is actually a memory leak, because I don't see this structure > saved anywhere or freed. > > > + > > + ctx->fh.ctrl_handler = &ctx->ctrl_hdl; > > + ctx->colorspace = V4L2_COLORSPACE_JPEG, > > + ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; > > + ctx->quantization = V4L2_QUANTIZATION_DEFAULT; > > + ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT; > > Since we already have a v4l2_pix_format_mplane struct which has fields for > the above 4 values, could we just store them there? > > Also, I don't see this driver handling the colorspaces in any way, but it > seems to allow changing them from the userspace. This is incorrect, because > the userspace has no way to know that the colorspace is not handled. > Instead, the try_fmt implementation should always override the > userspace-provided colorspace configuration with the ones that the driver > assumes. did as what we discussed earlier. > > > + pix_mp->width = MTK_JPEG_MIN_WIDTH; > > + pix_mp->height = MTK_JPEG_MIN_HEIGHT; > > + > > + q->fmt = mtk_jpeg_find_format(V4L2_PIX_FMT_YUYV, > > + MTK_JPEG_FMT_FLAG_ENC_OUTPUT); > > + vidioc_try_fmt(container_of(pix_mp, struct v4l2_format, > > + fmt.pix_mp), q->fmt); > > + q->w = pix_mp->width; > > + q->h = pix_mp->height; > > + q->crop_rect.width = pix_mp->width; > > + q->crop_rect.height = pix_mp->height; > > + q->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage; > > + q->bytesperline[0] = pix_mp->plane_fmt[0].bytesperline; > > Actually, do we need this custom mtk_jpeg_q_data struct? Why couldn't we > just keep the same values inside the standard v4l2_pix_format_mplane > struct? > > In general it's preferred to use the standard kernel structures as much as > possible and only introduce local driver structures for data that can't be > stored in generic ones. did as what we discussed earlier. > > > + > > + q = &ctx->cap_q; > > + q->fmt = mtk_jpeg_find_format(V4L2_PIX_FMT_JPEG, > > + MTK_JPEG_FMT_FLAG_ENC_CAPTURE); > > + pix_mp->width = MTK_JPEG_MIN_WIDTH; > > + pix_mp->height = MTK_JPEG_MIN_HEIGHT; > > + vidioc_try_fmt(container_of(pix_mp, struct v4l2_format, > > + fmt.pix_mp), q->fmt); > > + q->w = pix_mp->width; > > + q->h = pix_mp->height; > > + q->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage; > > + q->bytesperline[0] = pix_mp->plane_fmt[0].bytesperline; > > Ditto. done. > > > +} > > + > > static void mtk_jpeg_set_dec_default_params(struct mtk_jpeg_ctx *ctx) > > { > > struct mtk_jpeg_q_data *q = &ctx->out_q; > > + struct v4l2_pix_format_mplane *pix_mp; > > int i; > > > > + pix_mp = kmalloc(sizeof(*pix_mp), GFP_KERNEL); > > + > > + ctx->fh.ctrl_handler = &ctx->ctrl_hdl; > > ctx->colorspace = V4L2_COLORSPACE_JPEG, > > ctx->ycbcr_enc = V4L2_YCBCR_ENC_DEFAULT; > > ctx->quantization = V4L2_QUANTIZATION_DEFAULT; > > ctx->xfer_func = V4L2_XFER_FUNC_DEFAULT; > > - > > - q->fmt = mtk_jpeg_find_format(ctx, V4L2_PIX_FMT_JPEG, > > - MTK_JPEG_FMT_TYPE_OUTPUT); > > - q->w = MTK_JPEG_MIN_WIDTH; > > - q->h = MTK_JPEG_MIN_HEIGHT; > > - q->bytesperline[0] = 0; > > - q->sizeimage[0] = MTK_JPEG_DEFAULT_SIZEIMAGE; > > + pix_mp->width = MTK_JPEG_MIN_WIDTH; > > + pix_mp->height = MTK_JPEG_MIN_HEIGHT; > > + > > + q->fmt = mtk_jpeg_find_format(V4L2_PIX_FMT_JPEG, > > + MTK_JPEG_FMT_FLAG_DEC_OUTPUT); > > + vidioc_try_fmt(container_of(pix_mp, struct v4l2_format, > > + fmt.pix_mp), q->fmt); > > + q->w = pix_mp->width; > > + q->h = pix_mp->height; > > + q->sizeimage[0] = pix_mp->plane_fmt[0].sizeimage; > > + q->bytesperline[0] = pix_mp->plane_fmt[0].bytesperline; > > > > q = &ctx->cap_q; > > - q->fmt = mtk_jpeg_find_format(ctx, V4L2_PIX_FMT_YUV420M, > > - MTK_JPEG_FMT_TYPE_CAPTURE); > > - q->w = MTK_JPEG_MIN_WIDTH; > > - q->h = MTK_JPEG_MIN_HEIGHT; > > - > > + q->fmt = mtk_jpeg_find_format(V4L2_PIX_FMT_YUV420M, > > + MTK_JPEG_FMT_FLAG_DEC_CAPTURE); > > + pix_mp->width = MTK_JPEG_MIN_WIDTH; > > + pix_mp->height = MTK_JPEG_MIN_HEIGHT; > > + vidioc_try_fmt(container_of(pix_mp, struct v4l2_format, > > + fmt.pix_mp), q->fmt); > > + q->w = pix_mp->width; > > + q->h = pix_mp->height; > > for (i = 0; i < q->fmt->colplanes; i++) { > > - u32 stride = q->w * q->fmt->h_sample[i] / 4; > > - u32 h = q->h * q->fmt->v_sample[i] / 4; > > + q->sizeimage[i] = pix_mp->plane_fmt[i].sizeimage; > > + q->bytesperline[i] = pix_mp->plane_fmt[i].bytesperline; > > + } > > +} > > > > Same comments as for the encoder version. > > On top of that, both functions are almost identical and it should be > possible to merge them. done. > > > - q->bytesperline[i] = stride; > > - q->sizeimage[i] = stride * h; > > +static int mtk_jpeg_enc_open(struct file *file) > > +{ > > + struct mtk_jpeg_dev *jpeg = video_drvdata(file); > > + struct video_device *vfd = video_devdata(file); > > + struct mtk_jpeg_ctx *ctx; > > + int ret = 0; > > + > > + ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); > > + if (!ctx) > > + return -ENOMEM; > > + > > + if (mutex_lock_interruptible(&jpeg->lock)) { > > + ret = -ERESTARTSYS; > > + goto free; > > + } > > + > > + v4l2_fh_init(&ctx->fh, vfd); > > + file->private_data = &ctx->fh; > > + v4l2_fh_add(&ctx->fh); > > + > > + ctx->jpeg = jpeg; > > + ctx->fh.m2m_ctx = v4l2_m2m_ctx_init(jpeg->m2m_dev, ctx, > > + mtk_jpeg_enc_queue_init); > > + if (IS_ERR(ctx->fh.m2m_ctx)) { > > + ret = PTR_ERR(ctx->fh.m2m_ctx); > > + goto error; > > } > > + > > + ret = mtk_jpeg_enc_ctrls_setup(ctx); > > + if (ret) { > > + v4l2_err(&jpeg->v4l2_dev, "Failed to setup jpeg enc controls\n"); > > + goto error; > > + } > > + mtk_jpeg_set_enc_default_params(ctx); > > + > > + mutex_unlock(&jpeg->lock); > > + return 0; > > + > > +error: > > + v4l2_fh_del(&ctx->fh); > > + v4l2_fh_exit(&ctx->fh); > > + mutex_unlock(&jpeg->lock); > > +free: > > + kfree(ctx); > > + return ret; > > } > > It looks like the queue_init argument to v4l2_m2m_ctx_init() and control > handling would be the only differences from the decoder version. Perhaps > the functions can be merged? done. > > > > > static int mtk_jpeg_dec_open(struct file *file) > > @@ -953,6 +1507,12 @@ static int mtk_jpeg_dec_open(struct file *file) > > goto error; > > } > > > > + v4l2_ctrl_handler_init(&ctx->ctrl_hdl, 0); > > + ret = v4l2_ctrl_handler_setup(&ctx->ctrl_hdl); > > + if (ret) { > > + v4l2_err(&jpeg->v4l2_dev, "Failed to setup jpeg dec controls\n"); > > + goto error; > > + } > > There are no controls for the decoder, so there should be no need to set up > a control handler. done. > > > mtk_jpeg_set_dec_default_params(ctx); > > mutex_unlock(&jpeg->lock); > > return 0; > > @@ -973,6 +1533,7 @@ static int mtk_jpeg_release(struct file *file) > > > > mutex_lock(&jpeg->lock); > > v4l2_m2m_ctx_release(ctx->fh.m2m_ctx); > > + v4l2_ctrl_handler_free(&ctx->ctrl_hdl); > > v4l2_fh_del(&ctx->fh); > > v4l2_fh_exit(&ctx->fh); > > kfree(ctx); > > @@ -980,6 +1541,15 @@ static int mtk_jpeg_release(struct file *file) > > return 0; > > } > > > > +static const struct v4l2_file_operations mtk_jpeg_enc_fops = { > > + .owner = THIS_MODULE, > > + .open = mtk_jpeg_enc_open, > > + .release = mtk_jpeg_release, > > + .poll = v4l2_m2m_fop_poll, > > + .unlocked_ioctl = video_ioctl2, > > + .mmap = v4l2_m2m_fop_mmap, > > +}; > > + > > If we merge the .open() implementation, the same struct could be used for > both decoder and encoder. done. > > [snip] > > @@ -1042,8 +1619,12 @@ static int mtk_jpeg_probe(struct platform_device *pdev) > > return jpeg_irq; > > } > > > > - ret = devm_request_irq(&pdev->dev, jpeg_irq, mtk_jpeg_dec_irq, 0, > > - pdev->name, jpeg); > > + if (jpeg->variant->is_encoder) > > + ret = devm_request_irq(&pdev->dev, jpeg_irq, mtk_jpeg_enc_irq, > > + 0, pdev->name, jpeg); > > + else > > + ret = devm_request_irq(&pdev->dev, jpeg_irq, mtk_jpeg_dec_irq, > > + 0, pdev->name, jpeg); > > Rather than having "is_encoder" in the variant struct, would it make more > sense to have "irq_handler" instead? That would avoid the explicit if. done. > > > if (ret) { > > dev_err(&pdev->dev, "Failed to request jpeg_irq %d (%d)\n", > > jpeg_irq, ret); > > @@ -1063,7 +1644,10 @@ static int mtk_jpeg_probe(struct platform_device *pdev) > > goto err_dev_register; > > } > > > > - jpeg->m2m_dev = v4l2_m2m_init(&mtk_jpeg_dec_m2m_ops); > > + if (jpeg->variant->is_encoder) > > + jpeg->m2m_dev = v4l2_m2m_init(&mtk_jpeg_enc_m2m_ops); > > + else > > + jpeg->m2m_dev = v4l2_m2m_init(&mtk_jpeg_dec_m2m_ops); > > Same here. The variant struct could have a "m2m_ops" pointer. done. > > > if (IS_ERR(jpeg->m2m_dev)) { > > v4l2_err(&jpeg->v4l2_dev, "Failed to init mem2mem device\n"); > > ret = PTR_ERR(jpeg->m2m_dev); > > @@ -1076,9 +1660,15 @@ static int mtk_jpeg_probe(struct platform_device *pdev) > > goto err_vfd_jpeg_alloc; > > } > > snprintf(jpeg->vdev->name, sizeof(jpeg->vdev->name), > > - "%s-dec", MTK_JPEG_NAME); > > - jpeg->vdev->fops = &mtk_jpeg_dec_fops; > > - jpeg->vdev->ioctl_ops = &mtk_jpeg_dec_ioctl_ops; > > + "%s-%s", MTK_JPEG_NAME, > > + jpeg->variant->is_encoder ? "enc" : "dec"); > > + if (jpeg->variant->is_encoder) { > > + jpeg->vdev->fops = &mtk_jpeg_enc_fops; > > + jpeg->vdev->ioctl_ops = &mtk_jpeg_enc_ioctl_ops; > > + } else { > > + jpeg->vdev->fops = &mtk_jpeg_dec_fops; > > + jpeg->vdev->ioctl_ops = &mtk_jpeg_dec_ioctl_ops; > > + } > > Similarly here. done. > > [snip] > > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h > > index 0b59e48495d5..9ec2c3350a16 100644 > > --- a/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h > > +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_core.h > > @@ -3,6 +3,7 @@ > > * Copyright (c) 2016 MediaTek Inc. > > * Author: Ming Hsiu Tsai > > * Rick Chang > > + * Xia Jiang > > */ > > > > #ifndef _MTK_JPEG_CORE_H > > @@ -16,19 +17,21 @@ > > #define MTK_JPEG_NAME "mtk-jpeg" > > > > #define MTK_JPEG_COMP_MAX 3 > > +#define MTK_JPEG_MAX_CLOCKS 2 > > + > > > > Duplicate blank line. removed. > > > #define MTK_JPEG_FMT_FLAG_DEC_OUTPUT BIT(0) > > #define MTK_JPEG_FMT_FLAG_DEC_CAPTURE BIT(1) > > - > > -#define MTK_JPEG_FMT_TYPE_OUTPUT 1 > > -#define MTK_JPEG_FMT_TYPE_CAPTURE 2 > > +#define MTK_JPEG_FMT_FLAG_ENC_OUTPUT BIT(2) > > +#define MTK_JPEG_FMT_FLAG_ENC_CAPTURE BIT(3) > > Do we need separate bits for decoder and encoder? no need, I have removed it. > > > > > #define MTK_JPEG_MIN_WIDTH 32U > > #define MTK_JPEG_MIN_HEIGHT 32U > > -#define MTK_JPEG_MAX_WIDTH 8192U > > -#define MTK_JPEG_MAX_HEIGHT 8192U > > +#define MTK_JPEG_MAX_WIDTH 65535U > > +#define MTK_JPEG_MAX_HEIGHT 65535U > > If this is a change valid for the decoder too, it should be a separate > patch. done. > > > > > #define MTK_JPEG_DEFAULT_SIZEIMAGE (1 * 1024 * 1024) > > +#define MTK_JPEG_MAX_EXIF_SIZE (64 * 1024) > > There is one thing that I realized now. If the EXIF mode is enabled, the > driver needs to ensure that the buffer is big enough to hold the EXIF data. > The vb2 .buf_prepare callback would be the right place to do that. done. > > > > > /** > > * enum mtk_jpeg_ctx_state - states of the context state machine > > @@ -42,6 +45,18 @@ enum mtk_jpeg_ctx_state { > > MTK_JPEG_SOURCE_CHANGE, > > }; > > > > +/** > > + * mtk_jpeg_variant - mtk jpeg driver variant > > + * @is_encoder: driver mode is jpeg encoder > > + * @clk_names: clock names > > + * @num_clocks: numbers of clock > > + */ > > +struct mtk_jpeg_variant { > > + bool is_encoder; > > + const char *clk_names[MTK_JPEG_MAX_CLOCKS]; > > + int num_clocks; > > hint: Please avoid tabs between types and names, as it makes it difficult > to add new fields later (the number of tabs might need to change for all > members). done. > > [snip] > > diff --git a/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c > > new file mode 100644 > > index 000000000000..7fc1de920a75 > > --- /dev/null > > +++ b/drivers/media/platform/mtk-jpeg/mtk_jpeg_enc_hw.c > > @@ -0,0 +1,193 @@ > > +// SPDX-License-Identifier: GPL-2.0-only > > +/* > > + * Copyright (c) 2019 MediaTek Inc. > > + * Author: Xia Jiang > > + * > > + */ > > + > > +#include > > +#include > > +#include > > + > > +#include "mtk_jpeg_enc_hw.h" > > + > > +static const struct mtk_jpeg_enc_qlt mtk_jpeg_enc_quality[] = { > > + {.quality_param = 34, .hardware_value = JPEG_ENC_QUALITY_Q34}, > > + {.quality_param = 39, .hardware_value = JPEG_ENC_QUALITY_Q39}, > > + {.quality_param = 48, .hardware_value = JPEG_ENC_QUALITY_Q48}, > > + {.quality_param = 60, .hardware_value = JPEG_ENC_QUALITY_Q60}, > > + {.quality_param = 64, .hardware_value = JPEG_ENC_QUALITY_Q64}, > > + {.quality_param = 68, .hardware_value = JPEG_ENC_QUALITY_Q68}, > > + {.quality_param = 74, .hardware_value = JPEG_ENC_QUALITY_Q74}, > > + {.quality_param = 80, .hardware_value = JPEG_ENC_QUALITY_Q80}, > > + {.quality_param = 82, .hardware_value = JPEG_ENC_QUALITY_Q82}, > > + {.quality_param = 84, .hardware_value = JPEG_ENC_QUALITY_Q84}, > > + {.quality_param = 87, .hardware_value = JPEG_ENC_QUALITY_Q87}, > > + {.quality_param = 90, .hardware_value = JPEG_ENC_QUALITY_Q90}, > > + {.quality_param = 92, .hardware_value = JPEG_ENC_QUALITY_Q92}, > > + {.quality_param = 95, .hardware_value = JPEG_ENC_QUALITY_Q95}, > > + {.quality_param = 97, .hardware_value = JPEG_ENC_QUALITY_Q97}, > > +}; > > + > > +void mtk_jpeg_enc_reset(void __iomem *base) > > I'd suggest passing struct mtk_jpeg_dev pointer to all these functions, in > case more data about the hardware is needed in the future. > > > +{ > > + writel(0x00, base + JPEG_ENC_RSTB); > > nit: Just 0 is enough. done. > > > + writel(JPEG_ENC_RESET_BIT, base + JPEG_ENC_RSTB); > > + writel(0x00, base + JPEG_ENC_CODEC_SEL); > > Ditto. done. > > > +} > > + > > +u32 mtk_jpeg_enc_get_and_clear_int_status(void __iomem *base) > > +{ > > + u32 ret; > > + > > + ret = readl(base + JPEG_ENC_INT_STS) & > > + JPEG_ENC_INT_STATUS_MASK_ALLIRQ; > > + if (ret) > > + writel(0, base + JPEG_ENC_INT_STS); > > + > > + return ret; > > +} > > + > > +u32 mtk_jpeg_enc_get_file_size(void __iomem *base) > > +{ > > + return readl(base + JPEG_ENC_DMA_ADDR0) - > > + readl(base + JPEG_ENC_DST_ADDR0); > > +} > > + > > +u32 mtk_jpeg_enc_enum_result(void __iomem *base, u32 irq_status) > > +{ > > + if (irq_status & JPEG_ENC_INT_STATUS_DONE) > > + return MTK_JPEG_ENC_RESULT_DONE; > > + else if (irq_status & JPEG_ENC_INT_STATUS_STALL) > > + return MTK_JPEG_ENC_RESULT_STALL; > > + else > > + return MTK_JPEG_ENC_RESULT_VCODEC_IRQ; > > +} > > It looks like the driver only cares about 2 cases: DONE and anything else. > Actually it also cares about a case where no bits are set in irq_status, > which could be an interrupt controller misconfiguration or an interrupt > generated by another device on the same shared IRQ line, which should be > handled by returning IRQ_NONE. Since interrupt handling is a low level > hardware operation, I'd suggest another design: > - put the irq_handler_t function here in this file and have it directly > access the hardware registers and check the interrupt bits, > - add an mtk_jpeg_enc_done(..., enum vb2_buffer_state state, size_t > payload), which would be called from this low level interrupt handler and > do the V4L2 buffer and M2M job handling. > > WDYT? done. > > > + > > +void mtk_jpeg_enc_set_img_size(void __iomem *base, u32 width, u32 height) > > If we pass struct mtk_jpeg_dev to this function, the width and height > arguments wouldn't be necessary, as they could be directly retrieved from > the driver state. > > Similar advice applies to the other functions in this file. done. > > > +{ > > + u32 value; > > + > > + value = width << 16 | height; > > + writel(value, base + JPEG_ENC_IMG_SIZE); > > +} > > + > > +void mtk_jpeg_enc_set_blk_num(void __iomem *base, u32 enc_format, u32 width, > > + u32 height) > > +{ > > + u32 blk_num; > > + u32 is_420; > > + u32 padding_width; > > + u32 padding_height; > > + u32 luma_blocks; > > + u32 chroma_blocks; > > + > > + is_420 = (enc_format == V4L2_PIX_FMT_NV12M || > > + enc_format == V4L2_PIX_FMT_NV21M) ? 1 : 0; > > + padding_width = round_up(width, 16); > > + padding_height = round_up(height, is_420 ? 16 : 8); > > + > > + luma_blocks = padding_width / 8 * padding_height / 8; > > + if (is_420) > > + chroma_blocks = luma_blocks / 4; > > + else > > + chroma_blocks = luma_blocks / 2; > > + > > + blk_num = luma_blocks + 2 * chroma_blocks - 1; > > + > > + writel(blk_num, base + JPEG_ENC_BLK_NUM); > > +} > > My comments for this function from v7 haven't been addressed. done. > > > + > > +void mtk_jpeg_enc_set_stride(void __iomem *base, u32 enc_format, u32 width, > > + u32 height, u32 bytesperline) > > +{ > > + u32 img_stride; > > + u32 mem_stride; > > + > > + if (enc_format == V4L2_PIX_FMT_NV12M || > > + enc_format == V4L2_PIX_FMT_NV21M) { > > + img_stride = round_up(width, 16); > > + mem_stride = bytesperline; > > + } else { > > + img_stride = round_up(width * 2, 32); > > + mem_stride = img_stride; > > + } > > + > > + writel(img_stride, base + JPEG_ENC_IMG_STRIDE); > > + writel(mem_stride, base + JPEG_ENC_STRIDE); > > +} > > + > > My comments for this function from v7 haven't been addressed. done. > > > +void mtk_jpeg_enc_set_src_addr(void __iomem *base, u32 src_addr, > > + u32 plane_index) > > +{ > > + if (!plane_index) > > + writel(src_addr, base + JPEG_ENC_SRC_LUMA_ADDR); > > + else > > + writel(src_addr, base + JPEG_ENC_SRC_CHROMA_ADDR); > > Do we need this plane_index if we only have 2 planes? Also, for interleaved > formats, like YUYV, what should the LUMA and CHROMA registers be set to? If the format is YUYV, there is no need to set CHROMA register. Hardware can compute the CHROMA address from the LUMA address itself. > > > +} > > + > > +void mtk_jpeg_enc_set_dst_addr(void __iomem *base, u32 dst_addr, > > + u32 stall_size, u32 init_offset, > > + u32 offset_mask) > > +{ > > + writel(init_offset & ~0xf, base + JPEG_ENC_OFFSET_ADDR); > > + writel(offset_mask & 0xf, base + JPEG_ENC_BYTE_OFFSET_MASK); > > + writel(dst_addr & ~0xf, base + JPEG_ENC_DST_ADDR0); > > + writel((dst_addr + stall_size) & ~0xf, base + JPEG_ENC_STALL_ADDR0); > > +} > > + > > +static void mtk_jpeg_enc_set_quality(void __iomem *base, u32 quality) > > +{ > > + u32 value; > > + u32 i, enc_quality; > > + > > + enc_quality = mtk_jpeg_enc_quality[0].hardware_value; > > + for (i = 0; i < ARRAY_SIZE(mtk_jpeg_enc_quality); i++) { > > + if (quality <= mtk_jpeg_enc_quality[i].quality_param) { > > + enc_quality = mtk_jpeg_enc_quality[i].hardware_value; > > + break; > > + } > > + } > > + > > + value = readl(base + JPEG_ENC_QUALITY); > > nit: Is it still necessary to read the register here? Typically the reserved > bits would be defined as SBZ (should be zero) and it should be safe to just > write 0 to them. yes,removed it. > > > + value = (value & JPEG_ENC_QUALITY_MASK) | enc_quality; > > + writel(value, base + JPEG_ENC_QUALITY); > > +} > > + > > +static void mtk_jpeg_enc_set_ctrl(void __iomem *base, u32 enc_format, > > + bool exif_en, u32 restart_interval) > > +{ > > + u32 value; > > + > > + value = readl(base + JPEG_ENC_CTRL); > > nit: Is it still necessary to read the register here? I think it is necessary to read this register.Because that the default value of JPEG_ENC_CTRL's bit[2](enable interrupt) is 1. > > > + value &= ~JPEG_ENC_CTRL_YUV_FORMAT_MASK; > > + value |= (enc_format & 3) << 3; > > + if (exif_en) > > + value |= JPEG_ENC_CTRL_FILE_FORMAT_BIT; > > + else > > + value &= ~JPEG_ENC_CTRL_FILE_FORMAT_BIT; > > + if (restart_interval) > > + value |= JPEG_ENC_CTRL_RESTART_EN_BIT; > > + else > > + value &= ~JPEG_ENC_CTRL_RESTART_EN_BIT; > > + writel(value, base + JPEG_ENC_CTRL); > > +} > > + > > Best regards, > Tomasz Best Regards, Xia Jiang _______________________________________________ linux-arm-kernel mailing list linux-arm-kernel@lists.infradead.org http://lists.infradead.org/mailman/listinfo/linux-arm-kernel