From mboxrd@z Thu Jan 1 00:00:00 1970 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: base64 Subject: [RFC,v2,10/15] usb:cdns3: Ep0 operations part of the API From: Roger Quadros Message-Id: <5BFEA6D2.9010906@ti.com> Date: Wed, 28 Nov 2018 16:31:46 +0200 To: Pawel Laszczak , devicetree@vger.kernel.org Cc: gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, adouglas@cadence.com, jbergsagel@ti.com, nsekhar@ti.com, nm@ti.com, sureshp@cadence.com, peter.chen@nxp.com, pjez@cadence.com, kurahul@cadence.com List-ID: T24gMTgvMTEvMTggMTI6MDksIFBhd2VsIExhc3pjemFrIHdyb3RlOgo+IFBhdGNoIGltcGxlbWVu dHMgcmVsYXRlZCB0byBkZWZhdWx0IGVuZHBvaW50IGNhbGxiYWNrIGZ1bmN0aW9ucwo+IGRlZmlu ZWQgaW4gdXNiX2VwX29wcyBvYmplY3QKPiAKPiBTaWduZWQtb2ZmLWJ5OiBQYXdlbCBMYXN6Y3ph ayA8cGF3ZWxsQGNhZGVuY2UuY29tPgo+IC0tLQo+ICBkcml2ZXJzL3VzYi9jZG5zMy9lcDAuYyAg ICB8IDE5MSArKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKysrKystCj4gIGRyaXZlcnMv dXNiL2NkbnMzL2dhZGdldC5jIHwgICA4ICsrCj4gIGRyaXZlcnMvdXNiL2NkbnMzL2dhZGdldC5o IHwgIDEwICsrCj4gIDMgZmlsZXMgY2hhbmdlZCwgMjA3IGluc2VydGlvbnMoKyksIDIgZGVsZXRp b25zKC0pCj4gCj4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvdXNiL2NkbnMzL2VwMC5jIGIvZHJpdmVy cy91c2IvY2RuczMvZXAwLmMKPiBpbmRleCBjYTE3OTU0NjcxNTUuLmQwNTE2OWU3MzYzMSAxMDA2 NDQKPiAtLS0gYS9kcml2ZXJzL3VzYi9jZG5zMy9lcDAuYwo+ICsrKyBiL2RyaXZlcnMvdXNiL2Nk bnMzL2VwMC5jCj4gQEAgLTE4LDExICsxOCwxODUgQEAgc3RhdGljIHN0cnVjdCB1c2JfZW5kcG9p bnRfZGVzY3JpcHRvciBjZG5zM19nYWRnZXRfZXAwX2Rlc2MgPSB7Cj4gIAkuYm1BdHRyaWJ1dGVz ID0JVVNCX0VORFBPSU5UX1hGRVJfQ09OVFJPTCwKPiAgfTsKPiAgCj4gKy8qKgo+ICsgKiBjZG5z M19lcDBfcnVuX3RyYW5zZmVyIC0gRG8gdHJhbnNmZXIgb24gZGVmYXVsdCBlbmRwb2ludCBoYXJk d2FyZQo+ICsgKiBAcHJpdl9kZXY6IGV4dGVuZGVkIGdhZGdldCBvYmplY3QKPiArICogQGRtYV9h ZGRyOiBwaHlzaWNhbCBhZGRyZXNzIHdoZXJlIGRhdGEgaXMvd2lsbCBiZSBzdG9yZWQKPiArICog QGxlbmd0aDogZGF0YSBsZW5ndGgKPiArICogQGVyZHk6IHNldCBpdCB0byAxIHdoZW4gRVJEWSBw YWNrZXQgc2hvdWxkIGJlIHNlbnQgLQo+ICsgKiAgICAgICAgZXhpdCBmcm9tIGZsb3cgY29udHJv bCBzdGF0ZQo+ICsgKi8KPiArc3RhdGljIHZvaWQgY2RuczNfZXAwX3J1bl90cmFuc2ZlcihzdHJ1 Y3QgY2RuczNfZGV2aWNlICpwcml2X2RldiwKPiArCQkJCSAgIGRtYV9hZGRyX3QgZG1hX2FkZHIs Cj4gKwkJCQkgICB1bnNpZ25lZCBpbnQgbGVuZ3RoLCBpbnQgZXJkeSkKPiArewo+ICsJc3RydWN0 IGNkbnMzX3VzYl9yZWdzIF9faW9tZW0gKnJlZ3MgPSBwcml2X2Rldi0+cmVnczsKPiArCj4gKwlw cml2X2Rldi0+dHJiX2VwMC0+YnVmZmVyID0gVFJCX0JVRkZFUihkbWFfYWRkcik7Cj4gKwlwcml2 X2Rldi0+dHJiX2VwMC0+bGVuZ3RoID0gVFJCX0xFTihsZW5ndGgpOwo+ICsJcHJpdl9kZXYtPnRy Yl9lcDAtPmNvbnRyb2wgPSBUUkJfQ1lDTEUgfCBUUkJfSU9DIHwgVFJCX1RZUEUoVFJCX05PUk1B TCk7Cj4gKwo+ICsJY2RuczNfc2VsZWN0X2VwKHByaXZfZGV2LAo+ICsJCQlwcml2X2Rldi0+ZXAw X2RhdGFfZGlyID8gVVNCX0RJUl9JTiA6IFVTQl9ESVJfT1VUKTsKPiArCj4gKwl3cml0ZWwoRVBf U1RTX1RSQkVSUiwgJnJlZ3MtPmVwX3N0cyk7Cj4gKwl3cml0ZWwoRVBfVFJBRERSX1RSQUREUihw cml2X2Rldi0+dHJiX2VwMF9kbWEpLCAmcmVncy0+ZXBfdHJhZGRyKTsKPiArCj4gKwlkZXZfZGJn KCZwcml2X2Rldi0+ZGV2LCAiLy9EaW5nIERvbmcgZXAwJXNcbiIsCj4gKwkJcHJpdl9kZXYtPmVw MF9kYXRhX2RpciA/ICJJTiIgOiAiT1VUIik7Cj4gKwo+ICsJLyogVFJCIHNob3VsZCBiZSBwcmVw YXJlZCBiZWZvcmUgc3RhcnRpbmcgdHJhbnNmZXIgKi8KPiArCXdyaXRlbChFUF9DTURfRFJEWSwg JnJlZ3MtPmVwX2NtZCk7Cj4gKwo+ICsJaWYgKGVyZHkpCj4gKwkJd3JpdGVsKEVQX0NNRF9FUkRZ LCAmcHJpdl9kZXYtPnJlZ3MtPmVwX2NtZCk7Cj4gK30KPiArCj4gIHN0YXRpYyB2b2lkIGNkbnMz X3ByZXBhcmVfc2V0dXBfcGFja2V0KHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2KQo+ICB7 Cj4gIAkvL1RPRE86IEltcGxlbWVudHMgdGhpcyBmdW5jdGlvbgo+ICB9Cj4gIAo+ICtzdGF0aWMg dm9pZCBjZG5zM19zZXRfaHdfY29uZmlndXJhdGlvbihzdHJ1Y3QgY2RuczNfZGV2aWNlICpwcml2 X2RldikKCklzIHRoaXMgZ29pbmcgdG8gYmUgdXNlZCBvbmx5IGZvciBlcDA/CklmIHllcyB0aGVu IGxldCdzIGhhdmUgZXAwIGluIHRoZSBuYW1lLgpJZiBub3QgdGhlbiB0aGlzIGZ1bmN0aW9uIHNo b3VsZCBiZSBpbiBnYWRnZXQuYwoKPiArewo+ICsJc3RydWN0IGNkbnMzX2VuZHBvaW50ICpwcml2 X2VwOwo+ICsJc3RydWN0IHVzYl9yZXF1ZXN0ICpyZXF1ZXN0Owo+ICsJc3RydWN0IHVzYl9lcCAq ZXA7Cj4gKwlpbnQgcmVzdWx0ID0gMDsKPiArCj4gKwlpZiAocHJpdl9kZXYtPmh3X2NvbmZpZ3Vy ZWRfZmxhZykKPiArCQlyZXR1cm47Cj4gKwo+ICsJd3JpdGVsKFVTQl9DT05GX0NGR1NFVCwgJnBy aXZfZGV2LT5yZWdzLT51c2JfY29uZik7Cj4gKwl3cml0ZWwoRVBfQ01EX0VSRFkgfCBFUF9DTURf UkVRX0NNUEwsICZwcml2X2Rldi0+cmVncy0+ZXBfY21kKTsKPiArCj4gKwljZG5zM19zZXRfcmVn aXN0ZXJfYml0KCZwcml2X2Rldi0+cmVncy0+dXNiX2NvbmYsCj4gKwkJCSAgICAgICBVU0JfQ09O Rl9VMUVOIHwgVVNCX0NPTkZfVTJFTik7CgpTaG91bGRuJ3QgVTEvVTIgYmUgZW5hYmxlZCBvbmx5 IGlmIHRoZSBVU0JfREVWSUNFX1UxX0VOQUJMRS9VU0JfREVWSUNFX1UyX0VOQUJMRQpkZXZpY2Ug cmVxdWVzdCB3YXMgcmVjZWl2ZWQ/Cgo+ICsKPiArCS8qIHdhaXQgdW50aWwgY29uZmlndXJhdGlv biBzZXQgKi8KPiArCXJlc3VsdCA9IGNkbnMzX2hhbmRzaGFrZSgmcHJpdl9kZXYtPnJlZ3MtPnVz Yl9zdHMsCj4gKwkJCQkgVVNCX1NUU19DRkdTVFNfTUFTSywgMSwgMTAwKTsKPiArCj4gKwlwcml2 X2Rldi0+aHdfY29uZmlndXJlZF9mbGFnID0gMTsKPiArCWNkbnMzX2VuYWJsZV9sMShwcml2X2Rl diwgMSk7Cj4gKwo+ICsJbGlzdF9mb3JfZWFjaF9lbnRyeShlcCwgJnByaXZfZGV2LT5nYWRnZXQu ZXBfbGlzdCwgZXBfbGlzdCkgewo+ICsJCWlmIChlcC0+ZW5hYmxlZCkgewo+ICsJCQlwcml2X2Vw ID0gZXBfdG9fY2RuczNfZXAoZXApOwo+ICsJCQlyZXF1ZXN0ID0gY2RuczNfbmV4dF9yZXF1ZXN0 KCZwcml2X2VwLT5yZXF1ZXN0X2xpc3QpOwo+ICsJCQlpZiAocmVxdWVzdCkKPiArCQkJCWNkbnMz X2VwX3J1bl90cmFuc2Zlcihwcml2X2VwLCByZXF1ZXN0KTsKCndoeSBhcmUgeW91IHN0YXJ0aW5n IHRyYW5zZmVycyBpbiBhIGZ1bmN0aW9uIHRoYXQgaXMgc3VwcG9zZWQgdG8gc2V0IGh3IGNvbmZp Z3VyYXRpb24gb25seS4KCj4gKwkJfQo+ICsJfQo+ICt9Cj4gKwo+ICsvKioKPiArICogY2RuczNf Z2FkZ2V0X2VwMF9lbmFibGUKPiArICogRnVuY3Rpb24gc2hvdWxkbid0IGJlIGNhbGxlZCBieSBn YWRnZXQgZHJpdmVyLAo+ICsgKiBlbmRwb2ludCAwIGlzIGFsbHdheXMgYWN0aXZlCj4gKyAqLwo+ ICtzdGF0aWMgaW50IGNkbnMzX2dhZGdldF9lcDBfZW5hYmxlKHN0cnVjdCB1c2JfZXAgKmVwLAo+ ICsJCQkJICAgY29uc3Qgc3RydWN0IHVzYl9lbmRwb2ludF9kZXNjcmlwdG9yICpkZXNjKQo+ICt7 Cj4gKwlyZXR1cm4gLUVJTlZBTDsKPiArfQo+ICsKPiArLyoqCj4gKyAqIGNkbnMzX2dhZGdldF9l cDBfZGlzYWJsZQo+ICsgKiBGdW5jdGlvbiBzaG91bGRuJ3QgYmUgY2FsbGVkIGJ5IGdhZGdldCBk cml2ZXIsCj4gKyAqIGVuZHBvaW50IDAgaXMgYWxsd2F5cyBhY3RpdmUKPiArICovCj4gK3N0YXRp YyBpbnQgY2RuczNfZ2FkZ2V0X2VwMF9kaXNhYmxlKHN0cnVjdCB1c2JfZXAgKmVwKQo+ICt7Cj4g KwlyZXR1cm4gLUVJTlZBTDsKPiArfQo+ICsKPiArLyoqCj4gKyAqIGNkbnMzX2dhZGdldF9lcDBf c2V0X2hhbHQKPiArICogQGVwOiBwb2ludGVyIHRvIGVuZHBvaW50IHplcm8gb2JqZWN0Cj4gKyAq IEB2YWx1ZTogMSBmb3Igc2V0IHN0YWxsLCAwIGZvciBjbGVhciBzdGFsbAo+ICsgKgo+ICsgKiBS ZXR1cm5zIDAKPiArICovCj4gK3N0YXRpYyBpbnQgY2RuczNfZ2FkZ2V0X2VwMF9zZXRfaGFsdChz dHJ1Y3QgdXNiX2VwICplcCwgaW50IHZhbHVlKQo+ICt7Cj4gKwkvKiBUT0RPICovCj4gKwlyZXR1 cm4gMDsKPiArfQo+ICsKPiArLyoqCj4gKyAqIGNkbnMzX2dhZGdldF9lcDBfcXVldWUgVHJhbnNm ZXIgZGF0YSBvbiBlbmRwb2ludCB6ZXJvCj4gKyAqIEBlcDogcG9pbnRlciB0byBlbmRwb2ludCB6 ZXJvIG9iamVjdAo+ICsgKiBAcmVxdWVzdDogcG9pbnRlciB0byByZXF1ZXN0IG9iamVjdAo+ICsg KiBAZ2ZwX2ZsYWdzOiBnZnAgZmxhZ3MKPiArICoKPiArICogUmV0dXJucyAwIG9uIHN1Y2Nlc3Ms IGVycm9yIGNvZGUgZWxzZXdoZXJlCj4gKyAqLwo+ICtzdGF0aWMgaW50IGNkbnMzX2dhZGdldF9l cDBfcXVldWUoc3RydWN0IHVzYl9lcCAqZXAsCj4gKwkJCQkgIHN0cnVjdCB1c2JfcmVxdWVzdCAq cmVxdWVzdCwKPiArCQkJCSAgZ2ZwX3QgZ2ZwX2ZsYWdzKQo+ICt7Cj4gKwlzdHJ1Y3QgY2RuczNf ZW5kcG9pbnQgKnByaXZfZXAgPSBlcF90b19jZG5zM19lcChlcCk7Cj4gKwlzdHJ1Y3QgY2RuczNf ZGV2aWNlICpwcml2X2RldiA9IHByaXZfZXAtPmNkbnMzX2RldjsKPiArCXVuc2lnbmVkIGxvbmcg ZmxhZ3M7Cj4gKwlpbnQgZXJkeV9zZW50ID0gMDsKPiArCWludCByZXQgPSAwOwo+ICsKPiArCWRl dl9kYmcoJnByaXZfZGV2LT5kZXYsICJRdWV1ZSB0byBFcDAlcyBMOiAlZFxuIiwKPiArCQlwcml2 X2Rldi0+ZXAwX2RhdGFfZGlyID8gIklOIiA6ICJPVVQiLAo+ICsJCXJlcXVlc3QtPmxlbmd0aCk7 Cj4gKwo+ICsJLyogc2VuZCBTVEFUVVMgc3RhZ2UgKi8KPiArCWlmIChyZXF1ZXN0LT5sZW5ndGgg PT0gMCAmJiByZXF1ZXN0LT56ZXJvID09IDApIHsKCklzIHRoaXMgY2hlY2sgc3VmZmljaWVudCB0 byBrbm93IFNUQVRVUyBzdGFnZT8KSXQgbWlnaHQgYmUgbm9ybWFsIGZvciB2ZW5kb3Igc3BlY2lm aWMgY29udHJvbCByZXF1ZXN0IHRvIGhhdmUKcmVxdWVzdC0+bGVuZ3RoID0gMCBhbmQgcmVxdWVz dC0+emVybyA9IDAuCgoKPiArCQlzcGluX2xvY2tfaXJxc2F2ZSgmcHJpdl9kZXYtPmxvY2ssIGZs YWdzKTsKPiArCQljZG5zM19zZWxlY3RfZXAocHJpdl9kZXYsIDB4MDApOwo+ICsKPiArCQllcmR5 X3NlbnQgPSAhcHJpdl9kZXYtPmh3X2NvbmZpZ3VyZWRfZmxhZzsKPiArCQljZG5zM19zZXRfaHdf Y29uZmlndXJhdGlvbihwcml2X2Rldik7CgpXaGF0IGlmIHdlJ3JlIHN0aWxsIGJ1c3kgd2l0aCBE QVRBIHN0YWdlIG9mIHByZXZpb3VzIGVwMF9xdWV1ZT8KCmlmICghbGlzdF9lbXB0eSgmcHJpdl9l cC0+cmVxdWVzdF9saXN0KSkgc2hvdWxkIGJlIGRvbmUgYXMgdGhlIGZpcnN0IHRoaW5nIGluIHRo aXMgZnVuY3Rpb24uCgo+ICsKPiArCQlpZiAoIWVyZHlfc2VudCkKPiArCQkJd3JpdGVsKEVQX0NN RF9FUkRZIHwgRVBfQ01EX1JFUV9DTVBMLAo+ICsJCQkgICAgICAgJnByaXZfZGV2LT5yZWdzLT5l cF9jbWQpOwo+ICsKPiArCQljZG5zM19wcmVwYXJlX3NldHVwX3BhY2tldChwcml2X2Rldik7Cj4g KwkJcmVxdWVzdC0+YWN0dWFsID0gMDsKPiArCQlwcml2X2Rldi0+c3RhdHVzX2NvbXBsZXRpb25f bm9fY2FsbCA9IHRydWU7Cj4gKwkJcHJpdl9kZXYtPnBlbmRpbmdfc3RhdHVzX3JlcXVlc3QgPSBy ZXF1ZXN0Owo+ICsJCXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnByaXZfZGV2LT5sb2NrLCBmbGFn cyk7Cj4gKwo+ICsJCS8qCj4gKwkJICogU2luY2UgdGhlcmUgaXMgbm8gY29tcGxldGlvbiBpbnRl cnJ1cHQgZm9yIHN0YXR1cyBzdGFnZSwKPiArCQkgKiBpdCBuZWVkcyB0byBjYWxsIC0+Y29tcGxl dGlvbiBpbiBzb2Z0d2FyZSBhZnRlcgo+ICsJCSAqIGVwMF9xdWV1ZSBpcyBiYWNrLgo+ICsJCSAq Lwo+ICsJCXF1ZXVlX3dvcmsoc3lzdGVtX2ZyZWV6YWJsZV93cSwgJnByaXZfZGV2LT5wZW5kaW5n X3N0YXR1c193cSk7Cj4gKwkJcmV0dXJuIDA7Cj4gKwl9Cj4gKwo+ICsJc3Bpbl9sb2NrX2lycXNh dmUoJnByaXZfZGV2LT5sb2NrLCBmbGFncyk7Cj4gKwlpZiAoIWxpc3RfZW1wdHkoJnByaXZfZXAt PnJlcXVlc3RfbGlzdCkpIHsKPiArCQlkZXZfZXJyKCZwcml2X2Rldi0+ZGV2LAo+ICsJCQkiY2Fu J3QgaGFuZGxlIG11bHRpcGxlIHJlcXVlc3RzIGZvciBlcDBcbiIpOwo+ICsJCXNwaW5fdW5sb2Nr X2lycXJlc3RvcmUoJnByaXZfZGV2LT5sb2NrLCBmbGFncyk7Cj4gKwkJcmV0dXJuIC1FT1BOT1RT VVBQOwoKLUVCVVNZPwoKPiArCX0KPiArCj4gKwlyZXQgPSB1c2JfZ2FkZ2V0X21hcF9yZXF1ZXN0 X2J5X2Rldihwcml2X2Rldi0+c3lzZGV2LCByZXF1ZXN0LAo+ICsJCQkJCSAgICBwcml2X2Rldi0+ ZXAwX2RhdGFfZGlyKTsKPiArCWlmIChyZXQpIHsKPiArCQlzcGluX3VubG9ja19pcnFyZXN0b3Jl KCZwcml2X2Rldi0+bG9jaywgZmxhZ3MpOwo+ICsJCWRldl9lcnIoJnByaXZfZGV2LT5kZXYsICJm YWlsZWQgdG8gbWFwIHJlcXVlc3RcbiIpOwo+ICsJCXJldHVybiAtRUlOVkFMOwo+ICsJfQo+ICsK PiArCXByaXZfZGV2LT5lcDBfcmVxdWVzdCA9IHJlcXVlc3Q7Cj4gKwlsaXN0X2FkZF90YWlsKCZy ZXF1ZXN0LT5saXN0LCAmcHJpdl9lcC0+cmVxdWVzdF9saXN0KTsKPiArCWNkbnMzX2VwMF9ydW5f dHJhbnNmZXIocHJpdl9kZXYsIHJlcXVlc3QtPmRtYSwgcmVxdWVzdC0+bGVuZ3RoLCAxKTsKPiAr CXNwaW5fdW5sb2NrX2lycXJlc3RvcmUoJnByaXZfZGV2LT5sb2NrLCBmbGFncyk7Cj4gKwo+ICsJ cmV0dXJuIHJldDsKPiArfQo+ICsKPiAgLyoqCj4gICAqIGNkbnMzX2dhZGdldF9lcF9zZXRfd2Vk Z2UgU2V0IHdlZGdlIG9uIHNlbGVjdGVkIGVuZHBvaW50Cj4gICAqIEBlcDogZW5kcG9pbnQgb2Jq ZWN0Cj4gQEAgLTQxLDYgKzIxNSwxNyBAQCBpbnQgY2RuczNfZ2FkZ2V0X2VwX3NldF93ZWRnZShz dHJ1Y3QgdXNiX2VwICplcCkKPiAgCXJldHVybiAwOwo+ICB9Cj4gIAo+ICtjb25zdCBzdHJ1Y3Qg dXNiX2VwX29wcyBjZG5zM19nYWRnZXRfZXAwX29wcyA9IHsKPiArCS5lbmFibGUgPSBjZG5zM19n YWRnZXRfZXAwX2VuYWJsZSwKPiArCS5kaXNhYmxlID0gY2RuczNfZ2FkZ2V0X2VwMF9kaXNhYmxl LAo+ICsJLmFsbG9jX3JlcXVlc3QgPSBjZG5zM19nYWRnZXRfZXBfYWxsb2NfcmVxdWVzdCwKPiAr CS5mcmVlX3JlcXVlc3QgPSBjZG5zM19nYWRnZXRfZXBfZnJlZV9yZXF1ZXN0LAo+ICsJLnF1ZXVl ID0gY2RuczNfZ2FkZ2V0X2VwMF9xdWV1ZSwKPiArCS5kZXF1ZXVlID0gY2RuczNfZ2FkZ2V0X2Vw X2RlcXVldWUsCj4gKwkuc2V0X2hhbHQgPSBjZG5zM19nYWRnZXRfZXAwX3NldF9oYWx0LAo+ICsJ LnNldF93ZWRnZSA9IGNkbnMzX2dhZGdldF9lcF9zZXRfd2VkZ2UsCj4gK307Cj4gKwo+ICAvKioK PiAgICogY2RuczNfZXAwX2NvbmZpZyAtIENvbmZpZ3VyZXMgZGVmYXVsdCBlbmRwb2ludAo+ICAg KiBAcHJpdl9kZXY6IGV4dGVuZGVkIGdhZGdldCBvYmplY3QKPiBAQCAtNjIsNiArMjQ3LDkgQEAg dm9pZCBjZG5zM19lcDBfY29uZmlnKHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2KQo+ICAJ CXByaXZfZGV2LT5lcDBfcmVxdWVzdCA9IE5VTEw7Cj4gIAl9Cj4gIAo+ICsJcHJpdl9kZXYtPnUx X2FsbG93ZWQgPSAwOwo+ICsJcHJpdl9kZXYtPnUyX2FsbG93ZWQgPSAwOwo+ICsKCndoZXJlIGRv IHlvdSBzZXQgdGhlc2U/Cgo+ICAJcHJpdl9kZXYtPmdhZGdldC5lcDAtPm1heHBhY2tldCA9IG1h eF9wYWNrZXRfc2l6ZTsKPiAgCWNkbnMzX2dhZGdldF9lcDBfZGVzYy53TWF4UGFja2V0U2l6ZSA9 IGNwdV90b19sZTE2KG1heF9wYWNrZXRfc2l6ZSk7Cj4gIAo+IEBAIC0xMDYsOCArMjk0LDcgQEAg aW50IGNkbnMzX2luaXRfZXAwKHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2KQo+ICAJc3By aW50ZihlcDAtPm5hbWUsICJlcDAiKTsKPiAgCj4gIAkvKiBmaWxsIGxpbnV4IGZpZWxkcyAqLwo+ IC0JLy9UT0RPOiBpbXBsZW1lbnRzIGNkbnMzX2dhZGdldF9lcDBfb3BzIG9iamVjdAo+IC0JLy9l cDAtPmVuZHBvaW50Lm9wcyA9ICZjZG5zM19nYWRnZXRfZXAwX29wczsKPiArCWVwMC0+ZW5kcG9p bnQub3BzID0gJmNkbnMzX2dhZGdldF9lcDBfb3BzOwo+ICAJZXAwLT5lbmRwb2ludC5tYXhidXJz dCA9IDE7Cj4gIAl1c2JfZXBfc2V0X21heHBhY2tldF9saW1pdCgmZXAwLT5lbmRwb2ludCwgRU5E UE9JTlQwX01BWF9QQUNLRVRfTElNSVQpOwo+ICAJZXAwLT5lbmRwb2ludC5hZGRyZXNzID0gMDsK PiBkaWZmIC0tZ2l0IGEvZHJpdmVycy91c2IvY2RuczMvZ2FkZ2V0LmMgYi9kcml2ZXJzL3VzYi9j ZG5zMy9nYWRnZXQuYwo+IGluZGV4IDFmMmE0MzQ0ODZkYy4uYzk2NWRhMTZjMGM4IDEwMDY0NAo+ IC0tLSBhL2RyaXZlcnMvdXNiL2NkbnMzL2dhZGdldC5jCj4gKysrIGIvZHJpdmVycy91c2IvY2Ru czMvZ2FkZ2V0LmMKPiBAQCAtMTg4LDYgKzE4OCwxNCBAQCBzdGF0aWMgdm9pZCBjZG5zM19lcF9z dGFsbF9mbHVzaChzdHJ1Y3QgY2RuczNfZW5kcG9pbnQgKnByaXZfZXApCj4gIAlwcml2X2VwLT5m bGFncyB8PSBFUF9TVEFMTDsKPiAgfQo+ICAKCj4gK3ZvaWQgY2RuczNfZW5hYmxlX2wxKHN0cnVj dCBjZG5zM19kZXZpY2UgKnByaXZfZGV2LCBpbnQgZW5hYmxlKQoKU29tZSBjb21tZW50IG1pZ2h0 IGhlbHAgYXMgdG8gd2hhdCBMMSBpcy4KCj4gK3sKPiArCWlmIChlbmFibGUpCj4gKwkJd3JpdGVs KFVTQl9DT05GX0wxRU4sICZwcml2X2Rldi0+cmVncy0+dXNiX2NvbmYpOwo+ICsJZWxzZQo+ICsJ CXdyaXRlbChVU0JfQ09ORl9MMURTLCAmcHJpdl9kZXYtPnJlZ3MtPnVzYl9jb25mKTsKPiArfQo+ ICsKPiAgLyoqCj4gICAqIGNkbnMzX2dhZGdldF9naXZlYmFjayAtIGNhbGwgc3RydWN0IHVzYl9y ZXF1ZXN0J3MgLT5jb21wbGV0ZSBjYWxsYmFjawo+ICAgKiBAcHJpdl9lcDogVGhlIGVuZHBvaW50 IHRvIHdob20gdGhlIHJlcXVlc3QgYmVsb25ncyB0bwo+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3Vz Yi9jZG5zMy9nYWRnZXQuaCBiL2RyaXZlcnMvdXNiL2NkbnMzL2dhZGdldC5oCj4gaW5kZXggYTRi ZTI4OGIzNGNiLi4yMjRmNmI4MzBiYzkgMTAwNjQ0Cj4gLS0tIGEvZHJpdmVycy91c2IvY2RuczMv Z2FkZ2V0LmgKPiArKysgYi9kcml2ZXJzL3VzYi9jZG5zMy9nYWRnZXQuaAo+IEBAIC0xMDY4LDEx ICsxMDY4LDIxIEBAIHN0cnVjdCBjZG5zM19kZXZpY2Ugewo+ICAJc3RydWN0IHVzYl9yZXF1ZXN0 CQkqcGVuZGluZ19zdGF0dXNfcmVxdWVzdDsKPiAgfTsKPiAgCj4gK2ludCBjZG5zM19oYW5kc2hh a2Uodm9pZCBfX2lvbWVtICpwdHIsIHUzMiBtYXNrLCB1MzIgZG9uZSwgaW50IHVzZWMpOwo+ICB2 b2lkIGNkbnMzX3NldF9yZWdpc3Rlcl9iaXQodm9pZCBfX2lvbWVtICpwdHIsIHUzMiBtYXNrKTsK PiAgaW50IGNkbnMzX2luaXRfZXAwKHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2KTsKPiAg dm9pZCBjZG5zM19lcDBfY29uZmlnKHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2KTsKPiAg dm9pZCBjZG5zM19zZWxlY3RfZXAoc3RydWN0IGNkbnMzX2RldmljZSAqcHJpdl9kZXYsIHUzMiBl cCk7Cj4gK3ZvaWQgY2RuczNfZW5hYmxlX2wxKHN0cnVjdCBjZG5zM19kZXZpY2UgKnByaXZfZGV2 LCBpbnQgZW5hYmxlKTsKPiArc3RydWN0IHVzYl9yZXF1ZXN0ICpjZG5zM19uZXh0X3JlcXVlc3Qo c3RydWN0IGxpc3RfaGVhZCAqbGlzdCk7Cj4gK2ludCBjZG5zM19lcF9ydW5fdHJhbnNmZXIoc3Ry dWN0IGNkbnMzX2VuZHBvaW50ICpwcml2X2VwLAo+ICsJCQkgIHN0cnVjdCB1c2JfcmVxdWVzdCAq cmVxdWVzdCk7Cj4gIGludCBjZG5zM19nYWRnZXRfZXBfc2V0X3dlZGdlKHN0cnVjdCB1c2JfZXAg KmVwKTsKPiAgaW50IGNkbnMzX2dhZGdldF9lcF9zZXRfaGFsdChzdHJ1Y3QgdXNiX2VwICplcCwg aW50IHZhbHVlKTsKPiArc3RydWN0IHVzYl9yZXF1ZXN0ICpjZG5zM19nYWRnZXRfZXBfYWxsb2Nf cmVxdWVzdChzdHJ1Y3QgdXNiX2VwICplcCwKPiArCQkJCQkJICBnZnBfdCBnZnBfZmxhZ3MpOwo+ ICt2b2lkIGNkbnMzX2dhZGdldF9lcF9mcmVlX3JlcXVlc3Qoc3RydWN0IHVzYl9lcCAqZXAsCj4g KwkJCQkgIHN0cnVjdCB1c2JfcmVxdWVzdCAqcmVxdWVzdCk7Cj4gK2ludCBjZG5zM19nYWRnZXRf ZXBfZGVxdWV1ZShzdHJ1Y3QgdXNiX2VwICplcCwgc3RydWN0IHVzYl9yZXF1ZXN0ICpyZXF1ZXN0 KTsKPiAgCj4gICNlbmRpZiAvKiBfX0xJTlVYX0NETlMzX0dBREdFVCAqLwo+IAoKY2hlZXJzLAot cm9nZXIK From mboxrd@z Thu Jan 1 00:00:00 1970 From: Roger Quadros Subject: Re: [RFC PATCH v2 10/15] usb:cdns3: Ep0 operations part of the API Date: Wed, 28 Nov 2018 16:31:46 +0200 Message-ID: <5BFEA6D2.9010906@ti.com> References: <1542535751-16079-1-git-send-email-pawell@cadence.com> <1542535751-16079-11-git-send-email-pawell@cadence.com> Mime-Version: 1.0 Content-Type: text/plain; charset="windows-1252" Content-Transfer-Encoding: 7bit Return-path: In-Reply-To: <1542535751-16079-11-git-send-email-pawell@cadence.com> Sender: linux-kernel-owner@vger.kernel.org To: Pawel Laszczak , devicetree@vger.kernel.org Cc: gregkh@linuxfoundation.org, linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org, adouglas@cadence.com, jbergsagel@ti.com, nsekhar@ti.com, nm@ti.com, sureshp@cadence.com, peter.chen@nxp.com, pjez@cadence.com, kurahul@cadence.com List-Id: devicetree@vger.kernel.org On 18/11/18 12:09, Pawel Laszczak wrote: > Patch implements related to default endpoint callback functions > defined in usb_ep_ops object > > Signed-off-by: Pawel Laszczak > --- > drivers/usb/cdns3/ep0.c | 191 ++++++++++++++++++++++++++++++++++++- > drivers/usb/cdns3/gadget.c | 8 ++ > drivers/usb/cdns3/gadget.h | 10 ++ > 3 files changed, 207 insertions(+), 2 deletions(-) > > diff --git a/drivers/usb/cdns3/ep0.c b/drivers/usb/cdns3/ep0.c > index ca1795467155..d05169e73631 100644 > --- a/drivers/usb/cdns3/ep0.c > +++ b/drivers/usb/cdns3/ep0.c > @@ -18,11 +18,185 @@ static struct usb_endpoint_descriptor cdns3_gadget_ep0_desc = { > .bmAttributes = USB_ENDPOINT_XFER_CONTROL, > }; > > +/** > + * cdns3_ep0_run_transfer - Do transfer on default endpoint hardware > + * @priv_dev: extended gadget object > + * @dma_addr: physical address where data is/will be stored > + * @length: data length > + * @erdy: set it to 1 when ERDY packet should be sent - > + * exit from flow control state > + */ > +static void cdns3_ep0_run_transfer(struct cdns3_device *priv_dev, > + dma_addr_t dma_addr, > + unsigned int length, int erdy) > +{ > + struct cdns3_usb_regs __iomem *regs = priv_dev->regs; > + > + priv_dev->trb_ep0->buffer = TRB_BUFFER(dma_addr); > + priv_dev->trb_ep0->length = TRB_LEN(length); > + priv_dev->trb_ep0->control = TRB_CYCLE | TRB_IOC | TRB_TYPE(TRB_NORMAL); > + > + cdns3_select_ep(priv_dev, > + priv_dev->ep0_data_dir ? USB_DIR_IN : USB_DIR_OUT); > + > + writel(EP_STS_TRBERR, ®s->ep_sts); > + writel(EP_TRADDR_TRADDR(priv_dev->trb_ep0_dma), ®s->ep_traddr); > + > + dev_dbg(&priv_dev->dev, "//Ding Dong ep0%s\n", > + priv_dev->ep0_data_dir ? "IN" : "OUT"); > + > + /* TRB should be prepared before starting transfer */ > + writel(EP_CMD_DRDY, ®s->ep_cmd); > + > + if (erdy) > + writel(EP_CMD_ERDY, &priv_dev->regs->ep_cmd); > +} > + > static void cdns3_prepare_setup_packet(struct cdns3_device *priv_dev) > { > //TODO: Implements this function > } > > +static void cdns3_set_hw_configuration(struct cdns3_device *priv_dev) Is this going to be used only for ep0? If yes then let's have ep0 in the name. If not then this function should be in gadget.c > +{ > + struct cdns3_endpoint *priv_ep; > + struct usb_request *request; > + struct usb_ep *ep; > + int result = 0; > + > + if (priv_dev->hw_configured_flag) > + return; > + > + writel(USB_CONF_CFGSET, &priv_dev->regs->usb_conf); > + writel(EP_CMD_ERDY | EP_CMD_REQ_CMPL, &priv_dev->regs->ep_cmd); > + > + cdns3_set_register_bit(&priv_dev->regs->usb_conf, > + USB_CONF_U1EN | USB_CONF_U2EN); Shouldn't U1/U2 be enabled only if the USB_DEVICE_U1_ENABLE/USB_DEVICE_U2_ENABLE device request was received? > + > + /* wait until configuration set */ > + result = cdns3_handshake(&priv_dev->regs->usb_sts, > + USB_STS_CFGSTS_MASK, 1, 100); > + > + priv_dev->hw_configured_flag = 1; > + cdns3_enable_l1(priv_dev, 1); > + > + list_for_each_entry(ep, &priv_dev->gadget.ep_list, ep_list) { > + if (ep->enabled) { > + priv_ep = ep_to_cdns3_ep(ep); > + request = cdns3_next_request(&priv_ep->request_list); > + if (request) > + cdns3_ep_run_transfer(priv_ep, request); why are you starting transfers in a function that is supposed to set hw configuration only. > + } > + } > +} > + > +/** > + * cdns3_gadget_ep0_enable > + * Function shouldn't be called by gadget driver, > + * endpoint 0 is allways active > + */ > +static int cdns3_gadget_ep0_enable(struct usb_ep *ep, > + const struct usb_endpoint_descriptor *desc) > +{ > + return -EINVAL; > +} > + > +/** > + * cdns3_gadget_ep0_disable > + * Function shouldn't be called by gadget driver, > + * endpoint 0 is allways active > + */ > +static int cdns3_gadget_ep0_disable(struct usb_ep *ep) > +{ > + return -EINVAL; > +} > + > +/** > + * cdns3_gadget_ep0_set_halt > + * @ep: pointer to endpoint zero object > + * @value: 1 for set stall, 0 for clear stall > + * > + * Returns 0 > + */ > +static int cdns3_gadget_ep0_set_halt(struct usb_ep *ep, int value) > +{ > + /* TODO */ > + return 0; > +} > + > +/** > + * cdns3_gadget_ep0_queue Transfer data on endpoint zero > + * @ep: pointer to endpoint zero object > + * @request: pointer to request object > + * @gfp_flags: gfp flags > + * > + * Returns 0 on success, error code elsewhere > + */ > +static int cdns3_gadget_ep0_queue(struct usb_ep *ep, > + struct usb_request *request, > + gfp_t gfp_flags) > +{ > + struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + unsigned long flags; > + int erdy_sent = 0; > + int ret = 0; > + > + dev_dbg(&priv_dev->dev, "Queue to Ep0%s L: %d\n", > + priv_dev->ep0_data_dir ? "IN" : "OUT", > + request->length); > + > + /* send STATUS stage */ > + if (request->length == 0 && request->zero == 0) { Is this check sufficient to know STATUS stage? It might be normal for vendor specific control request to have request->length = 0 and request->zero = 0. > + spin_lock_irqsave(&priv_dev->lock, flags); > + cdns3_select_ep(priv_dev, 0x00); > + > + erdy_sent = !priv_dev->hw_configured_flag; > + cdns3_set_hw_configuration(priv_dev); What if we're still busy with DATA stage of previous ep0_queue? if (!list_empty(&priv_ep->request_list)) should be done as the first thing in this function. > + > + if (!erdy_sent) > + writel(EP_CMD_ERDY | EP_CMD_REQ_CMPL, > + &priv_dev->regs->ep_cmd); > + > + cdns3_prepare_setup_packet(priv_dev); > + request->actual = 0; > + priv_dev->status_completion_no_call = true; > + priv_dev->pending_status_request = request; > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + > + /* > + * Since there is no completion interrupt for status stage, > + * it needs to call ->completion in software after > + * ep0_queue is back. > + */ > + queue_work(system_freezable_wq, &priv_dev->pending_status_wq); > + return 0; > + } > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + if (!list_empty(&priv_ep->request_list)) { > + dev_err(&priv_dev->dev, > + "can't handle multiple requests for ep0\n"); > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return -EOPNOTSUPP; -EBUSY? > + } > + > + ret = usb_gadget_map_request_by_dev(priv_dev->sysdev, request, > + priv_dev->ep0_data_dir); > + if (ret) { > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + dev_err(&priv_dev->dev, "failed to map request\n"); > + return -EINVAL; > + } > + > + priv_dev->ep0_request = request; > + list_add_tail(&request->list, &priv_ep->request_list); > + cdns3_ep0_run_transfer(priv_dev, request->dma, request->length, 1); > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + > + return ret; > +} > + > /** > * cdns3_gadget_ep_set_wedge Set wedge on selected endpoint > * @ep: endpoint object > @@ -41,6 +215,17 @@ int cdns3_gadget_ep_set_wedge(struct usb_ep *ep) > return 0; > } > > +const struct usb_ep_ops cdns3_gadget_ep0_ops = { > + .enable = cdns3_gadget_ep0_enable, > + .disable = cdns3_gadget_ep0_disable, > + .alloc_request = cdns3_gadget_ep_alloc_request, > + .free_request = cdns3_gadget_ep_free_request, > + .queue = cdns3_gadget_ep0_queue, > + .dequeue = cdns3_gadget_ep_dequeue, > + .set_halt = cdns3_gadget_ep0_set_halt, > + .set_wedge = cdns3_gadget_ep_set_wedge, > +}; > + > /** > * cdns3_ep0_config - Configures default endpoint > * @priv_dev: extended gadget object > @@ -62,6 +247,9 @@ void cdns3_ep0_config(struct cdns3_device *priv_dev) > priv_dev->ep0_request = NULL; > } > > + priv_dev->u1_allowed = 0; > + priv_dev->u2_allowed = 0; > + where do you set these? > priv_dev->gadget.ep0->maxpacket = max_packet_size; > cdns3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(max_packet_size); > > @@ -106,8 +294,7 @@ int cdns3_init_ep0(struct cdns3_device *priv_dev) > sprintf(ep0->name, "ep0"); > > /* fill linux fields */ > - //TODO: implements cdns3_gadget_ep0_ops object > - //ep0->endpoint.ops = &cdns3_gadget_ep0_ops; > + ep0->endpoint.ops = &cdns3_gadget_ep0_ops; > ep0->endpoint.maxburst = 1; > usb_ep_set_maxpacket_limit(&ep0->endpoint, ENDPOINT0_MAX_PACKET_LIMIT); > ep0->endpoint.address = 0; > diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c > index 1f2a434486dc..c965da16c0c8 100644 > --- a/drivers/usb/cdns3/gadget.c > +++ b/drivers/usb/cdns3/gadget.c > @@ -188,6 +188,14 @@ static void cdns3_ep_stall_flush(struct cdns3_endpoint *priv_ep) > priv_ep->flags |= EP_STALL; > } > > +void cdns3_enable_l1(struct cdns3_device *priv_dev, int enable) Some comment might help as to what L1 is. > +{ > + if (enable) > + writel(USB_CONF_L1EN, &priv_dev->regs->usb_conf); > + else > + writel(USB_CONF_L1DS, &priv_dev->regs->usb_conf); > +} > + > /** > * cdns3_gadget_giveback - call struct usb_request's ->complete callback > * @priv_ep: The endpoint to whom the request belongs to > diff --git a/drivers/usb/cdns3/gadget.h b/drivers/usb/cdns3/gadget.h > index a4be288b34cb..224f6b830bc9 100644 > --- a/drivers/usb/cdns3/gadget.h > +++ b/drivers/usb/cdns3/gadget.h > @@ -1068,11 +1068,21 @@ struct cdns3_device { > struct usb_request *pending_status_request; > }; > > +int cdns3_handshake(void __iomem *ptr, u32 mask, u32 done, int usec); > void cdns3_set_register_bit(void __iomem *ptr, u32 mask); > int cdns3_init_ep0(struct cdns3_device *priv_dev); > void cdns3_ep0_config(struct cdns3_device *priv_dev); > void cdns3_select_ep(struct cdns3_device *priv_dev, u32 ep); > +void cdns3_enable_l1(struct cdns3_device *priv_dev, int enable); > +struct usb_request *cdns3_next_request(struct list_head *list); > +int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, > + struct usb_request *request); > int cdns3_gadget_ep_set_wedge(struct usb_ep *ep); > int cdns3_gadget_ep_set_halt(struct usb_ep *ep, int value); > +struct usb_request *cdns3_gadget_ep_alloc_request(struct usb_ep *ep, > + gfp_t gfp_flags); > +void cdns3_gadget_ep_free_request(struct usb_ep *ep, > + struct usb_request *request); > +int cdns3_gadget_ep_dequeue(struct usb_ep *ep, struct usb_request *request); > > #endif /* __LINUX_CDNS3_GADGET */ > cheers, -roger -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki 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=-8.6 required=3.0 tests=DKIMWL_WL_HIGH,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH, MAILING_LIST_MULTI,SIGNED_OFF_BY,SPF_PASS,URIBL_BLOCKED autolearn=ham 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 42342C43441 for ; Wed, 28 Nov 2018 14:32:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id E9B8D2081B for ; Wed, 28 Nov 2018 14:32:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=pass (1024-bit key) header.d=ti.com header.i=@ti.com header.b="BIAGKOuw" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org E9B8D2081B Authentication-Results: mail.kernel.org; dmarc=fail (p=quarantine dis=none) header.from=ti.com Authentication-Results: mail.kernel.org; spf=none smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728849AbeK2Bdu (ORCPT ); Wed, 28 Nov 2018 20:33:50 -0500 Received: from fllv0015.ext.ti.com ([198.47.19.141]:45166 "EHLO fllv0015.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727726AbeK2Bdu (ORCPT ); Wed, 28 Nov 2018 20:33:50 -0500 Received: from lelv0266.itg.ti.com ([10.180.67.225]) by fllv0015.ext.ti.com (8.15.2/8.15.2) with ESMTP id wASEVqeo052317; Wed, 28 Nov 2018 08:31:52 -0600 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ti.com; s=ti-com-17Q1; t=1543415512; bh=OFBu3ZozJsMiUk+5vSmf+2YS1IWYVP4nZs7aXBHA6z4=; h=Subject:To:References:CC:From:Date:In-Reply-To; b=BIAGKOuwhdP4m7fsp+3sPeHvmvWy2a7HJjkPChm5AeH5dvUvbUeoKQA2RmNQTDZ4s 9IQgxMtTpyYTi+tSFNO6WdAgNRYBDgDcEvjD8og9DYrLAm4NXJ+rKGio2JxNzXzqx3 m+o1tNgjrMHMgfV6ur14LCC7gUutm3RLJKZVXaTk= Received: from DLEE114.ent.ti.com (dlee114.ent.ti.com [157.170.170.25]) by lelv0266.itg.ti.com (8.15.2/8.15.2) with ESMTPS id wASEVqXp068263 (version=TLSv1.2 cipher=AES256-GCM-SHA384 bits=256 verify=FAIL); Wed, 28 Nov 2018 08:31:52 -0600 Received: from DLEE105.ent.ti.com (157.170.170.35) by DLEE114.ent.ti.com (157.170.170.25) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256_P256) id 15.1.1591.10; Wed, 28 Nov 2018 08:31:50 -0600 Received: from dflp33.itg.ti.com (10.64.6.16) by DLEE105.ent.ti.com (157.170.170.35) with Microsoft SMTP Server (version=TLS1_0, cipher=TLS_RSA_WITH_AES_256_CBC_SHA) id 15.1.1591.10 via Frontend Transport; Wed, 28 Nov 2018 08:31:50 -0600 Received: from [192.168.2.6] (ileax41-snat.itg.ti.com [10.172.224.153]) by dflp33.itg.ti.com (8.14.3/8.13.8) with ESMTP id wASEVl5G027090; Wed, 28 Nov 2018 08:31:47 -0600 Subject: Re: [RFC PATCH v2 10/15] usb:cdns3: Ep0 operations part of the API To: Pawel Laszczak , References: <1542535751-16079-1-git-send-email-pawell@cadence.com> <1542535751-16079-11-git-send-email-pawell@cadence.com> CC: , , , , , , , , , , From: Roger Quadros Message-ID: <5BFEA6D2.9010906@ti.com> Date: Wed, 28 Nov 2018 16:31:46 +0200 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:38.0) Gecko/20100101 Thunderbird/38.6.0 MIME-Version: 1.0 In-Reply-To: <1542535751-16079-11-git-send-email-pawell@cadence.com> Content-Type: text/plain; charset="windows-1252" Content-Transfer-Encoding: 7bit X-EXCLAIMER-MD-CONFIG: e1e8a2fd-e40a-4ac6-ac9b-f7e9cc9ee180 Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On 18/11/18 12:09, Pawel Laszczak wrote: > Patch implements related to default endpoint callback functions > defined in usb_ep_ops object > > Signed-off-by: Pawel Laszczak > --- > drivers/usb/cdns3/ep0.c | 191 ++++++++++++++++++++++++++++++++++++- > drivers/usb/cdns3/gadget.c | 8 ++ > drivers/usb/cdns3/gadget.h | 10 ++ > 3 files changed, 207 insertions(+), 2 deletions(-) > > diff --git a/drivers/usb/cdns3/ep0.c b/drivers/usb/cdns3/ep0.c > index ca1795467155..d05169e73631 100644 > --- a/drivers/usb/cdns3/ep0.c > +++ b/drivers/usb/cdns3/ep0.c > @@ -18,11 +18,185 @@ static struct usb_endpoint_descriptor cdns3_gadget_ep0_desc = { > .bmAttributes = USB_ENDPOINT_XFER_CONTROL, > }; > > +/** > + * cdns3_ep0_run_transfer - Do transfer on default endpoint hardware > + * @priv_dev: extended gadget object > + * @dma_addr: physical address where data is/will be stored > + * @length: data length > + * @erdy: set it to 1 when ERDY packet should be sent - > + * exit from flow control state > + */ > +static void cdns3_ep0_run_transfer(struct cdns3_device *priv_dev, > + dma_addr_t dma_addr, > + unsigned int length, int erdy) > +{ > + struct cdns3_usb_regs __iomem *regs = priv_dev->regs; > + > + priv_dev->trb_ep0->buffer = TRB_BUFFER(dma_addr); > + priv_dev->trb_ep0->length = TRB_LEN(length); > + priv_dev->trb_ep0->control = TRB_CYCLE | TRB_IOC | TRB_TYPE(TRB_NORMAL); > + > + cdns3_select_ep(priv_dev, > + priv_dev->ep0_data_dir ? USB_DIR_IN : USB_DIR_OUT); > + > + writel(EP_STS_TRBERR, ®s->ep_sts); > + writel(EP_TRADDR_TRADDR(priv_dev->trb_ep0_dma), ®s->ep_traddr); > + > + dev_dbg(&priv_dev->dev, "//Ding Dong ep0%s\n", > + priv_dev->ep0_data_dir ? "IN" : "OUT"); > + > + /* TRB should be prepared before starting transfer */ > + writel(EP_CMD_DRDY, ®s->ep_cmd); > + > + if (erdy) > + writel(EP_CMD_ERDY, &priv_dev->regs->ep_cmd); > +} > + > static void cdns3_prepare_setup_packet(struct cdns3_device *priv_dev) > { > //TODO: Implements this function > } > > +static void cdns3_set_hw_configuration(struct cdns3_device *priv_dev) Is this going to be used only for ep0? If yes then let's have ep0 in the name. If not then this function should be in gadget.c > +{ > + struct cdns3_endpoint *priv_ep; > + struct usb_request *request; > + struct usb_ep *ep; > + int result = 0; > + > + if (priv_dev->hw_configured_flag) > + return; > + > + writel(USB_CONF_CFGSET, &priv_dev->regs->usb_conf); > + writel(EP_CMD_ERDY | EP_CMD_REQ_CMPL, &priv_dev->regs->ep_cmd); > + > + cdns3_set_register_bit(&priv_dev->regs->usb_conf, > + USB_CONF_U1EN | USB_CONF_U2EN); Shouldn't U1/U2 be enabled only if the USB_DEVICE_U1_ENABLE/USB_DEVICE_U2_ENABLE device request was received? > + > + /* wait until configuration set */ > + result = cdns3_handshake(&priv_dev->regs->usb_sts, > + USB_STS_CFGSTS_MASK, 1, 100); > + > + priv_dev->hw_configured_flag = 1; > + cdns3_enable_l1(priv_dev, 1); > + > + list_for_each_entry(ep, &priv_dev->gadget.ep_list, ep_list) { > + if (ep->enabled) { > + priv_ep = ep_to_cdns3_ep(ep); > + request = cdns3_next_request(&priv_ep->request_list); > + if (request) > + cdns3_ep_run_transfer(priv_ep, request); why are you starting transfers in a function that is supposed to set hw configuration only. > + } > + } > +} > + > +/** > + * cdns3_gadget_ep0_enable > + * Function shouldn't be called by gadget driver, > + * endpoint 0 is allways active > + */ > +static int cdns3_gadget_ep0_enable(struct usb_ep *ep, > + const struct usb_endpoint_descriptor *desc) > +{ > + return -EINVAL; > +} > + > +/** > + * cdns3_gadget_ep0_disable > + * Function shouldn't be called by gadget driver, > + * endpoint 0 is allways active > + */ > +static int cdns3_gadget_ep0_disable(struct usb_ep *ep) > +{ > + return -EINVAL; > +} > + > +/** > + * cdns3_gadget_ep0_set_halt > + * @ep: pointer to endpoint zero object > + * @value: 1 for set stall, 0 for clear stall > + * > + * Returns 0 > + */ > +static int cdns3_gadget_ep0_set_halt(struct usb_ep *ep, int value) > +{ > + /* TODO */ > + return 0; > +} > + > +/** > + * cdns3_gadget_ep0_queue Transfer data on endpoint zero > + * @ep: pointer to endpoint zero object > + * @request: pointer to request object > + * @gfp_flags: gfp flags > + * > + * Returns 0 on success, error code elsewhere > + */ > +static int cdns3_gadget_ep0_queue(struct usb_ep *ep, > + struct usb_request *request, > + gfp_t gfp_flags) > +{ > + struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); > + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; > + unsigned long flags; > + int erdy_sent = 0; > + int ret = 0; > + > + dev_dbg(&priv_dev->dev, "Queue to Ep0%s L: %d\n", > + priv_dev->ep0_data_dir ? "IN" : "OUT", > + request->length); > + > + /* send STATUS stage */ > + if (request->length == 0 && request->zero == 0) { Is this check sufficient to know STATUS stage? It might be normal for vendor specific control request to have request->length = 0 and request->zero = 0. > + spin_lock_irqsave(&priv_dev->lock, flags); > + cdns3_select_ep(priv_dev, 0x00); > + > + erdy_sent = !priv_dev->hw_configured_flag; > + cdns3_set_hw_configuration(priv_dev); What if we're still busy with DATA stage of previous ep0_queue? if (!list_empty(&priv_ep->request_list)) should be done as the first thing in this function. > + > + if (!erdy_sent) > + writel(EP_CMD_ERDY | EP_CMD_REQ_CMPL, > + &priv_dev->regs->ep_cmd); > + > + cdns3_prepare_setup_packet(priv_dev); > + request->actual = 0; > + priv_dev->status_completion_no_call = true; > + priv_dev->pending_status_request = request; > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + > + /* > + * Since there is no completion interrupt for status stage, > + * it needs to call ->completion in software after > + * ep0_queue is back. > + */ > + queue_work(system_freezable_wq, &priv_dev->pending_status_wq); > + return 0; > + } > + > + spin_lock_irqsave(&priv_dev->lock, flags); > + if (!list_empty(&priv_ep->request_list)) { > + dev_err(&priv_dev->dev, > + "can't handle multiple requests for ep0\n"); > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + return -EOPNOTSUPP; -EBUSY? > + } > + > + ret = usb_gadget_map_request_by_dev(priv_dev->sysdev, request, > + priv_dev->ep0_data_dir); > + if (ret) { > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + dev_err(&priv_dev->dev, "failed to map request\n"); > + return -EINVAL; > + } > + > + priv_dev->ep0_request = request; > + list_add_tail(&request->list, &priv_ep->request_list); > + cdns3_ep0_run_transfer(priv_dev, request->dma, request->length, 1); > + spin_unlock_irqrestore(&priv_dev->lock, flags); > + > + return ret; > +} > + > /** > * cdns3_gadget_ep_set_wedge Set wedge on selected endpoint > * @ep: endpoint object > @@ -41,6 +215,17 @@ int cdns3_gadget_ep_set_wedge(struct usb_ep *ep) > return 0; > } > > +const struct usb_ep_ops cdns3_gadget_ep0_ops = { > + .enable = cdns3_gadget_ep0_enable, > + .disable = cdns3_gadget_ep0_disable, > + .alloc_request = cdns3_gadget_ep_alloc_request, > + .free_request = cdns3_gadget_ep_free_request, > + .queue = cdns3_gadget_ep0_queue, > + .dequeue = cdns3_gadget_ep_dequeue, > + .set_halt = cdns3_gadget_ep0_set_halt, > + .set_wedge = cdns3_gadget_ep_set_wedge, > +}; > + > /** > * cdns3_ep0_config - Configures default endpoint > * @priv_dev: extended gadget object > @@ -62,6 +247,9 @@ void cdns3_ep0_config(struct cdns3_device *priv_dev) > priv_dev->ep0_request = NULL; > } > > + priv_dev->u1_allowed = 0; > + priv_dev->u2_allowed = 0; > + where do you set these? > priv_dev->gadget.ep0->maxpacket = max_packet_size; > cdns3_gadget_ep0_desc.wMaxPacketSize = cpu_to_le16(max_packet_size); > > @@ -106,8 +294,7 @@ int cdns3_init_ep0(struct cdns3_device *priv_dev) > sprintf(ep0->name, "ep0"); > > /* fill linux fields */ > - //TODO: implements cdns3_gadget_ep0_ops object > - //ep0->endpoint.ops = &cdns3_gadget_ep0_ops; > + ep0->endpoint.ops = &cdns3_gadget_ep0_ops; > ep0->endpoint.maxburst = 1; > usb_ep_set_maxpacket_limit(&ep0->endpoint, ENDPOINT0_MAX_PACKET_LIMIT); > ep0->endpoint.address = 0; > diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c > index 1f2a434486dc..c965da16c0c8 100644 > --- a/drivers/usb/cdns3/gadget.c > +++ b/drivers/usb/cdns3/gadget.c > @@ -188,6 +188,14 @@ static void cdns3_ep_stall_flush(struct cdns3_endpoint *priv_ep) > priv_ep->flags |= EP_STALL; > } > > +void cdns3_enable_l1(struct cdns3_device *priv_dev, int enable) Some comment might help as to what L1 is. > +{ > + if (enable) > + writel(USB_CONF_L1EN, &priv_dev->regs->usb_conf); > + else > + writel(USB_CONF_L1DS, &priv_dev->regs->usb_conf); > +} > + > /** > * cdns3_gadget_giveback - call struct usb_request's ->complete callback > * @priv_ep: The endpoint to whom the request belongs to > diff --git a/drivers/usb/cdns3/gadget.h b/drivers/usb/cdns3/gadget.h > index a4be288b34cb..224f6b830bc9 100644 > --- a/drivers/usb/cdns3/gadget.h > +++ b/drivers/usb/cdns3/gadget.h > @@ -1068,11 +1068,21 @@ struct cdns3_device { > struct usb_request *pending_status_request; > }; > > +int cdns3_handshake(void __iomem *ptr, u32 mask, u32 done, int usec); > void cdns3_set_register_bit(void __iomem *ptr, u32 mask); > int cdns3_init_ep0(struct cdns3_device *priv_dev); > void cdns3_ep0_config(struct cdns3_device *priv_dev); > void cdns3_select_ep(struct cdns3_device *priv_dev, u32 ep); > +void cdns3_enable_l1(struct cdns3_device *priv_dev, int enable); > +struct usb_request *cdns3_next_request(struct list_head *list); > +int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, > + struct usb_request *request); > int cdns3_gadget_ep_set_wedge(struct usb_ep *ep); > int cdns3_gadget_ep_set_halt(struct usb_ep *ep, int value); > +struct usb_request *cdns3_gadget_ep_alloc_request(struct usb_ep *ep, > + gfp_t gfp_flags); > +void cdns3_gadget_ep_free_request(struct usb_ep *ep, > + struct usb_request *request); > +int cdns3_gadget_ep_dequeue(struct usb_ep *ep, struct usb_request *request); > > #endif /* __LINUX_CDNS3_GADGET */ > cheers, -roger -- Texas Instruments Finland Oy, Porkkalankatu 22, 00180 Helsinki. Y-tunnus/Business ID: 0615521-4. Kotipaikka/Domicile: Helsinki