From patchwork Sun Nov 18 10:09:05 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Pawel Laszczak X-Patchwork-Id: 10687709 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id B86AF109C for ; Sun, 18 Nov 2018 10:11:18 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id A7D9829D31 for ; Sun, 18 Nov 2018 10:11:18 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 9A20B29D43; Sun, 18 Nov 2018 10:11:18 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-8.0 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 6DCAA29D31 for ; Sun, 18 Nov 2018 10:11:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727459AbeKRUbB (ORCPT ); Sun, 18 Nov 2018 15:31:01 -0500 Received: from mx0a-0014ca01.pphosted.com ([208.84.65.235]:36408 "EHLO mx0a-0014ca01.pphosted.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727332AbeKRUbA (ORCPT ); Sun, 18 Nov 2018 15:31:00 -0500 Received: from pps.filterd (m0042385.ppops.net [127.0.0.1]) by mx0a-0014ca01.pphosted.com (8.16.0.27/8.16.0.27) with SMTP id wAIA6Vw2016029; Sun, 18 Nov 2018 02:10:49 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cadence.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-type; s=proofpoint; bh=bzpE4qQALzyWPjEOjKHnjLU28Zpeyt/p3Gm66EUqIBw=; b=IQA8RXr1GdnPhhOucgAFmozkUHVOYeC40jvAwWH5IwFwsRyv8eY6UNP/Ycv4WiEprnG4 JJLQjEFdAycTsAMH91VFsED+qTCr56cinG95nLgOAsu24Pf3dETO6zSbpBa4XU5XdRt4 /2YiFpZI0IWXX8hZAXIGO6n6PGwVp575QQ9O3hIMHgH9jEOv3GT7bM3Tg5JJi76qQqIe Tu/X4h7ASYIuALooJ7G8/chkAALzFArOLh1KEfwqGTp8eYqrEtiJB//p5Q6tsfSv7rYM 82QyAP6bhCw4NoXEWrl2z8K8lfRR/OdqfeGVpAIX9KQPEXYiOdmPjlon/1z8ty/Bn4qT 3g== Authentication-Results: cadence.com; spf=pass smtp.mailfrom=pawell@cadence.com Received: from nam01-by2-obe.outbound.protection.outlook.com (mail-by2nam01lp0178.outbound.protection.outlook.com [216.32.181.178]) by mx0a-0014ca01.pphosted.com with ESMTP id 2ntge14vg7-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-SHA384 bits=256 verify=NOT); Sun, 18 Nov 2018 02:10:49 -0800 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=cadence.com; s=selector1; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=bzpE4qQALzyWPjEOjKHnjLU28Zpeyt/p3Gm66EUqIBw=; b=dZkk1HXMiI6ibnyRShx7jmy72N58SmFaKMpvwTl/ghRyHcZqIoxaTbTMwyZzrapUSPwSp5mXwlAELXOxocsUrglo0iv3c5pUSZ/7CLiq4dcdGAkIjKViLEbJ6ejXvD1gIVvsVXNmXCsaKi3mWqXrQPZ1lSK3yhqj1rHCq2L+r7U= Received: from DM5PR07CA0051.namprd07.prod.outlook.com (2603:10b6:4:ad::16) by BLUPR0701MB1857.namprd07.prod.outlook.com (2a01:111:e400:5165::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1294.26; Sun, 18 Nov 2018 10:10:46 +0000 Received: from DM3NAM05FT017.eop-nam05.prod.protection.outlook.com (2a01:111:f400:7e51::204) by DM5PR07CA0051.outlook.office365.com (2603:10b6:4:ad::16) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1339.21 via Frontend Transport; Sun, 18 Nov 2018 10:10:45 +0000 Received-SPF: SoftFail (protection.outlook.com: domain of transitioning cadence.com discourages use of 158.140.1.28 as permitted sender) Received: from sjmaillnx2.cadence.com (158.140.1.28) by DM3NAM05FT017.mail.protection.outlook.com (10.152.98.126) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.1339.3 via Frontend Transport; Sun, 18 Nov 2018 10:10:44 +0000 Received: from maileu3.global.cadence.com (maileu3.cadence.com [10.160.88.99]) by sjmaillnx2.cadence.com (8.14.4/8.14.4) with ESMTP id wAIAAb5R029622 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=FAIL); Sun, 18 Nov 2018 02:10:44 -0800 X-CrossPremisesHeadersFilteredBySendConnector: maileu3.global.cadence.com Received: from maileu3.global.cadence.com (10.160.88.99) by maileu3.global.cadence.com (10.160.88.99) with Microsoft SMTP Server (TLS) id 15.0.1367.3; Sun, 18 Nov 2018 11:10:43 +0100 Received: from lvlogina.cadence.com (10.165.176.102) by maileu3.global.cadence.com (10.160.88.99) with Microsoft SMTP Server id 15.0.1367.3 via Frontend Transport; Sun, 18 Nov 2018 11:10:43 +0100 Received: from lvlogina.cadence.com (localhost.localdomain [127.0.0.1]) by lvlogina.cadence.com (8.14.4/8.14.4) with ESMTP id wAIAAdwF031663; Sun, 18 Nov 2018 10:10:39 GMT Received: (from pawell@localhost) by lvlogina.cadence.com (8.14.4/8.14.4/Submit) id wAIAAdnH031610; Sun, 18 Nov 2018 10:10:39 GMT From: Pawel Laszczak To: CC: , , , , , , , , , , , , "Pawel Laszczak" Subject: [RFC PATCH v2 09/15] usb:cdns3: EpX operations part of the API Date: Sun, 18 Nov 2018 10:09:05 +0000 Message-ID: <1542535751-16079-10-git-send-email-pawell@cadence.com> X-Mailer: git-send-email 1.7.11.2 In-Reply-To: <1542535751-16079-1-git-send-email-pawell@cadence.com> References: <1542535751-16079-1-git-send-email-pawell@cadence.com> MIME-Version: 1.0 X-OrganizationHeadersPreserved: maileu3.global.cadence.com X-EOPAttributedMessage: 0 X-Forefront-Antispam-Report: CIP:158.140.1.28;IPV:CAL;SCL:-1;CTRY:US;EFV:NLI;SFV:NSPM;SFS:(10009020)(346002)(376002)(39860400002)(136003)(396003)(2980300002)(36092001)(189003)(199004)(486006)(246002)(11346002)(6916009)(126002)(476003)(2616005)(2906002)(426003)(4744004)(4326008)(6666004)(4720700003)(446003)(105596002)(575784001)(26005)(86362001)(106466001)(2351001)(478600001)(26826003)(356004)(87636003)(14444005)(107886003)(336012)(76176011)(217873002)(50466002)(16586007)(36756003)(48376002)(47776003)(51416003)(316002)(186003)(8676002)(50226002)(8936002)(5660300001)(7636002)(305945005)(54906003)(42186006)(309714004);DIR:OUT;SFP:1101;SCL:1;SRVR:BLUPR0701MB1857;H:sjmaillnx2.cadence.com;FPR:;SPF:SoftFail;LANG:en;PTR:corp.cadence.com;MX:1;A:1; X-Microsoft-Exchange-Diagnostics: 1;DM3NAM05FT017;1:VZwdZ/uSg15PkpSpR/cgfKw2PgGnEMLqJeX17f5KsJuFo5Fgjw4dY+wjpug6IzWoGBlJcZQNAk4C2b+me4R9fjG/WCXyfHcqbgB7wj18Qe6atPFVqhLCxvfAS8E2lK3H X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-Correlation-Id: 97a94859-96f5-46fe-d380-08d64d3e1aeb X-Microsoft-Antispam: BCL:0;PCL:0;RULEID:(2390098)(7020095)(4652040)(8989299)(5600074)(711020)(4534185)(4627221)(201703031133081)(201702281549075)(8990200)(2017052603328)(7153060);SRVR:BLUPR0701MB1857; X-Microsoft-Exchange-Diagnostics: 1;BLUPR0701MB1857;3:q0tdBbVD7kCqWZMUtwxN/WZPNpM9YhjxGmnZcehuIoHMEzSUhWjddZerYOcf4qotfBGjD2s9OakFeiBvz30oMiipYr1e1IHHcr6vjE3yEXDt8ztmP0tjOTYFcBGvQFmDDMdB+wkoS40WPeDWWdEDn+M4U6yZc6ImG2rkJ8GhNIvVxe7SGGiKzEOSRY4EEz9qz94d2s+2N1b2OBLwoltm7EHwqZISBlLm9bMwH5vmsh7pnxYrl6mbjFg1wQ9xoEPDhtIOG+jugFzQvChK9/hItUo/Mn8ImJDGRRGDZs6lAOMrKO+fwGgLkkPS3A/ZA5rERhMwqpAbweKBPC0wAkBzTkBb/7k7jiCmKF6+Y9L0EIA=;25:VnqMkEJ4Bf5AotiV/fX9O7EHIQdw0/4O2hXRGZrxq4m1agNmz2X+Id55YCarvXoiS0qZTHZm8HzSuV/po9sLJbh0adVa/BwYE8dUEmJuKNqU22Ijg5KYFYw7Mik0CZs509+LWPtTmuCCdsTZ6gssVqosVx3TbRXOp8DK13XmizFG1FRupWYeHoey+3gfGE95fh/IT8GmFvz5Vn2ogQ9NHANmrYWelDaPbQ6IE+vl3PFNHCfVRXX6+FE3vLnm+wLFkFLrOveCrmYr7i/djhLVBI1XoA899wz6Af4AQt3K62G3hNlITwut88kDwwh6vI5nL4Ygv/5d4gMfy21sSr+t6cbPKCYSfAigQeqd9O5I3Pw= X-MS-TrafficTypeDiagnostic: BLUPR0701MB1857: X-Microsoft-Exchange-Diagnostics: 1;BLUPR0701MB1857;31:MM/RTt1u3wrOuoQ7xb/wtYgpkowFtK7l/LjKchhBsr3vM38j11AQLR2cv3H109Jken9LEKvI7jgEIiS3PKoF2mkMsmpn1OULinlK/IIR18UGWFInY1TlbP4sA//GUrfdoORypYnhriwJjvIh/tyqY6YI1Ry2wQQb0qMpDfBCxQqDONmWw3mnafLxaN3YC8SsmAn727AuwUI483Q/tufDChSLckUSBqd4qKdJEB8mvdc=;20:7Pqj4IV9wzMKgLJRuZsCshraU3lfAm751DgAKMlEbvTkK89R9aDs01fs+ipRM4dfeePnDFSq6R8NbY9i5k5c7tSDKjOK4zwG9CZJ9XUg3q8jArL7Dz6KgGFC9Z1wejAB/ghHlMRTHzkTNTTTV5Hiv5xSW46VPIdSMEvDfkdcT9tbOv9vNbSFvEGdsP2/d6IoE4j5kY6Csh1DpkPFwsC3WT1p13CK25aCpUUWzE3Gsu6lh5v4S15M5xAPF6IbdFv62DSISMZ6Q71siJly22Xv7H9f/prTXgwPikCtGpdfrMHaWOF5/QjtvX8y1PzJSljBcRsuIVvNcAOIT0Ic2ap0vN4Hhz8zN9qo59S0fY4TU9V4C6AkO0/Ic58l9GPAAcsebDk+9P5/ZK6JTFU02bEACoplvCOwGhZj4YN0w6UqbshFe9EO0Ureh18OHna17CjGLXSTThzScbfMOTuTbywK4H0o4SUjck5O8YWxhqk2XjzWavm4QSNN2SVld9uxoYYd X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:(72806322054110); X-MS-Exchange-SenderADCheck: 1 X-Exchange-Antispam-Report-CFA-Test: BCL:0;PCL:0;RULEID:(8211001083)(6040522)(2401047)(5005006)(8121501046)(93006095)(93003095)(3231415)(944501410)(52105112)(10201501046)(3002001)(148016)(149066)(150057)(6041310)(20161123558120)(20161123562045)(20161123564045)(20161123560045)(201703131423095)(201702281528075)(20161123555045)(201703061421075)(201703061406153)(201708071742011)(7699051)(76991095);SRVR:BLUPR0701MB1857;BCL:0;PCL:0;RULEID:;SRVR:BLUPR0701MB1857; X-Microsoft-Exchange-Diagnostics: 1;BLUPR0701MB1857;4:wq8K8EfiDpkHvTZBO1ACGMyZtGXOVphFFspe3KK4O6w2cI9zPtMWBjkS8QIIHzeGrEKR2AifNmz7oOkkPetxJwuvr5x3fX0u5D7WEPnkSRm0Gz1kVa/9SGvx2sCAywIEer5Gsc/NKiQhNA3KZRRSn7MKUw2t20GzFCNZWEvjbZBdid17LeREk4SA/l/7afFKYa5+VGcMBxiADM3chl5FHpW9vF5G/f/b4JRI5qfojdsCSyY0jqQJYxtDGR8kud6/9nfR2KrEaORIZkGrZywSD36/uBGXLG73mCCGza27p1DUjF8rACorLWtsFaKz7fjo X-Forefront-PRVS: 0860FE717F X-Microsoft-Exchange-Diagnostics: 1;BLUPR0701MB1857;23:vV2hw3d60bA0j5MALl42449IihmXis/1hmCv9vKnR7r+lB+Z2q3WYY1Dc64f+qN6vsBhjU4Usj78fMHi0DlCklTlK4J9scCBPG0w1HCA+i4rrSUr88pPB9nSgGuOZ16VfPzzvITmVfk3J4Bj0NhTtw+ssgpYz5DK0OXogTM4DWL1CHl5+dC4lP/qkgjWzCvlmLOnI6nmFSe9DnAFSeTNGogT7IpF0A8yB/zc8GjQcs04ikVDuBlTi2UGZCE5fon9KWN3F/J/VIaLoLMSUuENpOfIxFZPyURI+bJPOI533Oc99Rrm19tHQR/9LZnJg8rfmLMXFntqqi+/b3SBH76BzG2AJEtrWzKOiDa45SkTX5osi4aXHVU8u8mfdcGPOdeQE9KHsPtGzPI5RknUNBo8CHXqY1fcJHv8OnhtwlQUm10iGjhRgSDe862dtmA/0AfoXNDyUK0EiursoQE/hW+MfGe6o6+Tjt7fz45nC2PT83zTuDLZF+Ntd9OaRwyw2FBIX6G7Aa6GRTcqfK7pPzgdU1apETWEwiZlzChFB4IdjHasYFHq/gjODxUuNUoUdtV1z8YhMheioAmGQGGuqHEizlTy1iqTh9ZzW1jIxtXguWMZR0oHu355xi6px8sTfEWG7oGRWLw6MzkXVakRv/fe8DnoZ+Uwvv+zOeUBKffVHJ2r1tfBKDlnxij5xCWxwXxJ23cXq0Q7aPIjRThZBsxZws2wDIZC3o0SL8hJYoZyUepe5KXKe+1XEB96MNbOiCHLC9vHP/67Wkk4Ev53HLAITZTX5Vn4ZMmKEFsNO6+6A3+eXEI2lXJgPhRd//W4qnh11fT6Z5Zgd8P6329QD7sAnvXU+n9nOaRJSi88oiMLbAMmFAnPHhM2o5eQskfBc934Pr9kzWtlTWNIsxIkf1yadtxAJBmDKmFQIxR9AeTyVYHnJ31M1mrSq3e4stP3tTO7b0/cwFEDniwCyGZH7HHxWbWlb2nRwhsOdFLh4VHDOKBOeYFMsB7pvTKQ9obJuP7kRg8StCPYSAvZ96I8lr9yDe5IXhhAXSWssepX5bzu9IN4QG+Qm6/Sy+dFdrfIPfEO4F3NbW/rtLMo22QXk32C+CIuO6gS/50pP2TC8T37byrwwH2C/S47cEOyi5gD7gcSJqS9h8WhRiFh94ezaePpOh2QY6NhjSiXWFzzV2kt1T4l7ptzjlFR+XPa7tOX8xDaBAlGyh7i6YUc518QpY3Pug== X-Microsoft-Antispam-Message-Info: rBusOuP8Ir083U0AI04J/5qt5TI0ojUrgrejrh5PofwKPRipUdwZ2dUWo1fchrx1WfKbknwRdmBh50XMzRMckMcR3+5IOeNqtN2O1e8Is+2aGol3zO3qKS67yN4xX+Z90p8UZVAKfEKciRvmbuEXoJow/pIM4dD67W0AkZg6lI/J/W7+CeSgYltDnKG/kJyaWB4NjAUaDeGQ9dmJ/c+k14QiKVYLM4ftJVi5Yd0P50V5+D5dZxOcppjI/10CMUi9N3fpfS/Z5FX2lb57X6pPZCvJcgbVhWTt0Rq7M82Ly29/rFqoHbzcPwuDvbIOPfaHCwZPU7fFxwlQtE1Q04vK6tiYacdyusX+1HDbCuS/UpQ= X-Microsoft-Exchange-Diagnostics: 1;BLUPR0701MB1857;6:s9qJ8/sGSt5lK03qdpwNGTykMC9L79pzqz4bpMGPQv8RQqTWeoxvP6JqIyfhNci5BdRE/GBVIOuvZ6ixSAvvYnwZn7/wGtmXBCxKnpS9g0JDsSgOcqMcaipKJKwrR1+LjqBFSDiFiQtTF6d1N0maS3CKK1b/sFK2dBGaNgJSur2EngVltZJCNimr5PI0YuMHLFRphomjG8Oorl9nmtftgZNuDMmF2hqnWhlDYGD67vLpv06Hk+Zy0eF9KfDP1/dI00kZZRJsUSbPxxbolBnf1p4Zynnw/NU5kkfbUGB6TFn02/EOqyfOuxShxWr92evBK7RiB1UD+OmNqBXucxQgJPkb4/3CQD7/nAH+e3kI1w2dSI8yQwzrZMi83AnV+jV37ed3P/F67IE0+F5om1a4lOGmsHixP2QzNUx+kAZJhTLk3PJ+ElTe/CoB/bj49mqxSvfN1Eaumm6HE6gMxarsDzxJNp6K2RF+MBQXZ1cTVvU=;5:iYFIMOnOvWm2QKm7kMNChL7Sw6MKxHPu3aEqBvxCmdaPtcL3MGUjgl0bSipnd8uIXZrVWkumFDpeVOTqysJkzKYSdTH7oRmD/VijUeU/AhjCiBTyqXwEyS+fMFKyBGhaC7BQjg4sSVO3rIksrNS2WzPwkckSPyFsA6N5hW4mm2k=;7:kgNKmPclKmKGlSn+fsav30cJtC7oCSTBA0BctyLeqVldKiSpFsowF/farabw0zSmtG4V40/R8DpL0YzAQp9rIQ77LBD7pX66+LfvmTmaw01qPpg70Jch/J6yuBICFl8QflgbXoBKAuCqjGI2I16rUA== SpamDiagnosticOutput: 1:99 SpamDiagnosticMetadata: NSPM X-Microsoft-Exchange-Diagnostics: 1;BLUPR0701MB1857;20:ZXGnL+gLcrSnqY2jK6p+6/l4Ncj8YVUJiilgk/K6mxG/8lRVEhaS3uQJtWDpOchrva3fW3yw4hTF7jYqdKmnxNeU4ekkhoLgHwYYtZZxcfPNmyTcIbAdqacK8ET0kJV5kmm3Updf2gmOzvMb0VH30UnX9CnXX8Kh0EgQhz45dbZe9DeP7ctir5cqwJ0OeZIygDHp6PFTpxN7rMpBaTc+3oEc93UvoAOoY/a2ISOAyN0dlJ4HWDmfYyW1GQS574JG X-OriginatorOrg: cadence.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 18 Nov 2018 10:10:44.9008 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: 97a94859-96f5-46fe-d380-08d64d3e1aeb X-MS-Exchange-CrossTenant-Id: d36035c5-6ce6-4662-a3dc-e762e61ae4c9 X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=d36035c5-6ce6-4662-a3dc-e762e61ae4c9;Ip=[158.140.1.28];Helo=[sjmaillnx2.cadence.com] X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: BLUPR0701MB1857 X-Proofpoint-SPF-Result: pass X-Proofpoint-SPF-Record: v=spf1 a:mx-sanjose2.Cadence.COM a:mx-sanjose4.Cadence.COM a:mx-sanjose5.Cadence.COM include:mktomail.com include:spf-0014ca01.pphosted.com include:spf.protection.outlook.com include:auth.msgapp.com include:spf.mandrillapp.com ~all X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10434:,, definitions=2018-11-18_03:,, signatures=0 X-Proofpoint-Spam-Details: rule=outbound_check_notspam policy=outbound_check score=0 priorityscore=1501 malwarescore=0 suspectscore=3 phishscore=0 bulkscore=0 spamscore=0 clxscore=1015 lowpriorityscore=0 mlxscore=0 impostorscore=0 mlxlogscore=725 adultscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.0.1-1810050000 definitions=main-1811180096 Sender: linux-usb-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-usb@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Patch implements callback functions for non-default endpoints defined in usb_ep_ops object. Signed-off-by: Pawel Laszczak --- drivers/usb/cdns3/ep0.c | 18 ++ drivers/usb/cdns3/gadget.c | 442 ++++++++++++++++++++++++++++++++++++- drivers/usb/cdns3/gadget.h | 3 + 3 files changed, 461 insertions(+), 2 deletions(-) diff --git a/drivers/usb/cdns3/ep0.c b/drivers/usb/cdns3/ep0.c index c08d02665f9d..ca1795467155 100644 --- a/drivers/usb/cdns3/ep0.c +++ b/drivers/usb/cdns3/ep0.c @@ -23,6 +23,24 @@ static void cdns3_prepare_setup_packet(struct cdns3_device *priv_dev) //TODO: Implements this function } +/** + * cdns3_gadget_ep_set_wedge Set wedge on selected endpoint + * @ep: endpoint object + * + * Returns 0 + */ +int cdns3_gadget_ep_set_wedge(struct usb_ep *ep) +{ + struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; + + dev_dbg(&priv_dev->dev, "Wedge for %s\n", ep->name); + cdns3_gadget_ep_set_halt(ep, 1); + priv_ep->flags |= EP_WEDGE; + + return 0; +} + /** * cdns3_ep0_config - Configures default endpoint * @priv_dev: extended gadget object diff --git a/drivers/usb/cdns3/gadget.c b/drivers/usb/cdns3/gadget.c index 702a05faa664..1f2a434486dc 100644 --- a/drivers/usb/cdns3/gadget.c +++ b/drivers/usb/cdns3/gadget.c @@ -58,6 +58,19 @@ void cdns3_set_register_bit(void __iomem *ptr, u32 mask) writel(mask, ptr); } +/** + * cdns3_next_request - returns next request from list + * @list: list containing requests + * + * Returns request or NULL if no requests in list + */ +struct usb_request *cdns3_next_request(struct list_head *list) +{ + if (list_empty(list)) + return NULL; + return list_first_entry(list, struct usb_request, list); +} + /** * select_ep - selects endpoint * @priv_dev: extended gadget object @@ -73,6 +86,53 @@ void cdns3_select_ep(struct cdns3_device *priv_dev, u32 ep) writel(ep, &priv_dev->regs->ep_sel); } +/** + * cdns3_allocate_trb_pool - Allocates TRB's pool for selected endpoint + * @priv_ep: endpoint object + * + * Function will return 0 on success or -ENOMEM on allocation error + */ +static int cdns3_allocate_trb_pool(struct cdns3_endpoint *priv_ep) +{ + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; + struct cdns3_trb *link_trb; + + if (!priv_ep->trb_pool) { + priv_ep->trb_pool = dma_zalloc_coherent(priv_dev->sysdev, + TRB_RIGN_SIZE, + &priv_ep->trb_pool_dma, + GFP_DMA); + if (!priv_ep->trb_pool) + return -ENOMEM; + } else { + memset(priv_ep->trb_pool, 0, TRB_RIGN_SIZE); + } + + if (!priv_ep->aligned_buff) { + priv_ep->aligned_buff = dma_alloc_coherent(priv_dev->sysdev, + CDNS3_UNALIGNED_BUF_SIZE, + &priv_ep->aligned_dma_addr, + GFP_DMA); + if (!priv_ep->aligned_buff) { + dma_free_coherent(priv_dev->sysdev, + TRB_RIGN_SIZE, + priv_ep->trb_pool, + priv_ep->trb_pool_dma); + priv_ep->trb_pool = NULL; + + return -ENOMEM; + } + } + + /* Initialize the last TRB as Link TRB */ + link_trb = (priv_ep->trb_pool + TRBS_PER_SEGMENT - 1); + link_trb->buffer = TRB_BUFFER(priv_ep->trb_pool_dma); + link_trb->control = TRB_CYCLE | TRB_TYPE(TRB_LINK) | + TRB_CHAIN | TRB_TOGGLE; + + return 0; +} + static void cdns3_free_trb_pool(struct cdns3_endpoint *priv_ep) { struct cdns3_device *priv_dev = priv_ep->cdns3_dev; @@ -92,6 +152,73 @@ static void cdns3_free_trb_pool(struct cdns3_endpoint *priv_ep) } } +/** + * cdns3_data_flush - flush data at onchip buffer + * @priv_ep: endpoint object + * + * Endpoint must be selected before call to this function + * + * Returns zero on success or negative value on failure + */ +static int cdns3_data_flush(struct cdns3_endpoint *priv_ep) +{ + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; + + writel(EP_CMD_DFLUSH, &priv_dev->regs->ep_cmd); + + /* wait for DFLUSH cleared */ + return cdns3_handshake(&priv_dev->regs->ep_cmd, EP_CMD_DFLUSH, 0, 100); +} + +/** + * cdns3_ep_stall_flush - Stalls and flushes selected endpoint + * @priv_ep: endpoint object + * + * Endpoint must be selected before call to this function + */ +static void cdns3_ep_stall_flush(struct cdns3_endpoint *priv_ep) +{ + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; + + writel(EP_CMD_DFLUSH | EP_CMD_ERDY | EP_CMD_SSTALL, + &priv_dev->regs->ep_cmd); + + /* wait for DFLUSH cleared */ + cdns3_handshake(&priv_dev->regs->ep_cmd, EP_CMD_DFLUSH, 0, 100); + priv_ep->flags |= EP_STALL; +} + +/** + * cdns3_gadget_giveback - call struct usb_request's ->complete callback + * @priv_ep: The endpoint to whom the request belongs to + * @priv_req: The request we're giving back + * @status: completion code for the request + * + * Must be called with controller's lock held and interrupts disabled. This + * function will unmap @req and call its ->complete() callback to notify upper + * layers that it has completed. + */ +void cdns3_gadget_giveback(struct cdns3_endpoint *priv_ep, + struct cdns3_request *priv_req, + int status) +{ + //TODO: Implements this function. +} + +/** + * cdns3_ep_run_transfer - start transfer on no-default endpoint hardware + * @priv_ep: endpoint object + * + * Returns zero on success or negative value on failure + */ +int cdns3_ep_run_transfer(struct cdns3_endpoint *priv_ep, + struct usb_request *request) +{ + //TODO: Implements this function. + + return 0; +} + /** * cdns3_irq_handler - irq line interrupt handler * @cdns: cdns3 instance @@ -170,6 +297,318 @@ static struct usb_ep *cdns3_gadget_match_ep(struct usb_gadget *gadget, return &priv_ep->endpoint; } +/** + * cdns3_gadget_ep_enable Enable endpoint + * @ep: endpoint object + * @desc: endpoint descriptor + * + * Returns 0 on success, error code elsewhere + */ +static int cdns3_gadget_ep_enable(struct usb_ep *ep, + const struct usb_endpoint_descriptor *desc) +{ + struct cdns3_endpoint *priv_ep; + struct cdns3_device *priv_dev; + unsigned long flags; + int ret; + u32 reg; + + priv_ep = ep_to_cdns3_ep(ep); + priv_dev = priv_ep->cdns3_dev; + + if (!ep || !desc || desc->bDescriptorType != USB_DT_ENDPOINT) { + dev_err(&priv_dev->dev, "usbss: invalid parameters\n"); + return -EINVAL; + } + + if (!desc->wMaxPacketSize) { + dev_err(&priv_dev->dev, "usbss: missing wMaxPacketSize\n"); + return -EINVAL; + } + + if (dev_WARN_ONCE(&priv_dev->dev, priv_ep->flags & EP_ENABLED, + "%s is already enabled\n", priv_ep->name)) + return 0; + + ret = cdns3_allocate_trb_pool(priv_ep); + if (ret) + return ret; + + dev_dbg(&priv_dev->dev, "Enabling endpoint: %s\n", ep->name); + spin_lock_irqsave(&priv_dev->lock, flags); + cdns3_select_ep(priv_dev, desc->bEndpointAddress); + writel(EP_CMD_EPRST, &priv_dev->regs->ep_cmd); + + ret = cdns3_handshake(&priv_dev->regs->ep_cmd, + EP_CMD_CSTALL | EP_CMD_EPRST, 0, 100); + + cdns3_set_register_bit(&priv_dev->regs->ep_cfg, EP_CFG_ENABLE); + + ep->desc = desc; + priv_ep->flags &= ~(EP_PENDING_REQUEST | EP_STALL); + priv_ep->flags |= EP_ENABLED | EP_UPDATE_EP_TRBADDR; + priv_ep->enqueue = 0; + priv_ep->dequeue = 0; + reg = readl(&priv_dev->regs->ep_sts); + priv_ep->pcs = !!EP_STS_CCS(reg); + priv_ep->ccs = !!EP_STS_CCS(reg); + /* one TRB is reserved for link TRB used in DMULT mode*/ + priv_ep->free_trbs = TRBS_PER_SEGMENT - 1; + + spin_unlock_irqrestore(&priv_dev->lock, flags); + return 0; +} + +/** + * cdns3_gadget_ep_disable Disable endpoint + * @ep: endpoint object + * + * Returns 0 on success, error code elsewhere + */ +static int cdns3_gadget_ep_disable(struct usb_ep *ep) +{ + struct cdns3_endpoint *priv_ep; + struct cdns3_device *priv_dev; + unsigned long flags; + int ret = 0; + struct usb_request *request; + u32 ep_cfg; + + if (!ep) { + pr_debug("usbss: invalid parameters\n"); + return -EINVAL; + } + + priv_ep = ep_to_cdns3_ep(ep); + priv_dev = priv_ep->cdns3_dev; + + if (dev_WARN_ONCE(&priv_dev->dev, !(priv_ep->flags & EP_ENABLED), + "%s is already disabled\n", priv_ep->name)) + return 0; + + spin_lock_irqsave(&priv_dev->lock, flags); + if (!priv_dev->start_gadget) { + dev_dbg(&priv_dev->dev, + "Disabling endpoint at disconnection: %s\n", ep->name); + spin_unlock_irqrestore(&priv_dev->lock, flags); + return 0; + } + + dev_dbg(&priv_dev->dev, "Disabling endpoint: %s\n", ep->name); + + cdns3_select_ep(priv_dev, ep->desc->bEndpointAddress); + ret = cdns3_data_flush(priv_ep); + while (!list_empty(&priv_ep->request_list)) { + request = cdns3_next_request(&priv_ep->request_list); + + cdns3_gadget_giveback(priv_ep, to_cdns3_request(request), + -ESHUTDOWN); + } + + ep_cfg = readl(&priv_dev->regs->ep_cfg); + ep_cfg &= ~EP_CFG_ENABLE; + writel(ep_cfg, &priv_dev->regs->ep_cfg); + ep->desc = NULL; + priv_ep->flags &= ~EP_ENABLED; + + spin_unlock_irqrestore(&priv_dev->lock, flags); + + return ret; +} + +/** + * cdns3_gadget_ep_alloc_request Allocates request + * @ep: endpoint object associated with request + * @gfp_flags: gfp flags + * + * Returns allocated request address, NULL on allocation error + */ +struct usb_request *cdns3_gadget_ep_alloc_request(struct usb_ep *ep, + gfp_t gfp_flags) +{ + struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); + struct cdns3_request *priv_req; + + priv_req = kzalloc(sizeof(*priv_req), gfp_flags); + if (!priv_req) + return NULL; + + priv_req->priv_ep = priv_ep; + + return &priv_req->request; +} + +/** + * cdns3_gadget_ep_free_request Free memory occupied by request + * @ep: endpoint object associated with request + * @request: request to free memory + */ +void cdns3_gadget_ep_free_request(struct usb_ep *ep, + struct usb_request *request) +{ + struct cdns3_request *priv_req = to_cdns3_request(request); + + kfree(priv_req); +} + +/** + * cdns3_gadget_ep_queue Transfer data on endpoint + * @ep: endpoint object + * @request: request object + * @gfp_flags: gfp flags + * + * Returns 0 on success, error code elsewhere + */ +static int __cdns3_gadget_ep_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; + int ret = 0; + + request->actual = 0; + request->status = -EINPROGRESS; + + dev_dbg(&priv_dev->dev, "Queuing to endpoint: %s\n", priv_ep->name); + + ret = usb_gadget_map_request_by_dev(priv_dev->sysdev, request, + usb_endpoint_dir_in(ep->desc)); + + if (ret) + return ret; + + if (!cdns3_ep_run_transfer(priv_ep, request)) + list_add_tail(&request->list, &priv_ep->request_list); + + return ret; +} + +static int cdns3_gadget_ep_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; + struct usb_request *zlp_request; + unsigned long flags; + int ret; + + spin_lock_irqsave(&priv_dev->lock, flags); + ret = __cdns3_gadget_ep_queue(ep, request, gfp_flags); + + if (ret == 0 && request->zero && request->length && + (request->length % ep->maxpacket == 0)) { + zlp_request = cdns3_gadget_ep_alloc_request(ep, GFP_ATOMIC); + zlp_request->buf = priv_dev->zlp_buf; + zlp_request->length = 0; + + dev_dbg(&priv_dev->dev, "Queuing ZLP for endpoint: %s\n", + priv_ep->name); + ret = __cdns3_gadget_ep_queue(ep, zlp_request, gfp_flags); + } + + spin_unlock_irqrestore(&priv_dev->lock, flags); + return ret; +} + +/** + * cdns3_gadget_ep_dequeue Remove request from transfer queue + * @ep: endpoint object associated with request + * @request: request object + * + * Returns 0 on success, error code elsewhere + */ +int cdns3_gadget_ep_dequeue(struct usb_ep *ep, + struct usb_request *request) +{ + struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; + struct usb_request *req, *req_temp; + unsigned long flags; + int ret = 0; + + if (!ep || !request || !ep->desc) + return -EINVAL; + + spin_lock_irqsave(&priv_dev->lock, flags); + dev_dbg(&priv_dev->dev, "Dequeue from %s\n", ep->name); + + cdns3_select_ep(priv_dev, ep->desc->bEndpointAddress); + if (priv_dev->start_gadget) + ret = cdns3_data_flush(priv_ep); + + list_for_each_entry_safe(req, req_temp, &priv_ep->request_list, list) { + if (request == req) { + cdns3_gadget_giveback(priv_ep, + to_cdns3_request(request), + -ECONNRESET); + break; + } + } + + spin_unlock_irqrestore(&priv_dev->lock, flags); + return ret; +} + +/** + * cdns3_gadget_ep_set_halt Sets/clears stall on selected endpoint + * @ep: endpoint object to set/clear stall on + * @value: 1 for set stall, 0 for clear stall + * + * Returns 0 on success, error code elsewhere + */ +int cdns3_gadget_ep_set_halt(struct usb_ep *ep, int value) +{ + struct cdns3_endpoint *priv_ep = ep_to_cdns3_ep(ep); + struct cdns3_device *priv_dev = priv_ep->cdns3_dev; + unsigned long flags; + int ret = 0; + + if (!(priv_ep->flags & EP_ENABLED)) + return -EPERM; + + /* if actual transfer is pending defer setting stall on this endpoint */ + if ((priv_ep->flags & EP_PENDING_REQUEST) && value) { + priv_ep->flags |= EP_STALL; + return 0; + } + + dev_dbg(&priv_dev->dev, "Halt endpoint %s\n", priv_ep->name); + + spin_lock_irqsave(&priv_dev->lock, flags); + + cdns3_select_ep(priv_dev, ep->desc->bEndpointAddress); + if (value) { + cdns3_ep_stall_flush(priv_ep); + } else { + priv_ep->flags &= ~EP_WEDGE; + writel(EP_CMD_CSTALL | EP_CMD_EPRST, &priv_dev->regs->ep_cmd); + + /* wait for EPRST cleared */ + ret = cdns3_handshake(&priv_dev->regs->ep_cmd, + EP_CMD_EPRST, 0, 100); + priv_ep->flags &= ~EP_STALL; + } + + priv_ep->flags &= ~EP_PENDING_REQUEST; + spin_unlock_irqrestore(&priv_dev->lock, flags); + + return ret; +} + +extern const struct usb_ep_ops cdns3_gadget_ep0_ops; + +static const struct usb_ep_ops cdns3_gadget_ep_ops = { + .enable = cdns3_gadget_ep_enable, + .disable = cdns3_gadget_ep_disable, + .alloc_request = cdns3_gadget_ep_alloc_request, + .free_request = cdns3_gadget_ep_free_request, + .queue = cdns3_gadget_ep_queue, + .dequeue = cdns3_gadget_ep_dequeue, + .set_halt = cdns3_gadget_ep_set_halt, + .set_wedge = cdns3_gadget_ep_set_wedge, +}; + /** * cdns3_gadget_get_frame Returns number of actual ITP frame * @gadget: gadget object @@ -365,8 +804,7 @@ static int cdns3_init_ep(struct cdns3_device *priv_dev) usb_ep_set_maxpacket_limit(&priv_ep->endpoint, ENDPOINT_MAX_PACKET_LIMIT); priv_ep->endpoint.max_streams = ENDPOINT_MAX_STREAMS; - //TODO: Add implementation of cdns3_gadget_ep_ops - //priv_ep->endpoint.ops = &cdns3_gadget_ep_ops; + priv_ep->endpoint.ops = &cdns3_gadget_ep_ops; if (ep_dir) priv_ep->endpoint.caps.dir_in = 1; else diff --git a/drivers/usb/cdns3/gadget.h b/drivers/usb/cdns3/gadget.h index 3b0d4d2e4831..a4be288b34cb 100644 --- a/drivers/usb/cdns3/gadget.h +++ b/drivers/usb/cdns3/gadget.h @@ -1072,4 +1072,7 @@ 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); +int cdns3_gadget_ep_set_wedge(struct usb_ep *ep); +int cdns3_gadget_ep_set_halt(struct usb_ep *ep, int value); + #endif /* __LINUX_CDNS3_GADGET */