From mboxrd@z Thu Jan  1 00:00:00 1970
Received: from EUR04-VI1-obe.outbound.protection.outlook.com (EUR04-VI1-obe.outbound.protection.outlook.com [40.107.8.81])
 by mx.groups.io with SMTP id smtpd.web10.14704.1595319458363738271
 for <devel@edk2.groups.io>;
 Tue, 21 Jul 2020 01:17:39 -0700
Authentication-Results: mx.groups.io;
 dkim=pass header.i=@nxp1.onmicrosoft.com header.s=selector2-nxp1-onmicrosoft-com header.b=dIOzlVR8;
 spf=pass (domain: oss.nxp.com, ip: 40.107.8.81, mailfrom: meenakshi.aggarwal@oss.nxp.com)
ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none;
 b=a7xZOJjnf5APjZSzt3zar0C7Iby/DOIQWVSRMKo1iM7ky74SaO2ZESBHW06SvLFYXQubFwHxpBwbvoIf/WAk2WkDyD+QefI35y5E7k3Ti/UBQ2R//7aJGm16++I0+FOT1ZSUMMMGaCvP36g5m4BQHKa4jpjNhfsaLXIlsAKLRLIUCzoeQayj/6gL0R6Q2DwbpaHtBJRVhOPeich6zaUzWs8XTkQnDvTsaobOmxkjcVsCt2c9av9FPAdlhtt8fWCDr31Qz4J8Swc/zUhbZ9H7YxnrQLDcNR2DXFRl+f9vM7Rsa4FoclVX1MUCwCnaENABwB5hR0Vc2SazZySrhJeYww==
ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com;
 s=arcselector9901;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=Th5JPUgTamynB0vgx/Pi8og6vzWdqxGJk9LkgF4MwlY=;
 b=GLrvoaAXBy+Xqq1VlgXc4AIJ5cg09aUd7z8DMKTFIQ3EpaRL3xNqytJpvUVyaeQbl1HXcXpT0ifFaNcoE7kmePaII1/92XmsvsxZEHO37xOgBiO5yvLi7yxRubjCqR5rXhwa/GOPrWx0OObV+RA7EhH7RwpQHOVsXzhIRf2ZjFgClYyVlE7m+mStvOH5VBRXdeJtV8hC8Rfe0hAEijZoCx6i5dGFXkvnMXgW6uVz5tMITzku3hNGpbyJLYzZNhLU0Td9WVxssboQVc5opgknqJCIK9Jp035my13cx2iLDe6CW+7wbV/jbtoxS9GYL0YQITGMfbZ3QBEw2PXf1eIIdA==
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass
 smtp.mailfrom=oss.nxp.com; dmarc=pass action=none header.from=oss.nxp.com;
 dkim=pass header.d=oss.nxp.com; arc=none
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=NXP1.onmicrosoft.com;
 s=selector2-NXP1-onmicrosoft-com;
 h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
 bh=Th5JPUgTamynB0vgx/Pi8og6vzWdqxGJk9LkgF4MwlY=;
 b=dIOzlVR8rpCerGZdFeGrKKowJthAV9bld2K9dN/VGsUOrclnOgRI0j01xPxyZ7UzdiPA5wlcK5h5+Lcmrg7P8osKmOYxYkiX7gQ+/9+vC0AVZdPBCXl2x3jc6aNbA2pQBNN7+RlXwGVr/xeQ3OfmkHLKt489Ifve5AFzcsBPwEg=
Received: from AM7PR04MB6885.eurprd04.prod.outlook.com (2603:10a6:20b:10d::24)
 by AM6PR04MB6101.eurprd04.prod.outlook.com (2603:10a6:20b:b7::18) with
 Microsoft SMTP Server (version=TLS1_2,
 cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3195.17; Tue, 21 Jul
 2020 08:17:29 +0000
Received: from AM7PR04MB6885.eurprd04.prod.outlook.com
 ([fe80::55ce:fc95:27b8:7e9a]) by AM7PR04MB6885.eurprd04.prod.outlook.com
 ([fe80::55ce:fc95:27b8:7e9a%9]) with mapi id 15.20.3195.025; Tue, 21 Jul 2020
 08:17:29 +0000
From: "Meenakshi Aggarwal (OSS)" <meenakshi.aggarwal@oss.nxp.com>
To: Leif Lindholm <leif@nuviainc.com>, Vin Xue <vinxue@outlook.com>
CC: "devel@edk2.groups.io" <devel@edk2.groups.io>, Ard Biesheuvel
	<ard.biesheuvel@arm.com>, "Meenakshi Aggarwal (OSS)"
	<meenakshi.aggarwal@oss.nxp.com>, Pankaj Bansal <pankaj.bansal@nxp.com>,
	Varun Sethi <V.Sethi@nxp.com>
Subject: Re: [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare: Import DesignWare USB3 peripheral driver
Thread-Topic: [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare: Import
 DesignWare USB3 peripheral driver
Thread-Index: AQHWXzdfmZ++sCM6Q0Ww65a9sS4a7Q==
Date: Tue, 21 Jul 2020 08:17:28 +0000
Message-ID: 
 <AM7PR04MB6885E2C76EAF37BED6675F9D8E780@AM7PR04MB6885.eurprd04.prod.outlook.com>
References: 
 <SL2PR03MB4442ED3E414E5FCB952E88E9C57C0@SL2PR03MB4442.apcprd03.prod.outlook.com>
 <20200720174324.GR12303@vanye>
In-Reply-To: <20200720174324.GR12303@vanye>
Accept-Language: en-GB, en-US
X-MS-Has-Attach: 
X-MS-TNEF-Correlator: 
authentication-results: nuviainc.com; dkim=none (message not signed)
 header.d=none;nuviainc.com; dmarc=none action=none header.from=oss.nxp.com;
x-ms-exchange-messagesentrepresentingtype: 1
x-originating-ip: [103.92.42.211]
x-ms-publictraffictype: Email
x-ms-office365-filtering-ht: Tenant
x-ms-office365-filtering-correlation-id: aaee3fe0-801c-498f-9147-08d82d4e8265
x-ms-traffictypediagnostic: AM6PR04MB6101:
x-ms-exchange-sharedmailbox-routingagent-processed: True
x-ms-exchange-transport-forked: True
x-microsoft-antispam-prvs: 
 <AM6PR04MB6101AB7D0E93666F729A4934CF780@AM6PR04MB6101.eurprd04.prod.outlook.com>
x-ms-oob-tlc-oobclassifiers: OLM:9508;
x-ms-exchange-senderadcheck: 1
x-microsoft-antispam: BCL:0;
x-microsoft-antispam-message-info: 
 Q8S2AFDlP1M+FnYnR/TS919TsuPIqu8ETyeZuMancUylUvrMTrryh26/sAiG7GFLyCE/zmtmMwVD3VOx0SQij0AlFhcZZHJn/nmF8TxFVHt1OL0Eesu8UCztXSgykAVTA6a2q7fPd4XfNjRNPXJYdFyLCdfaWUXlarpJHiATE1l7m2cl28+IPOx05vMkwvx4NQI35ROBsEtS6KAmy5JzgFvcrZUBgWgYb0w4vfOEi7OcR7Xb7Gh2pDZ8xGumI10kmkio8LQpIquK+ZpOPO2xqwiuJBPD1xdF95bhAsEQTRnxxlVtBQe1AZ8+ruvI3s2+UjtFFGQwI9pvUJRVbMWzeTQ9Tt3KSZzzrOM4F7tmUuvEt2dZOf6FqfATZTtNuOS7ZUHo4zcfHrywOnndCKM4XAoK4GrZkVwImMTMkph4j9yFeSFNFAumx2QmqY/aFXN5
x-forefront-antispam-report: 
 CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:AM7PR04MB6885.eurprd04.prod.outlook.com;PTR:;CAT:NONE;SFTY:;SFS:(4636009)(39860400002)(366004)(376002)(346002)(396003)(136003)(54906003)(110136005)(316002)(8676002)(55016002)(33656002)(966005)(478600001)(66476007)(16799955002)(9686003)(86362001)(15188155005)(2906002)(66946007)(76116006)(8936002)(64756008)(186003)(26005)(71200400001)(19627235002)(30864003)(52536014)(5660300002)(6506007)(4326008)(83120400003)(7696005)(83380400001)(66556008)(66446008)(53546011)(579004)(569008);DIR:OUT;SFP:1101;
x-ms-exchange-antispam-messagedata: 
 +MiR1DALtgDghzXVZDEc6FeFwvLMl9dkaf26+bXAJauYKlD1LRubNJA4t/BCo9GNoiPx9jXze/DJGlcH9KEjhGunTCaQh9GAA1bXzqMWXJ/Kg/lcZRY43QUKE24WBjEC22oaUhkWqZkAIJmJqvgU1HxUFpNpQ3ZvIo6HVHcvBgnAZMyBQVYRlRsulQtNukdU80q4yfyY1FTjz+RIdgJG7ZYGr3FerJC71En/JAsu0bQvgnnCWPWK62zSWSC1FW3+dN0HB2PQ+yHUySxkBRdpwOrmTZ8W4VRSqIe2VHSPfLWhT6NS8H58DCjcH2OB0RYzI3sgTg3joUUYn+9NNpEuhSq0t3gySyb2iGmtGLguZYgmJULykMUjYqMN3Cqh1TT51EeB6f6YzI0rdgn9LsRuuY5KvCi1I40qPpEcSmJZAlaiN9MbIbagoe9C0v0qMBrZcgSXbOXq0kLIV5cKcpBBRE75eUAlBxNNjSMeT/eCWkVRtUKL/HyB1tEeA30mKPTI
MIME-Version: 1.0
X-OriginatorOrg: oss.nxp.com
X-MS-Exchange-CrossTenant-AuthAs: Internal
X-MS-Exchange-CrossTenant-AuthSource: AM7PR04MB6885.eurprd04.prod.outlook.com
X-MS-Exchange-CrossTenant-Network-Message-Id: aaee3fe0-801c-498f-9147-08d82d4e8265
X-MS-Exchange-CrossTenant-originalarrivaltime: 21 Jul 2020 08:17:28.7709
 (UTC)
X-MS-Exchange-CrossTenant-fromentityheader: Hosted
X-MS-Exchange-CrossTenant-id: 686ea1d3-bc2b-4c6f-a92c-d99c5c301635
X-MS-Exchange-CrossTenant-mailboxtype: HOSTED
X-MS-Exchange-CrossTenant-userprincipalname: VLtyARy4RRs6DoztJcH/G4n7HkBXUIN3oOotwHw3GF1As2ECPhk6C7GBw2YRstCmBbEmQVIE1pILFakRsEytah5aCjAXQq6syhBib91JDa8=
X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM6PR04MB6101
Content-Language: en-US
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

Hi Leif,

I completely agree that we should always try to have one common driver rath=
er platform specific.
But integrating and testing this driver will be a time consuming for me as =
I need to implement a platform specific library/driver to apply erratas
and anything else if needed.

We will keep this work in our bucket list but ,for now, we really appreciat=
e if you please accept our patches as its been years since we are trying to=
 upstream these.
We have gone through a number of review cycles and we do not want to furthe=
r delay our upstreaming process.

Please help with this.

Thanks,
Meenakshi

> -----Original Message-----
> From: Leif Lindholm <leif@nuviainc.com>
> Sent: Monday, July 20, 2020 11:13 PM
> To: Vin Xue <vinxue@outlook.com>
> Cc: devel@edk2.groups.io; Ard Biesheuvel <ard.biesheuvel@arm.com>;
> Meenakshi Aggarwal (OSS) <meenakshi.aggarwal@oss.nxp.com>
> Subject: Re: [edk2-platforms PATCH 1/5] Silicon/Synopsys/DesignWare:
> Import DesignWare USB3 peripheral driver
>=20
> Hi Vin, +Meenakshi
>=20
> Can you clarify the exact origin of this source code please?
> We can only accept bsd+patent code contributions, and these days we
> use only SPDX tags rather than full license statements at top of
> files.
>=20
> Meenakshi - I would certainly prefer to have a single (and
> Arm-functional) driver for DWC3 rather than init-only drivers per
> platform. Can you have a look at this code plese and see if it looks
> feasible to integrate in the NXP platforms?
>=20
> Regards,
>=20
> Leif
>=20
> On Fri, Jul 17, 2020 at 18:01:59 +0800, Vin Xue wrote:
> > Incorporate the driver for the DesignWare USB3 DRD controller device
> > mode (peripheral) that is defined in
> > edk2-platforms/devel-IntelAtomProcessorE3900 branch.
> >
> > The driver is supported by Intel Atom series (Merrifield/BayTrail/
> > CherryTrail/Broxton/ApoloLake/GeminiLake etc.) and Core series
> > (6th Generation and newer).
> >
> > The driver verified on AAEON UP Squared developer board (Intel
> > ApoloLake platform).
> >
> > The driver supports Synopsys DesignWare DWC_usb3 and DWC_usb31 IP.
> >
> > It is better if the driver can be ported to ARM silicon.
> >
> > Cc: Ard Biesheuvel <ard.biesheuvel@arm.com>
> > Cc: Leif Lindholm <leif@nuviainc.com>
> > Signed-off-by: Vin Xue <vinxue@outlook.com>
> > ---
> >  .../Drivers/UsbDeviceDxe/ComponentName.c      |  305 ++
> >  .../Drivers/UsbDeviceDxe/UsbDeviceDxe.c       |  395 ++
> >  .../Drivers/UsbDeviceDxe/UsbDeviceDxe.h       |  159 +
> >  .../Drivers/UsbDeviceDxe/UsbDeviceDxe.inf     |   74 +
> >  .../Drivers/UsbDeviceDxe/UsbDeviceMode.c      | 1489 ++++++
> >  .../Drivers/UsbDeviceDxe/UsbDeviceMode.h      |   39 +
> >  .../Drivers/UsbDeviceDxe/UsbFuncIo.c          | 2221 +++++++++
> >  .../Drivers/UsbDeviceDxe/UsbFuncIo.h          |  234 +
> >  .../Drivers/UsbDeviceDxe/UsbIoNode.c          |  177 +
> >  .../Drivers/UsbDeviceDxe/UsbIoNode.h          |   90 +
> >  .../Drivers/UsbDeviceDxe/XdciCommon.h         |  156 +
> >  .../DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c | 4030
> +++++++++++++++++
> >  .../DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h |  741 +++
> >  .../Drivers/UsbDeviceDxe/XdciDevice.c         |  695 +++
> >  .../Drivers/UsbDeviceDxe/XdciDevice.h         |  184 +
> >  .../Drivers/UsbDeviceDxe/XdciInterface.h      |  241 +
> >  .../Drivers/UsbDeviceDxe/XdciTable.c          |   55 +
> >  .../Drivers/UsbDeviceDxe/XdciUtility.c        |  148 +
> >  .../Drivers/UsbDeviceDxe/XdciUtility.h        |   62 +
> >  .../DesignWare/Include/Library/UsbDeviceLib.h |  323 ++
> >  .../DesignWare/Include/Protocol/EfiUsbFnIo.h  |  430 ++
> >  .../Include/Protocol/UsbDeviceModeProtocol.h  |  104 +
> >  22 files changed, 12352 insertions(+)
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
> >  create mode 100644
> Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h
> >
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
> > new file mode 100644
> > index 0000000000..acb4b6a23d
> > --- /dev/null
> > +++
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/ComponentName.c
> > @@ -0,0 +1,305 @@
> > +/** @file
> > +  Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#include <Uefi.h>
> > +#include <Library/UefiLib.h>
> > +
> > +
> > +/**
> > +  Retrieves a Unicode string that is the user readable name of the dri=
ver.
> > +
> > +  This function retrieves the user readable name of a driver in the fo=
rm of
> a
> > +  Unicode string. If the driver specified by This has a user readable =
name in
> > +  the language specified by Language, then a pointer to the driver nam=
e is
> > +  returned in DriverName, and EFI_SUCCESS is returned. If the driver
> specified
> > +  by This does not support the language specified by Language,
> > +  then EFI_UNSUPPORTED is returned.
> > +
> > +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> > +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> > +
> > +  @param  Language[in]          A pointer to a Null-terminated ASCII s=
tring
> > +                                array indicating the language. This is=
 the
> > +                                language of the driver name that the c=
aller is
> > +                                requesting, and it must match one of t=
he
> > +                                languages specified in SupportedLangua=
ges. The
> > +                                number of languages supported by a dri=
ver is up
> > +                                to the driver writer. Language is spec=
ified
> > +                                in RFC 4646 or ISO 639-2 language code=
 format.
> > +
> > +  @param  DriverName[out]       A pointer to the Unicode string to ret=
urn.
> > +                                This Unicode string is the name of the
> > +                                driver specified by This in the langua=
ge
> > +                                specified by Language.
> > +
> > +  @retval EFI_SUCCESS           The Unicode string for the Driver spec=
ified by
> > +                                This and the language specified by Lan=
guage was
> > +                                returned in DriverName.
> > +
> > +  @retval EFI_INVALID_PARAMETER Language is NULL.
> > +
> > +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> > +
> > +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> > +                                the language specified by Language.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeGetDriverName (
> > +  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
> > +  IN  CHAR8                        *Language,
> > +  OUT CHAR16                       **DriverName
> > +  );
> > +
> > +
> > +/**
> > +  Retrieves a Unicode string that is the user readable name of the
> controller
> > +  that is being managed by a driver.
> > +
> > +  This function retrieves the user readable name of the controller spe=
cified
> by
> > +  ControllerHandle and ChildHandle in the form of a Unicode string. If=
 the
> > +  driver specified by This has a user readable name in the language
> specified by
> > +  Language, then a pointer to the controller name is returned in
> ControllerName,
> > +  and EFI_SUCCESS is returned.  If the driver specified by This is not
> currently
> > +  managing the controller specified by ControllerHandle and ChildHandl=
e,
> > +  then EFI_UNSUPPORTED is returned.  If the driver specified by This d=
oes
> not
> > +  support the language specified by Language, then EFI_UNSUPPORTED is
> returned.
> > +
> > +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> > +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> > +
> > +  @param  ControllerHandle[in]  The handle of a controller that the dr=
iver
> > +                                specified by This is managing.  This h=
andle
> > +                                specifies the controller whose name is=
 to be
> > +                                returned.
> > +
> > +  @param  ChildHandle[in]       The handle of the child controller to
> retrieve
> > +                                the name of.  This is an optional para=
meter that
> > +                                may be NULL.  It will be NULL for devi=
ce
> > +                                drivers.  It will also be NULL for a b=
us drivers
> > +                                that wish to retrieve the name of the =
bus
> > +                                controller.  It will not be NULL for a=
 bus
> > +                                driver that wishes to retrieve the nam=
e of a
> > +                                child controller.
> > +
> > +  @param  Language[in]          A pointer to a Null-terminated ASCII s=
tring
> > +                                array indicating the language.  This i=
s the
> > +                                language of the driver name that the c=
aller is
> > +                                requesting, and it must match one of t=
he
> > +                                languages specified in SupportedLangua=
ges. The
> > +                                number of languages supported by a dri=
ver is up
> > +                                to the driver writer. Language is spec=
ified in
> > +                                RFC 4646 or ISO 639-2 language code fo=
rmat.
> > +
> > +  @param  ControllerName[out]   A pointer to the Unicode string to
> return.
> > +                                This Unicode string is the name of the
> > +                                controller specified by ControllerHand=
le and
> > +                                ChildHandle in the language specified =
by
> > +                                Language from the point of view of the=
 driver
> > +                                specified by This.
> > +
> > +  @retval EFI_SUCCESS           The Unicode string for the user readab=
le
> name in
> > +                                the language specified by Language for=
 the
> > +                                driver specified by This was returned =
in
> > +                                DriverName.
> > +
> > +  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
> > +
> > +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not =
a
> valid
> > +                                EFI_HANDLE.
> > +
> > +  @retval EFI_INVALID_PARAMETER Language is NULL.
> > +
> > +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> > +
> > +  @retval EFI_UNSUPPORTED       The driver specified by This is not
> currently
> > +                                managing the controller specified by
> > +                                ControllerHandle and ChildHandle.
> > +
> > +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> > +                                the language specified by Language.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeGetControllerName (
> > +  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
> > +  IN  EFI_HANDLE                                      ControllerHandle=
,
> > +  IN  EFI_HANDLE                                      ChildHandle     =
   OPTIONAL,
> > +  IN  CHAR8                                           *Language,
> > +  OUT CHAR16                                          **ControllerName
> > +  );
> > +
> > +
> > +//
> > +// EFI Component Name Protocol
> > +//
> > +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_COMPONENT_NAME_PROTOCOL  mUsbDeviceDxeComponentName =3D {
> > +  UsbDeviceDxeGetDriverName,
> > +  UsbDeviceDxeGetControllerName,
> > +  "eng"
> > +};
> > +
> > +//
> > +// EFI Component Name 2 Protocol
> > +//
> > +GLOBAL_REMOVE_IF_UNREFERENCED
> EFI_COMPONENT_NAME2_PROTOCOL mUsbDeviceDxeComponentName2 =3D {
> > +  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)
> UsbDeviceDxeGetDriverName,
> > +  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)
> UsbDeviceDxeGetControllerName,
> > +  "en"
> > +};
> > +
> > +
> > +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE
> mUsbDeviceDxeDriverNameTable[] =3D {
> > +  { "eng;en", L"Usb Device Driver" },
> > +  { NULL , NULL }
> > +};
> > +
> > +/**
> > +  Retrieves a Unicode string that is the user readable name of the dri=
ver.
> > +
> > +  This function retrieves the user readable name of a driver in the fo=
rm of
> a
> > +  Unicode string. If the driver specified by This has a user readable =
name in
> > +  the language specified by Language, then a pointer to the driver nam=
e is
> > +  returned in DriverName, and EFI_SUCCESS is returned. If the driver
> specified
> > +  by This does not support the language specified by Language,
> > +  then EFI_UNSUPPORTED is returned.
> > +
> > +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> > +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> > +
> > +  @param  Language[in]          A pointer to a Null-terminated ASCII s=
tring
> > +                                array indicating the language. This is=
 the
> > +                                language of the driver name that the c=
aller is
> > +                                requesting, and it must match one of t=
he
> > +                                languages specified in SupportedLangua=
ges. The
> > +                                number of languages supported by a dri=
ver is up
> > +                                to the driver writer. Language is spec=
ified
> > +                                in RFC 4646 or ISO 639-2 language code=
 format.
> > +
> > +  @param  DriverName[out]       A pointer to the Unicode string to ret=
urn.
> > +                                This Unicode string is the name of the
> > +                                driver specified by This in the langua=
ge
> > +                                specified by Language.
> > +
> > +  @retval EFI_SUCCESS           The Unicode string for the Driver spec=
ified by
> > +                                This and the language specified by Lan=
guage was
> > +                                returned in DriverName.
> > +
> > +  @retval EFI_INVALID_PARAMETER Language is NULL.
> > +
> > +  @retval EFI_INVALID_PARAMETER DriverName is NULL.
> > +
> > +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> > +                                the language specified by Language.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeGetDriverName (
> > +  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,
> > +  IN  CHAR8                        *Language,
> > +  OUT CHAR16                       **DriverName
> > +  )
> > +{
> > +  return LookupUnicodeString2 (
> > +           Language,
> > +           This->SupportedLanguages,
> > +           mUsbDeviceDxeDriverNameTable,
> > +           DriverName,
> > +           (BOOLEAN)(This =3D=3D &mUsbDeviceDxeComponentName)
> > +           );
> > +}
> > +
> > +/**
> > +  Retrieves a Unicode string that is the user readable name of the
> controller
> > +  that is being managed by a driver.
> > +
> > +  This function retrieves the user readable name of the controller spe=
cified
> by
> > +  ControllerHandle and ChildHandle in the form of a Unicode string. If=
 the
> > +  driver specified by This has a user readable name in the language
> specified by
> > +  Language, then a pointer to the controller name is returned in
> ControllerName,
> > +  and EFI_SUCCESS is returned.  If the driver specified by This is not
> currently
> > +  managing the controller specified by ControllerHandle and ChildHandl=
e,
> > +  then EFI_UNSUPPORTED is returned.  If the driver specified by This d=
oes
> not
> > +  support the language specified by Language, then EFI_UNSUPPORTED is
> returned.
> > +
> > +  @param  This[in]              A pointer to the
> EFI_COMPONENT_NAME2_PROTOCOL or
> > +                                EFI_COMPONENT_NAME_PROTOCOL instance.
> > +
> > +  @param  ControllerHandle[in]  The handle of a controller that the dr=
iver
> > +                                specified by This is managing.  This h=
andle
> > +                                specifies the controller whose name is=
 to be
> > +                                returned.
> > +
> > +  @param  ChildHandle[in]       The handle of the child controller to
> retrieve
> > +                                the name of.  This is an optional para=
meter that
> > +                                may be NULL.  It will be NULL for devi=
ce
> > +                                drivers.  It will also be NULL for a b=
us drivers
> > +                                that wish to retrieve the name of the =
bus
> > +                                controller.  It will not be NULL for a=
 bus
> > +                                driver that wishes to retrieve the nam=
e of a
> > +                                child controller.
> > +
> > +  @param  Language[in]          A pointer to a Null-terminated ASCII s=
tring
> > +                                array indicating the language.  This i=
s the
> > +                                language of the driver name that the c=
aller is
> > +                                requesting, and it must match one of t=
he
> > +                                languages specified in SupportedLangua=
ges. The
> > +                                number of languages supported by a dri=
ver is up
> > +                                to the driver writer. Language is spec=
ified in
> > +                                RFC 4646 or ISO 639-2 language code fo=
rmat.
> > +
> > +  @param  ControllerName[out]   A pointer to the Unicode string to
> return.
> > +                                This Unicode string is the name of the
> > +                                controller specified by ControllerHand=
le and
> > +                                ChildHandle in the language specified =
by
> > +                                Language from the point of view of the=
 driver
> > +                                specified by This.
> > +
> > +  @retval EFI_SUCCESS           The Unicode string for the user readab=
le
> name in
> > +                                the language specified by Language for=
 the
> > +                                driver specified by This was returned =
in
> > +                                DriverName.
> > +
> > +  @retval EFI_INVALID_PARAMETER ControllerHandle is not a valid
> EFI_HANDLE.
> > +
> > +  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not =
a
> valid
> > +                                EFI_HANDLE.
> > +
> > +  @retval EFI_INVALID_PARAMETER Language is NULL.
> > +
> > +  @retval EFI_INVALID_PARAMETER ControllerName is NULL.
> > +
> > +  @retval EFI_UNSUPPORTED       The driver specified by This is not
> currently
> > +                                managing the controller specified by
> > +                                ControllerHandle and ChildHandle.
> > +
> > +  @retval EFI_UNSUPPORTED       The driver specified by This does not
> support
> > +                                the language specified by Language.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeGetControllerName (
> > +  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,
> > +  IN  EFI_HANDLE                                      ControllerHandle=
,
> > +  IN  EFI_HANDLE                                      ChildHandle     =
   OPTIONAL,
> > +  IN  CHAR8                                           *Language,
> > +  OUT CHAR16                                          **ControllerName
> > +  )
> > +{
> > +  return EFI_UNSUPPORTED;
> > +}
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
> > new file mode 100644
> > index 0000000000..2732cc2e31
> > --- /dev/null
> > +++
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.c
> > @@ -0,0 +1,395 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#include "UsbDeviceDxe.h"
> > +#include <Guid/EventGroup.h>
> > +
> > +EFI_DRIVER_BINDING_PROTOCOL mUsbDeviceDxeDriverBinding =3D {
> > +  UsbDeviceDxeDriverSupported,
> > +  UsbDeviceDxeDriverStart,
> > +  UsbDeviceDxeDriverStop,
> > +  0x1,
> > +  NULL,
> > +  NULL
> > +};
> > +
> > +
> > +
> > +VOID
> > +EFIAPI
> > +PlatformSpecificInit (
> > +  VOID
> > +  )
> > +{
> > +  UINTN                 XhciPciMmBase;
> > +  EFI_PHYSICAL_ADDRESS  XhciMemBaseAddress;
> > +
> > +  XhciPciMmBase   =3D MmPciAddress (
> > +                      0,
> > +                      0,
> > +                      PCI_DEVICE_NUMBER_XHCI,
> > +                      PCI_FUNCTION_NUMBER_XHCI,
> > +                      0
> > +                      );
> > +
> > +
> > +  XhciMemBaseAddress =3D MmioRead32 ((UINTN) (XhciPciMmBase +
> R_XHCI_MEM_BASE)) & B_XHCI_MEM_BASE_BA;
> > +  DEBUG ((DEBUG_INFO, "XhciPciMmBase=3D%x,
> XhciMemBaseAddress=3D%x\n", XhciPciMmBase, XhciMemBaseAddress));
> > +
> > +  MmioWrite32 ((UINTN)(XhciMemBaseAddress +
> R_XHCI_MEM_DUAL_ROLE_CFG0), 0x1310800);
> > +
> > +  PmicUSBSwitchControl (TRUE);//conduction USB switch.
> > +  return;
> > +}
> > +
> > +
> > +VOID
> > +EFIAPI
> > +UsbDeviceDxeExitBootService (
> > +  EFI_EVENT  Event,
> > +  VOID       *Context
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT  *UsbXdciDevContext;
> > +
> > +  UsbXdciDevContext =3D (USB_XDCI_DEV_CONTEXT *) Context;
> > +  DEBUG ((EFI_D_INFO, "UsbDeviceDxeExitBootService enter\n"));
> > +
> > +  if (UsbXdciDevContext->XdciPollTimer !=3D NULL) {
> > +    gBS->SetTimer (UsbXdciDevContext->XdciPollTimer, TimerCancel, 0);
> > +    gBS->CloseEvent (UsbXdciDevContext->XdciPollTimer);
> > +    UsbXdciDevContext->XdciPollTimer =3D NULL;
> > +    }
> > +
> > +  return;
> > +}
> > +
> > +/**
> > +  The USB bus driver entry pointer.
> > +
> > +  @param ImageHandle       The driver image handle.
> > +  @param SystemTable       The system table.
> > +
> > +  @return EFI_SUCCESS      The component name protocol is installed.
> > +  @return Others           Failed to init the usb driver.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeEntryPoint (
> > +  IN EFI_HANDLE           ImageHandle,
> > +  IN EFI_SYSTEM_TABLE     *SystemTable
> > +  )
> > +{
> > +  return EfiLibInstallDriverBindingComponentName2 (
> > +           ImageHandle,
> > +           SystemTable,
> > +           &mUsbDeviceDxeDriverBinding,
> > +           ImageHandle,
> > +           &mUsbDeviceDxeComponentName,
> > +           &mUsbDeviceDxeComponentName2
> > +           );
> > +}
> > +
> > +/**
> > +  Check whether USB bus driver support this device.
> > +
> > +  @param  This                   The USB bus driver binding protocol.
> > +  @param  Controller             The controller handle to check.
> > +  @param  RemainingDevicePath    The remaining device path.
> > +
> > +  @retval EFI_SUCCESS            The bus supports this controller.
> > +  @retval EFI_UNSUPPORTED        This device isn't supported.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeDriverSupported (
> > +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> > +  IN EFI_HANDLE                   Controller,
> > +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> > +  )
> > +{
> > +  EFI_STATUS                Status;
> > +  EFI_PCI_IO_PROTOCOL       *PciIo;
> > +  USB_CLASSC                UsbClassCReg;
> > +
> > +
> > +  Status =3D gBS->OpenProtocol (
> > +                  Controller,
> > +                  &gEfiPciIoProtocolGuid,
> > +                  (VOID **) &PciIo,
> > +                  This->DriverBindingHandle,
> > +                  Controller,
> > +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> > +                  );
> > +
> > +  if (EFI_ERROR (Status)) {
> > +    return EFI_UNSUPPORTED;
> > +  }
> > +
> > +  Status =3D PciIo->Pci.Read (
> > +                        PciIo,
> > +                        EfiPciIoWidthUint8,
> > +                        PCI_CLASSCODE_OFFSET,
> > +                        sizeof (USB_CLASSC) / sizeof (UINT8),
> > +                        &UsbClassCReg
> > +                        );
> > +
> > +  if (EFI_ERROR (Status)) {
> > +    Status =3D EFI_UNSUPPORTED;
> > +    goto ON_EXIT;
> > +  }
> > +
> > +  //
> > +  // Test whether the controller belongs to USB device type
> > +  //
> > +  // 0x0C03FE / 0x0C0380
> > +  //
> > +  if ((UsbClassCReg.BaseCode !=3D PCI_CLASS_SERIAL) ||
> > +      (UsbClassCReg.SubClassCode !=3D PCI_CLASS_SERIAL_USB) ||
> > +      ((UsbClassCReg.ProgInterface !=3D PCI_IF_USBDEV) &&
> (UsbClassCReg.ProgInterface !=3D 0x80))) {
> > +    Status =3D EFI_UNSUPPORTED;
> > +  }
> > +
> > +ON_EXIT:
> > +  gBS->CloseProtocol (
> > +         Controller,
> > +         &gEfiPciIoProtocolGuid,
> > +         This->DriverBindingHandle,
> > +         Controller
> > +         );
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Start to process the controller.
> > +
> > +  @param  This                   The USB bus driver binding instance.
> > +  @param  Controller             The controller to check.
> > +  @param  RemainingDevicePath    The remaining device patch.
> > +
> > +  @retval EFI_SUCCESS            The controller is controlled by the u=
sb bus.
> > +  @retval EFI_ALREADY_STARTED    The controller is already controlled =
by
> the usb
> > +                                 bus.
> > +  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeDriverStart (
> > +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> > +  IN EFI_HANDLE                   Controller,
> > +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> > +  )
> > +{
> > +  EFI_STATUS            Status;
> > +  USB_XDCI_DEV_CONTEXT  *UsbXdciDevContext;
> > +  EFI_PCI_IO_PROTOCOL   *PciIo;
> > +  EFI_EVENT             ExitBootServicesEvent;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbFunIoEntryPoint - Entry\n"));
> > +
> > +  UsbXdciDevContext =3D NULL;
> > +
> > +  //
> > +  // Provide protocol interface
> > +  //
> > +  //
> > +  // Get the PCI I/O Protocol on PciHandle
> > +  //
> > +  Status =3D gBS->OpenProtocol (
> > +                  Controller,
> > +                  &gEfiPciIoProtocolGuid,
> > +                  (VOID **) &PciIo,
> > +                  This->DriverBindingHandle,
> > +                  Controller,
> > +                  EFI_OPEN_PROTOCOL_BY_DRIVER
> > +                  );
> > +
> > +  if (EFI_ERROR (Status)) {
> > +    goto ErrorExit;
> > +  }
> > +
> > +  UsbXdciDevContext =3D AllocateZeroPool (sizeof
> (USB_XDCI_DEV_CONTEXT));
> > +  if (UsbXdciDevContext =3D=3D NULL) {
> > +    Status =3D EFI_OUT_OF_RESOURCES;
> > +    goto ErrorExit;
> > +  }
> > +
> > +  //
> > +  // Initialize the driver context
> > +  //
> > +  UsbXdciDevContext->StartUpController =3D FALSE;
> > +  UsbXdciDevContext->XdciHandle =3D Controller;
> > +  UsbXdciDevContext->FirstNodePtr =3D NULL;
> > +  UsbXdciDevContext->Signature =3D EFI_USB_DEV_SIGNATURE;
> > +
> > +  PciIo->Pci.Read (
> > +               PciIo,
> > +               EfiPciIoWidthUint32,
> > +               R_OTG_BAR0,
> > +               1,
> > +               &UsbXdciDevContext->XdciMmioBarAddr
> > +               );
> > +
> > +  UsbXdciDevContext->XdciMmioBarAddr &=3D B_OTG_BAR0_BA;
> > +  DEBUG ((USB_FUIO_DEBUG_INFO, "USB DEV mode IO addr 0x%08x\n",
> UsbXdciDevContext->XdciMmioBarAddr));
> > +
> > +  CopyMem (
> > +    &(UsbXdciDevContext->UsbFunIoProtocol),
> > +    &mUsbFunIoProtocol,
> > +    sizeof (EFI_USBFN_IO_PROTOCOL)
> > +    );
> > +
> > +  CopyMem (
> > +    &(UsbXdciDevContext->UsbDevModeProtocol),
> > +    &mUsbDeviceModeProtocol,
> > +    sizeof (EFI_USB_DEVICE_MODE_PROTOCOL)
> > +    );
> > +
> > +  Status =3D gBS->CreateEventEx (
> > +                  EVT_NOTIFY_SIGNAL,
> > +                  TPL_NOTIFY,
> > +                  UsbDeviceDxeExitBootService,
> > +                  UsbXdciDevContext,
> > +                  &gEfiEventExitBootServicesGuid,
> > +                  &ExitBootServicesEvent
> > +                  );
> > +  if (EFI_ERROR (Status)) {
> > +    goto ErrorExit;
> > +  }
> > +
> > +  Status =3D gBS->InstallMultipleProtocolInterfaces (
> > +                  &UsbXdciDevContext->XdciHandle,
> > +                  &gEfiUsbFnIoProtocolGuid,
> > +                  &UsbXdciDevContext->UsbFunIoProtocol,
> > +                  &gEfiUsbDeviceModeProtocolGuid,
> > +                  &UsbXdciDevContext->UsbDevModeProtocol,
> > +                  NULL
> > +                  );
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((USB_FUIO_DEBUG_ERROR, "ERROR - Failed to install upper
> protocol, Status: %r\n", Status));
> > +    goto ErrorExit;
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "Done - install upper protocol
> complete\n"));
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbFunIoEntryPoint - Exit\n"));
> > +  return Status;
> > +
> > +ErrorExit:
> > +  gBS->CloseProtocol (
> > +         Controller,
> > +         &gEfiPciIoProtocolGuid,
> > +         This->DriverBindingHandle,
> > +         Controller
> > +         );
> > +
> > +  if (UsbXdciDevContext !=3D NULL) {
> > +    if (UsbXdciDevContext->XdciPollTimer !=3D NULL) {
> > +      gBS->CloseEvent (UsbXdciDevContext->XdciPollTimer);
> > +      UsbXdciDevContext->XdciPollTimer =3D NULL;
> > +    }
> > +    FreePool (UsbXdciDevContext);
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_ERROR, "ERROR - UsbFunIoEntryPoint -
> Exit\n"));
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Stop handle the controller by this USB bus driver.
> > +
> > +  @param  This                   The USB bus driver binding protocol.
> > +  @param  Controller             The controller to release.
> > +  @param  NumberOfChildren       The child of USB bus that opened
> controller
> > +                                 BY_CHILD.
> > +  @param  ChildHandleBuffer      The array of child handle.
> > +
> > +  @retval EFI_SUCCESS            The controller or children are stoppe=
d.
> > +  @retval EFI_DEVICE_ERROR       Failed to stop the driver.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeDriverStop (
> > +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> > +  IN EFI_HANDLE                   Controller,
> > +  IN UINTN                        NumberOfChildren,
> > +  IN EFI_HANDLE                   *ChildHandleBuffer
> > +  )
> > +{
> > +  EFI_USBFN_IO_PROTOCOL           *UsbFunIoProtocol;
> > +  EFI_STATUS                      Status;
> > +  USB_XDCI_DEV_CONTEXT            *UsbXdciDevContext;
> > +
> > +
> > +  //
> > +  // Locate USB_BUS for the current host controller
> > +  //
> > +  Status =3D gBS->OpenProtocol (
> > +                  Controller,
> > +                  &gEfiUsbFnIoProtocolGuid,
> > +                  (VOID **)&UsbFunIoProtocol,
> > +                  This->DriverBindingHandle,
> > +                  Controller,
> > +                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
> > +                  );
> > +
> > +
> > +  if (EFI_ERROR (Status)) {
> > +    return Status;
> > +  }
> > +
> > +  UsbXdciDevContext =3D USBFUIO_CONTEXT_FROM_PROTOCOL
> (UsbFunIoProtocol);
> > +
> > +  //
> > +  // free pool
> > +  //
> > +  while (UsbXdciDevContext->FirstNodePtr !=3D NULL) {
> > +    RemoveNode (UsbFunIoProtocol, UsbXdciDevContext->FirstNodePtr);
> > +  }
> > +
> > +  Status =3D gBS->UninstallMultipleProtocolInterfaces (
> > +                  UsbXdciDevContext->XdciHandle,
> > +                  &gEfiUsbFnIoProtocolGuid,
> > +                  &UsbXdciDevContext->UsbFunIoProtocol,
> > +                  &gEfiUsbDeviceModeProtocolGuid,
> > +                  &UsbXdciDevContext->UsbDevModeProtocol,
> > +                  NULL
> > +                  );
> > +
> > +  if (UsbXdciDevContext->StartUpController =3D=3D TRUE) {
> > +    Status =3D StopController (UsbFunIoProtocol);
> > +    DEBUG ((USB_FUIO_DEBUG_INFO, "USB DEV mode STOP
> UsbFnDeInitDevice %r\n", Status));
> > +  }
> > +
> > +  if (UsbXdciDevContext->XdciPollTimer !=3D NULL) {
> > +    gBS->SetTimer (UsbXdciDevContext->XdciPollTimer, TimerCancel, 0);
> > +    gBS->CloseEvent (UsbXdciDevContext->XdciPollTimer);
> > +    UsbXdciDevContext->XdciPollTimer =3D NULL;
> > +  }
> > +
> > +  gBS->CloseProtocol (
> > +         Controller,
> > +         &gEfiPciIoProtocolGuid,
> > +         This->DriverBindingHandle,
> > +         Controller
> > +         );
> > +
> > +  FreePool (UsbXdciDevContext);
> > +  return EFI_SUCCESS;
> > +}
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
> > new file mode 100644
> > index 0000000000..36620f9b12
> > --- /dev/null
> > +++
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.h
> > @@ -0,0 +1,159 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#ifndef __USB_DEVICE_DXE_H__
> > +#define __USB_DEVICE_DXE_H__
> > +
> > +#include <Uefi.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DevicePathLib.h>
> > +#include <Library/DriverLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Library/IoLib.h>
> > +#include <Protocol/EfiUsbFnIo.h>
> > +#include <Protocol/UsbDeviceModeProtocol.h>
> > +#include <PlatformBaseAddresses.h>
> > +#include <ScAccess.h>
> > +#include "UsbFuncIo.h"
> > +#include "UsbDeviceMode.h"
> > +
> > +
> > +#define PCI_IF_USBDEV                      0xFE
> > +
> > +#define EFI_USB_DEV_SIGNATURE              0x55534244 //"USBD"
> > +#define USBFUIO_CONTEXT_FROM_PROTOCOL(a)   CR (a,
> USB_XDCI_DEV_CONTEXT, UsbFunIoProtocol, EFI_USB_DEV_SIGNATURE)
> > +#define USBUSBD_CONTEXT_FROM_PROTOCOL(a)   CR (a,
> USB_XDCI_DEV_CONTEXT, UsbDevModeProtocol, EFI_USB_DEV_SIGNATURE)
> > +
> > +
> > +typedef struct _USB_FUIO_EVENT_NODE   USB_FUIO_EVENT_NODE;
> > +
> > +#pragma pack(1)
> > +struct _USB_FUIO_EVENT_NODE{
> > +  EFI_USBFN_MESSAGE            Message;
> > +  UINTN                        PayloadSize;
> > +  EFI_USBFN_MESSAGE_PAYLOAD    Payload;
> > +  USB_FUIO_EVENT_NODE          *Nextptr;
> > +};
> > +
> > +typedef struct {
> > +  UINTN                         Signature;
> > +  UINTN                         XdciMmioBarAddr;
> > +  EFI_HANDLE                    XdciHandle;
> > +  //
> > +  // Timer to handle EndPoint event periodically.
> > +  //
> > +  EFI_EVENT                     XdciPollTimer;
> > +  EFI_USB_DEVICE_MODE_PROTOCOL  UsbDevModeProtocol;
> > +  EFI_USBFN_IO_PROTOCOL         UsbFunIoProtocol;
> > +
> > +  //
> > +  // Structure members used by UsbFunIoProtocol.
> > +  //
> > +  USB_MEM_NODE                  *FirstNodePtr;
> > +  EFI_USB_DEVICE_INFO           *DevInfoPtr;
> > +  EFI_USB_CONFIG_INFO           IndexPtrConfig;
> > +  EFI_USB_INTERFACE_INFO        IndexPtrInteface;
> > +  USB_DEVICE_ENDPOINT_INFO      IndexPtrInEp;
> > +  USB_DEVICE_ENDPOINT_INFO      IndexPtrOutEp;
> > +  XDCI_CORE_HANDLE              *XdciDrvIfHandle;
> > +  USB_DEV_CORE                  *DrvCore;
> > +  UINT16                        VendorId;
> > +  UINT16                        DeviceId;
> > +  USBD_EP_XFER_REC
> EndPointXferRec[DWC_XDCI_MAX_ENDPOINTS];
> > +  BOOLEAN                       StartUpController;
> > +  BOOLEAN                       DevReConnect;
> > +  BOOLEAN                       DevResetFlag;
> > +  EFI_EVENT                     TimerEvent;
> > +  USB_FUIO_EVENT_NODE           *EventNodePtr;
> > +  //
> > +  // Following structure members are used by UsbDevModeProtocol.
> > +  //
> > +
> > +} USB_XDCI_DEV_CONTEXT;
> > +#pragma pack()
> > +
> > +
> > +
> > +/**
> > +  Check whether USB bus driver support this device.
> > +
> > +  @param  This                   The USB bus driver binding protocol.
> > +  @param  Controller             The controller handle to check.
> > +  @param  RemainingDevicePath    The remaining device path.
> > +
> > +  @retval EFI_SUCCESS            The bus supports this controller.
> > +  @retval EFI_UNSUPPORTED        This device isn't supported.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeDriverSupported (
> > +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> > +  IN EFI_HANDLE                   Controller,
> > +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> > +  );
> > +
> > +/**
> > +  Start to process the controller.
> > +
> > +  @param  This                   The USB bus driver binding instance.
> > +  @param  Controller             The controller to check.
> > +  @param  RemainingDevicePath    The remaining device patch.
> > +
> > +  @retval EFI_SUCCESS            The controller is controlled by the u=
sb bus.
> > +  @retval EFI_ALREADY_STARTED    The controller is already controlled =
by
> the usb
> > +                                 bus.
> > +  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resources.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeDriverStart (
> > +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> > +  IN EFI_HANDLE                   Controller,
> > +  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath
> > +  );
> > +
> > +/**
> > +  Stop handle the controller by this USB bus driver.
> > +
> > +  @param  This                   The USB bus driver binding protocol.
> > +  @param  Controller             The controller to release.
> > +  @param  NumberOfChildren       The child of USB bus that opened
> controller
> > +                                 BY_CHILD.
> > +  @param  ChildHandleBuffer      The array of child handle.
> > +
> > +  @retval EFI_SUCCESS            The controller or children are stoppe=
d.
> > +  @retval EFI_DEVICE_ERROR       Failed to stop the driver.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDxeDriverStop (
> > +  IN EFI_DRIVER_BINDING_PROTOCOL  *This,
> > +  IN EFI_HANDLE                   Controller,
> > +  IN UINTN                        NumberOfChildren,
> > +  IN EFI_HANDLE                   *ChildHandleBuffer
> > +  );
> > +
> > +VOID
> > +EFIAPI
> > +PlatformSpecificInit (
> > +  VOID
> > +  );
> > +
> > +extern EFI_COMPONENT_NAME_PROTOCOL
> mUsbDeviceDxeComponentName;
> > +extern EFI_COMPONENT_NAME2_PROTOCOL
> mUsbDeviceDxeComponentName2;
> > +
> > +#endif
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
> > new file mode 100644
> > index 0000000000..acf5021327
> > --- /dev/null
> > +++
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceDxe.inf
> > @@ -0,0 +1,74 @@
> > +## @file
> > +#
> > +#  Copyright (c) 2008 - 2017, Intel Corporation. All rights reserved.<=
BR>
> > +#
> > +#  This program and the accompanying materials
> > +#  are licensed and made available under the terms and conditions of t=
he
> BSD License
> > +#  which accompanies this distribution. The full text of the license m=
ay be
> found at
> > +#  http://opensource.org/licenses/bsd-license.php
> > +#
> > +#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +#
> > +##
> > +
> > +[Defines]
> > +  INF_VERSION                    =3D 0x00010005
> > +  BASE_NAME                      =3D UsbDeviceDxe
> > +  FILE_GUID                      =3D 42CF2D4A-78B4-4B80-80F9-96A83A630=
D70
> > +  MODULE_TYPE                    =3D UEFI_DRIVER
> > +  VERSION_STRING                 =3D 1.0
> > +  ENTRY_POINT                    =3D UsbDeviceDxeEntryPoint
> > +
> > +#
> > +# The following information is for reference only and not required by =
the
> build tools.
> > +#
> > +#  VALID_ARCHITECTURES           =3D IA32 X64
> > +#
> > +
> > +[Sources.common]
> > +  UsbDeviceDxe.c
> > +  UsbFuncIo.c
> > +  UsbIoNode.c
> > +  ComponentName.c
> > +  UsbDeviceMode.c
> > +  XdciDevice.c
> > +  XdciDWC.c
> > +  XdciTable.c
> > +  XdciUtility.c
> > +
> > +[Packages]
> > +  MdePkg/MdePkg.dec
> > +  BroxtonSiPkg/BroxtonSiPkg.dec
> > +  BroxtonPlatformPkg/PlatformPkg.dec
> > +
> > +[LibraryClasses]
> > +  BaseMemoryLib
> > +  DebugLib
> > +  DevicePathLib
> > +  MemoryAllocationLib
> > +  TimerLib
> > +  PcdLib
> > +  UefiBootServicesTableLib
> > +  UefiDriverEntryPoint
> > +  UefiLib
> > +  PmicLib
> > +
> > +[Protocols]
> > +  gEfiUsbDeviceModeProtocolGuid
> > +  gEfiUsbFnIoProtocolGuid
> > +  gEfiPciIoProtocolGuid
> > +
> > +[Pcd]
> > +  gEfiMdePkgTokenSpaceGuid.PcdPciExpressBaseAddress
> > +
> > +[Guids]
> > +  gEfiEventExitBootServicesGuid
> > +
> > +#[BuildOptions]
> > +#  MSFT:*_*_*_CC_FLAGS =3D /D SUPPORT_SUPER_SPEED
> > +#  GCC:*_*_*_CC_FLAGS =3D -DSUPPORT_SUPER_SPEED
> > +
> > +[Depex]
> > +  TRUE
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
> > new file mode 100644
> > index 0000000000..48a37a37fb
> > --- /dev/null
> > +++
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.c
> > @@ -0,0 +1,1489 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#include <Base.h>
> > +#include <Library/BaseLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/IoLib.h>
> > +#include <PlatformBaseAddresses.h>
> > +#include <ScAccess.h>
> > +#include "XdciUtility.h"
> > +#include "UsbDeviceMode.h"
> > +#include "UsbDeviceDxe.h"
> > +
> > +//
> > +// Global USBD driver object. This is the main private driver object
> > +// that contains all data needed for this driver to operate.
> > +//
> > +USB_DEVICE_DRIVER_OBJ mDrvObj;
> > +
> > +//
> > +// Global data IO transaction request object
> > +//
> > +USB_DEVICE_IO_REQ  mCtrlIoReq =3D {
> > +  //
> > +  // IO information containing the Buffer and data size
> > +  //
> > +  {
> > +    NULL,
> > +    0,
> > +  },
> > +  //
> > +  // Note: This object is used for Control Ep transfers only
> > +  // therefore the endpoint info must always be NULL
> > +  //
> > +  {
> > +    NULL,
> > +    NULL,
> > +  }
> > +};
> > +
> > +//
> > +// global flag to signal device event processing loop to run/stop
> > +//
> > +BOOLEAN mXdciRun =3D FALSE;
> > +
> > +STATIC VOID
> > +XhciSwitchSwid(BOOLEAN enable)
> > +{
> > +  UINTN                             XhciPciMmBase;
> > +  EFI_PHYSICAL_ADDRESS              XhciMemBaseAddress;
> > +  UINT32                            DualRoleCfg0;
> > +  UINT32                            DualRoleCfg1;
> > +
> > +  XhciPciMmBase =3D MmPciAddress (0, 0, PCI_DEVICE_NUMBER_XHCI,
> PCI_FUNCTION_NUMBER_XHCI, 0);
> > +  XhciMemBaseAddress =3D MmioRead32 ((UINTN) (XhciPciMmBase +
> R_XHCI_MEM_BASE)) & B_XHCI_MEM_BASE_BA;
> > +  DEBUG ((DEBUG_INFO, "XhciPciMmBase=3D%x,
> XhciMemBaseAddress=3D%x\n", XhciPciMmBase, XhciMemBaseAddress));
> > +
> > +  DualRoleCfg0 =3D MmioRead32 ((UINTN)(XhciMemBaseAddress +
> R_XHCI_MEM_DUAL_ROLE_CFG0));
> > +  if (enable) {
> > +    DualRoleCfg0 =3D DualRoleCfg0 | (1 << 24) | (1 << 21) | (1 << 20);
> > +    DEBUG ((DEBUG_INFO, "DualRoleCfg0 : Set SW ID : 0x%x \n",
> DualRoleCfg0));
> > +  }
> > +  else {
> > +    DualRoleCfg0 =3D DualRoleCfg0 & ~(1 << 24) & ~(1 << 21) & ~(1 << 2=
0);
> > +    DEBUG ((DEBUG_INFO, "DualRoleCfg0 : Clear SW ID : 0x%x \n",
> DualRoleCfg0));
> > +  }
> > +  MmioWrite32 ((UINTN)(XhciMemBaseAddress +
> R_XHCI_MEM_DUAL_ROLE_CFG0), DualRoleCfg0);
> > +
> > +  DualRoleCfg1 =3D MmioRead32 ((UINTN)(XhciMemBaseAddress +
> R_XHCI_MEM_DUAL_ROLE_CFG1));
> > +  DEBUG ((DEBUG_INFO, "DualRoleCfg1 : 0x%x \n", DualRoleCfg1));
> > +}
> > +
> > +VOID
> > +EFIAPI
> > +UsbdMonitorEvents (
> > +  IN EFI_EVENT            Event,
> > +  IN VOID                 *Context
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT    *XdciDevContext;
> > +  UINT32                  EventCount;
> > +  UINT32                  PreEventCount;
> > +  UINT32                  LoopCount;
> > +
> > +  XdciDevContext =3D (USB_XDCI_DEV_CONTEXT *) Context;
> > +  EventCount =3D UsbRegRead ((UINT32)XdciDevContext->XdciMmioBarAddr,
> DWC_XDCI_EVNTCOUNT_REG (0));
> > +  if (EventCount =3D=3D 0) {
> > +    return;
> > +  }
> > +
> > +  LoopCount =3D 0;
> > +  PreEventCount =3D EventCount;
> > +  while (EventCount !=3D 0) {
> > +    if (UsbDeviceIsrRoutineTimerBased (mDrvObj.XdciDrvObj) !=3D
> EFI_SUCCESS) {
> > +      DEBUG ((DEBUG_INFO, "UsbDeviceRun() - Failed to execute event
> ISR\n"));
> > +    }
> > +    EventCount =3D UsbRegRead ((UINT32)XdciDevContext-
> >XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG (0));
> > +    if (PreEventCount =3D=3D EventCount) {
> > +      LoopCount++;
> > +      if (LoopCount >=3D 5) {
> > +        DEBUG ((DEBUG_INFO, "USB is working on a long event...\n"));
> > +        break;
> > +      }
> > +    } else {
> > +      LoopCount =3D 0;
> > +    }
> > +  }
> > +
> > +  return;
> > +}
> > +
> > +/**
> > +  Initializes the XDCI core
> > +
> > +  @param MmioBar       Address of MMIO BAR
> > +  @param XdciHndl      Double pointer to for XDCI layer to set as an
> > +                       opaque handle to the driver to be used in subse=
quent
> > +                       interactions with the XDCI layer.
> > +
> > +  @return EFI_SUCCESS if successfully initialized XDCI, EFI_DEVICE_ERR=
OR
> otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdInit (
> > +  IN UINT32    MmioBar,
> > +  IN VOID      **XdciHndl
> > +  )
> > +{
> > +  EFI_STATUS               Status =3D EFI_DEVICE_ERROR;
> > +  USB_DEV_CONFIG_PARAMS    ConfigParams;
> > +
> > +  XhciSwitchSwid(TRUE);
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdInit start\n"));
> > +  ConfigParams.ControllerId =3D USB_ID_DWC_XDCI;
> > +  ConfigParams.BaseAddress  =3D MmioBar;
> > +  ConfigParams.Role =3D USB_ROLE_DEVICE;
> > +  ConfigParams.Speed =3D USB_SPEED_SUPER;
> > +
> > +  Status =3D UsbDeviceInit (&ConfigParams, XdciHndl);
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdInit status is %x\n", Status));
> > +  DEBUG ((DEBUG_INFO, "ConfigParams.BaseAddress 0x%x\n",
> ConfigParams.BaseAddress));
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Copies relevant endpoint data from standard USB endpoint descriptors
> > +  to the usbEpInfo structure used by the XDCI
> > +
> > +  @param EpDest   destination structure
> > +  @param EpSrc    source structure
> > +
> > +  @return VOID
> > +
> > +**/
> > +VOID
> > +UsbdSetEpInfo (
> > +  IN USB_EP_INFO                 *EpDest,
> > +  IN USB_DEVICE_ENDPOINT_INFO    *EpSrc
> > +  )
> > +{
> > +  EFI_USB_ENDPOINT_DESCRIPTOR              *EpDesc =3D NULL;
> > +  EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpCompDesc =3D NULL;
> > +
> > +  //
> > +  // start by clearing all data in the destination
> > +  //
> > +  SetMem (EpDest, sizeof(USB_EP_INFO), 0);
> > +  EpDesc =3D EpSrc->EndpointDesc;
> > +  EpCompDesc =3D EpSrc->EndpointCompDesc;
> > +
> > +  if (EpDesc !=3D NULL) {
> > +    EpDest->EpNum =3D EpDesc->EndpointAddress & 0x0F; //Bits 0-3 are e=
p
> num
> > +    EpDest->EpDir =3D ((EpDesc->EndpointAddress & USB_ENDPOINT_DIR_IN)
> > 0) ? UsbEpDirIn : UsbEpDirOut;
> > +    EpDest->EpType =3D EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK;
> > +    EpDest->MaxPktSize =3D EpDesc->MaxPacketSize;
> > +    EpDest->Interval =3D EpDesc->Interval;
> > +  }
> > +  if (EpCompDesc !=3D NULL) {
> > +    EpDest->MaxStreams =3D EpCompDesc->Attributes &
> USB_EP_BULK_BM_ATTR_MASK;
> > +    EpDest->BurstSize =3D EpCompDesc->MaxBurst;
> > +    EpDest->Mult =3D EpCompDesc->BytesPerInterval;
> > +  }
> > +
> > +  return;
> > +}
> > +
> > +
> > +/**
> > +  Initializes the given endpoint
> > +
> > +  @param XdciHndl  Pointer (handle) to the XDCI driver object
> > +  @param DevEpInfo Pointer to endpoint info structure
> > +                   for the endpoint to initialize
> > +
> > +  @return EFI_SUCCESS if operation succeeded, EFI_DEVICE_ERROR
> otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdInitEp (
> > +  IN VOID                      *XdciHndl,
> > +  IN USB_DEVICE_ENDPOINT_INFO  *DevEpInfo
> > +  )
> > +{
> > +  EFI_STATUS   Status =3D EFI_DEVICE_ERROR;
> > +  USB_EP_INFO  EpInfo;
> > +
> > +  UsbdSetEpInfo (&EpInfo, DevEpInfo);
> > +  Status =3D UsbDeviceInitEp (XdciHndl, &EpInfo);
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Callback handler used when transfer operations complete. Calls
> > +  upper layer routine to handle the operation.
> > +
> > +  @param XdciHndl  Pointer (handle) to the XDCI driver object
> > +  @param XferReq   Pointer to the transfer request structure
> > +
> > +  @return VOID
> > +
> > +**/
> > +VOID
> > +EFIAPI
> > +UsbdXferDoneHndlr (
> > +  IN VOID                    *XdciHndl,
> > +  IN USB_XFER_REQUEST        *XferReq
> > +  )
> > +{
> > +  EFI_USB_DEVICE_XFER_INFO  XferInfo;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdXferDoneHndlr\n"));
> > +
> > +  XferInfo.EndpointNum =3D (UINT8)XferReq->EpInfo.EpNum;
> > +  XferInfo.EndpointDir =3D XferReq->EpInfo.EpDir;
> > +  XferInfo.EndpointType =3D XferReq->EpInfo.EpType;
> > +  XferInfo.Buffer =3D XferReq->XferBuffer;
> > +  XferInfo.Length =3D XferReq->ActualXferLen;
> > +
> > +  //
> > +  // If this is a non-control transfer complete, notify the class driv=
er
> > +  //
> > +  if (XferInfo.EndpointNum > 0) {
> > +    if (mDrvObj.UsbdDevObj->DataCallback !=3D NULL) {
> > +      mDrvObj.UsbdDevObj->DataCallback (&XferInfo);
> > +    }
> > +  }
> > +
> > +  return;
> > +}
> > +
> > +
> > +/**
> > +  Queue a request to transmit data
> > +
> > +  @param XdciHndl  Pointer (handle) to the XDCI driver object
> > +  @param IoReq     Pointer to IO structure containing details of the
> > +                   transfer request
> > +
> > +  @return EFI_SUCCESS if operation succeeded, EFI_DEVICE_ERROR
> otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdEpTxData (
> > +  IN VOID               *XdciHndl,
> > +  IN USB_DEVICE_IO_REQ  *IoReq
> > +  )
> > +{
> > +  EFI_STATUS        Status =3D EFI_DEVICE_ERROR;
> > +  USB_XFER_REQUEST  TxReq;
> > +
> > +  //
> > +  //set endpoint data
> > +  //
> > +  UsbdSetEpInfo (&(TxReq.EpInfo), &(IoReq->EndpointInfo)); // set
> endpoint data
> > +
> > +  //
> > +  //if this is a control endpoint, set the number and direction
> > +  //
> > +  if (IoReq->EndpointInfo.EndpointDesc =3D=3D NULL) {
> > +    TxReq.EpInfo.EpNum =3D 0;
> > +    TxReq.EpInfo.EpDir =3D UsbEpDirIn;
> > +  }
> > +
> > +  //
> > +  // setup the trasfer request
> > +  //
> > +  TxReq.XferBuffer =3D IoReq->IoInfo.Buffer;
> > +  TxReq.XferLen =3D IoReq->IoInfo.Length;
> > +  TxReq.XferDone =3D UsbdXferDoneHndlr;
> > +
> > +  DEBUG ((DEBUG_INFO,  "TX REQUEST: EpNum: 0x%x, epDir: 0x%x,
> epType: 0x%x, MaxPktSize: 0x%x\n",\
> > +          TxReq.EpInfo.EpNum, TxReq.EpInfo.EpDir, TxReq.EpInfo.EpType,
> TxReq.EpInfo.MaxPktSize));
> > +
> > +  Status =3D UsbXdciDeviceEpTxData (XdciHndl, &TxReq);
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Queue a request to receive data
> > +
> > +  @param XdciHndl  Pointer (handle) to the XDCI driver object
> > +  @param IoReq     Pointer to IO structure containing details of the
> > +                   receive request
> > +
> > +  @return EFI_SUCCESS if operation succeeded, EFI_DEVICE_ERROR
> otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdEpRxData (
> > +  IN VOID               *XdciHndl,
> > +  IN USB_DEVICE_IO_REQ  *IoReq
> > +  )
> > +{
> > +  EFI_STATUS        Status =3D EFI_DEVICE_ERROR;
> > +  USB_XFER_REQUEST  RxReq;
> > +  UINT32            ReqPacket;
> > +
> > +  DEBUG ((DEBUG_INFO,  "RX REQUEST in: IoReq->IoInfo.Length: 0x%x\n",
> IoReq->IoInfo.Length));
> > +  DEBUG ((DEBUG_INFO,  "RX REQUEST in: MaxPacketSize: 0x%x\n", IoReq-
> >EndpointInfo.EndpointDesc->MaxPacketSize));
> > +
> > +  if (IoReq->EndpointInfo.EndpointDesc->MaxPacketSize =3D=3D 0) {
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // set endpoint data
> > +  //
> > +  UsbdSetEpInfo (&(RxReq.EpInfo), &(IoReq->EndpointInfo));
> > +
> > +  //
> > +  // setup the trasfer request
> > +  //
> > +  RxReq.XferBuffer =3D IoReq->IoInfo.Buffer;
> > +
> > +  //
> > +  // Transfer length should be multiple of USB packet size.
> > +  //
> > +  ReqPacket =3D IoReq->IoInfo.Length / IoReq->EndpointInfo.EndpointDes=
c-
> >MaxPacketSize;
> > +  ReqPacket =3D ((IoReq->IoInfo.Length % IoReq-
> >EndpointInfo.EndpointDesc->MaxPacketSize) =3D=3D 0)? ReqPacket : ReqPack=
et
> + 1;
> > +  RxReq.XferLen =3D ReqPacket * IoReq->EndpointInfo.EndpointDesc-
> >MaxPacketSize;
> > +
> > +  RxReq.XferDone =3D UsbdXferDoneHndlr;
> > +
> > +  DEBUG ((DEBUG_INFO,  "RX REQUEST: EpNum: 0x%x, epDir: 0x%x,
> epType: 0x%x\n",\
> > +          RxReq.EpInfo.EpNum, RxReq.EpInfo.EpDir, RxReq.EpInfo.EpType)=
);
> > +  DEBUG ((DEBUG_INFO,  "RX REQUEST send: XferLen: 0x%x\n",
> RxReq.XferLen));
> > +
> > +  Status =3D UsbXdciDeviceEpRxData (XdciHndl, &RxReq);
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Callback used to handle Reset events from the XDCI
> > +
> > +  @param Param Pointer to a generic callback parameter structure
> > +
> > +  @return XDCI usb status
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbdResetEvtHndlr (
> > +  IN USB_DEVICE_CALLBACK_PARAM  *Param
> > +  )
> > +{
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdResetEvtHndlr\n"));
> > +
> > +  //
> > +  // reset device address to 0
> > +  //
> > +  Status =3D UsbDeviceSetAddress (mDrvObj.XdciDrvObj, 0x0);
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_INFO, "UsbdResetHdlr() - Failed to set address in
> XDCI\n"));
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Callback used to handle Connection done events from the XDCI
> > +
> > +  @param Param Pointer to a generic callback parameter structure
> > +
> > +  @return XDCI usb status
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbdConnDoneEvtHndlr (
> > +  IN USB_DEVICE_CALLBACK_PARAM *Param
> > +  )
> > +{
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdConnDoneEvtHndlr\n"));
> > +
> > +  //
> > +  //reset device address to 0
> > +  //
> > +  Status =3D UsbDeviceSetAddress (mDrvObj.XdciDrvObj, 0x0);
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_INFO, "UsbdConnDoneHdlr() - Failed to set address in
> XDCI\n"));
> > +  }
> > +
> > +  //
> > +  // set the device state to attached/connected
> > +  //
> > +  mDrvObj.State =3D UsbDevStateAttached;
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Callback used to handle Control Endpoint Setup events from the XDCI
> > +
> > +  @param Param Pointer to a generic callback parameter structure
> > +
> > +  @return XDCI usb status
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbdSetupEvtHndlr (
> > +  IN USB_DEVICE_CALLBACK_PARAM *Param
> > +  )
> > +{
> > +  EFI_STATUS              Status =3D EFI_SUCCESS;
> > +  EFI_USB_DEVICE_REQUEST  Req;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdSetupEvtHndlr\n"));
> > +
> > +  //
> > +  // Fill out request object from the incomming Buffer
> > +  //
> > +  CopyMem (&Req, Param->Buffer, sizeof(EFI_USB_DEVICE_REQUEST));
> > +
> > +  Status =3D UsbdSetupHdlr (&Req);
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_INFO, "UsbdSetupEvtHndlr: EFI_DEVICE_ERROR\n"));
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > + * Callback used to handle XferNotReady events from the XDCI
> > + *
> > + * @param Param Pointer to a generic callback parameter structure
> > + *
> > + * @return XDCI usb status
> > + */
> > +EFI_STATUS
> > +EFIAPI
> > +UsbdNrdyEvtHndlr (
> > +  IN USB_DEVICE_CALLBACK_PARAM *Param
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "UsbdNrdyEvtHndlr\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Registers callbacks for event handlers with the XDCI layer.
> > +  The functions will be called as the registered events are triggered.
> > +
> > +  @param  XdciHndl to XDCI core driver
> > +  @return EFI_SUCCESS if successful, EFI_DEVICE_ERROR otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdRegisterCallbacks (
> > +  IN VOID  *XdciHndl
> > +  )
> > +{
> > +  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_RESET_EVENT,
> UsbdResetEvtHndlr) !=3D EFI_SUCCESS) {
> > +    goto UdciRegCallbackError;
> > +  }
> > +
> > +  if (UsbDeviceRegisterCallback (XdciHndl,
> USB_DEVICE_CONNECTION_DONE, UsbdConnDoneEvtHndlr) !=3D
> EFI_SUCCESS) {
> > +    goto UdciRegCallbackError;
> > +  }
> > +
> > +  if (UsbDeviceRegisterCallback (XdciHndl,
> USB_DEVICE_SETUP_PKT_RECEIVED, UsbdSetupEvtHndlr) !=3D EFI_SUCCESS) {
> > +    goto UdciRegCallbackError;
> > +  }
> > +
> > +  if (UsbDeviceRegisterCallback (XdciHndl, USB_DEVICE_XFER_NRDY,
> UsbdNrdyEvtHndlr) !=3D EFI_SUCCESS) {
> > +    goto UdciRegCallbackError;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +
> > +UdciRegCallbackError:
> > +  return EFI_DEVICE_ERROR;
> > +}
> > +
> > +
> > +/**
> > +  Returns the configuration descriptor for this device. The data
> > +  Buffer returned will also contain all downstream interface and
> > +  endpoint Buffers.
> > +
> > +  @param Buffer    Pointer to destination Buffer to copy descriptor da=
ta to
> > +  @param DescIndex the index of the descriptor to return
> > +  @param ReqLen    the length in bytes of the request Buffer
> > +  @param DataLen   Pointer whos value is to be filled with the byte co=
unt
> of
> > +                   data copied to the output Buffer
> > +
> > +  @return EFI_SUCCESS if descritor successfully copied,
> EFI_DEVICE_ERROR otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdGetConfigDesc (
> > +  IN VOID      *Buffer,
> > +  IN UINT8     DescIndex,
> > +  IN UINT32    ReqLen,
> > +  IN UINT32    *DataLen
> > +  )
> > +{
> > +  EFI_STATUS             Status =3D EFI_DEVICE_ERROR;
> > +  UINT8                  NumConfigs =3D 0;
> > +  UINT32                 ConfigLen =3D 0;
> > +  USB_DEVICE_CONFIG_OBJ  *ConfigObj =3D NULL;
> > +  VOID                   *Descriptor =3D 0;
> > +  UINT32                 Length =3D 0;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdGetConfigDesc()\n"));
> > +
> > +  //
> > +  // For a CONFIGURATION request we send back all descriptors branchin=
g
> out
> > +  // from this descriptor including the INTERFACE and ENDPOINT
> descriptors
> > +  //
> > +  //
> > +  // Verify the requested configuration exists - check valid index
> > +  //
> > +  NumConfigs =3D mDrvObj.UsbdDevObj->DeviceDesc->NumConfigurations;
> > +
> > +  if (DescIndex < NumConfigs) {
> > +    //
> > +    // get the configuration object using the index Offset
> > +    //
> > +    ConfigObj =3D (mDrvObj.UsbdDevObj->ConfigObjs + DescIndex);
> > +    //
> > +    // get the complete configuration Buffer block including Interface=
 and
> Endpoint data
> > +    //
> > +    Descriptor =3D ConfigObj->ConfigAll;
> > +    //
> > +    // The config descriptor TotalLength has the full value for all de=
sc
> Buffers
> > +    //
> > +    ConfigLen =3D ConfigObj->ConfigDesc->TotalLength;
> > +    //
> > +    // copy the data to the output Buffer
> > +    //
> > +    Length =3D MIN (ReqLen, ConfigLen);
> > +    CopyMem (Buffer, Descriptor, Length);
> > +    *DataLen =3D Length;
> > +    Status =3D EFI_SUCCESS;
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "UsbdGetConfigDesc() - Invalid Config index:
> %i\n", DescIndex));
> > +  }
> > +
> > +  if (Status =3D=3D EFI_SUCCESS) {
> > +    if (ConfigObj !=3D NULL) {
> > +      PrintConfigDescriptor (ConfigObj->ConfigDesc);
> > +    }
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Sets the active configuration to the selected configuration index if=
 it exists
> > +
> > +  @param CfgValue  the configuration value to set
> > +
> > +  @return EFI_SUCCESS if the configuration was set, EFI_DEVICE_ERROR
> otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdSetConfig (
> > +  UINT8  CfgValue
> > +  )
> > +{
> > +  EFI_STATUS                 Status =3D EFI_DEVICE_ERROR;
> > +  UINT8                      numConfigs =3D 0;
> > +  USB_DEVICE_CONFIG_OBJ      *pConfigObj =3D NULL;
> > +  USB_DEVICE_INTERFACE_OBJ   *pIfObj =3D NULL;
> > +  USB_DEVICE_ENDPOINT_OBJ    *pEpObj =3D NULL;
> > +  UINT8                      cfgItr =3D 0;
> > +  UINT8                      ifItr =3D 0;
> > +  UINT8                      epItr =3D 0;
> > +  USB_DEVICE_ENDPOINT_INFO   EpInfo;
> > +  USB_EP_INFO                UsbEpInfo;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdSetConfig()\n"));
> > +  //
> > +  // Verify the requested configuration exists - check valid index
> > +  //
> > +  numConfigs =3D mDrvObj.UsbdDevObj->DeviceDesc->NumConfigurations;
> > +
> > +  if (CfgValue !=3D 0) {
> > +    //
> > +    // Search for a matching configuration
> > +    //
> > +    for (cfgItr =3D 0; cfgItr < numConfigs; cfgItr++) {
> > +      pConfigObj =3D (mDrvObj.UsbdDevObj->ConfigObjs + cfgItr);
> > +      if (pConfigObj->ConfigDesc->ConfigurationValue =3D=3D CfgValue) =
{
> > +
> > +        //
> > +        // Set the active configuration object
> > +        //
> > +        mDrvObj.ActiveConfigObj =3D pConfigObj;
> > +        //
> > +        // Find all interface objects for this configuration
> > +        //
> > +        for (ifItr =3D 0; ifItr < pConfigObj->ConfigDesc->NumInterface=
s; ifItr++) {
> > +          pIfObj =3D (pConfigObj->InterfaceObjs + ifItr);
> > +          //
> > +          // Configure the Endpoints in the XDCI
> > +          //
> > +          for (epItr =3D 0; epItr < pIfObj->InterfaceDesc->NumEndpoint=
s;
> epItr++) {
> > +            pEpObj =3D (pIfObj->EndpointObjs + epItr);
> > +
> > +            EpInfo.EndpointDesc =3D pEpObj->EndpointDesc;
> > +            EpInfo.EndpointCompDesc =3D pEpObj->EndpointCompDesc;
> > +
> > +            if (UsbdInitEp (mDrvObj.XdciDrvObj, &EpInfo) =3D=3D EFI_SU=
CCESS) {
> > +              UsbdSetEpInfo(&UsbEpInfo, &EpInfo);
> > +              if (UsbDeviceEpEnable (mDrvObj.XdciDrvObj, &UsbEpInfo) =
=3D=3D
> EFI_SUCCESS) {
> > +                Status =3D EFI_SUCCESS;
> > +              } else {
> > +                DEBUG ((DEBUG_INFO, "UsbdSetConfig() - Failed to enabl=
e
> endpoint\n"));
> > +              }
> > +            } else {
> > +              DEBUG ((DEBUG_INFO, "UsbdSetConfig() - Failed to initial=
ize
> endpoint\n"));
> > +            }
> > +          }
> > +        }
> > +        //
> > +        // Let the class driver know it is configured
> > +        //
> > +        if (Status =3D=3D EFI_SUCCESS) {
> > +          if (mDrvObj.UsbdDevObj->ConfigCallback !=3D NULL) {
> > +            mDrvObj.UsbdDevObj->ConfigCallback (CfgValue);
> > +          }
> > +        }
> > +
> > +        mDrvObj.State =3D UsbDevStateConfigured; // we are now configu=
red
> > +
> > +        break; // break from config search loop
> > +      }
> > +    }
> > +  }
> > +
> > +  if (EFI_ERROR (Status)) {
> > +   DEBUG ((DEBUG_INFO, "UsbdSetConfig() - Invalid requested
> configuration value: %i\n", CfgValue));
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Returns the currently active configuration value
> > +
> > +  @param Buffer    Pointer to destination Buffer to copy configuration
> value to
> > +  @param ReqLen    the length in bytes of the request Buffer
> > +  @param DataLen   Pointer whos value is to be filled with the byte co=
unt
> of
> > +                   data copied to the output Buffer
> > +
> > +  @return EFI_SUCCESS if config value is successfully copied,
> EFI_DEVICE_ERROR otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdGetConfig (
> > +  VOID      *Buffer,
> > +  UINT32    ReqLen,
> > +  UINT32    *DataLen
> > +  )
> > +{
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdGetConfig()\n"));
> > +
> > +  if (ReqLen >=3D 1) { // length of data expected must be 1
> > +    if (mDrvObj.ActiveConfigObj !=3D NULL) { // assure we have a confi=
g active
> > +      *DataLen =3D 1; // one byte for ConfigurationValue
> > +      *(UINT8*)Buffer =3D mDrvObj.ActiveConfigObj->ConfigDesc-
> >ConfigurationValue;
> > +
> > +      Status =3D EFI_SUCCESS;
> > +    } else {
> > +      DEBUG ((DEBUG_INFO, "UsbdGetConfig() - No active configuration
> available\n"));
> > +    }
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "UsbdGetConfig() - Invalid data length\n"));
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Returns the requested string descriptor if it exists
> > +
> > +  @param Buffer    Pointer to destination Buffer to copy descriptor da=
ta to
> > +  @param DescIndex the index of the descriptor to return
> > +  @param LangId    the target language ID
> > +  @param ReqLen    the length in bytes of the request Buffer
> > +  @param DataLen   Pointer whos value is to be filled with the byte co=
unt
> of
> > +                   data copied to the output Buffer
> > +
> > +  @return EFI_SUCCESS if descritor successfully copied,
> EFI_DEVICE_ERROR otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdGetStringDesc (
> > +  VOID      *Buffer,
> > +  UINT8     DescIndex,
> > +  UINT16    LangId,
> > +  UINT32    ReqLen,
> > +  UINT32    *DataLen
> > +  )
> > +{
> > +  EFI_STATUS             Status =3D EFI_DEVICE_ERROR;
> > +  UINT32                 Length =3D 0;
> > +  USB_STRING_DESCRIPTOR  *StringDesc;
> > +  UINT8                  Index =3D 0;
> > +  UINT8                  StrLangEntries =3D 0;
> > +  BOOLEAN                StrLangFound =3D FALSE;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: Index: 0x%x, LangId: 0x%x,
> ReqLen: 0x%x\n", DescIndex, LangId, ReqLen));
> > +
> > +  //
> > +  // index zero of the string table contains the supported language co=
des
> > +  //
> > +  if (DescIndex =3D=3D 0) {
> > +    StringDesc =3D (mDrvObj.UsbdDevObj->StringTable);
> > +    Length =3D MIN (ReqLen, StringDesc->Length);
> > +    CopyMem (Buffer, StringDesc, Length);
> > +    *DataLen =3D Length;
> > +    Status =3D EFI_SUCCESS;
> > +  } else {
> > +
> > +    //
> > +    // Verify the requested language ID is supported. String descripto=
r Zero
> > +    // (First entry in the string table) is expected to contain the la=
nguage list.
> > +    // The requested language ID is specified in the Index member of t=
he
> request.
> > +    //
> > +    StringDesc =3D mDrvObj.UsbdDevObj->StringTable; // get language st=
ring
> descriptor
> > +    StrLangEntries =3D ((StringDesc->Length - 2) >> 1);
> > +    DEBUG ((DEBUG_INFO, "StrLangEntries=3D%x\n", StrLangEntries));
> > +
> > +    DEBUG ((DEBUG_INFO, "Looking LangID: \n"));
> > +
> > +    for (Index =3D 0; Index < StrLangEntries; Index++) {
> > +      DEBUG ((DEBUG_INFO, "LangID [%x]=3D %x\n", Index, StringDesc-
> >LangID [Index]));
> > +
> > +      if (StringDesc->LangID [Index] =3D=3D LangId) {
> > +        DEBUG ((DEBUG_INFO, "Found it\n"));
> > +        StrLangFound =3D TRUE;
> > +      }
> > +    }
> > +
> > +    //
> > +    // If we found a matching language, attempt to get the string inde=
x
> requested
> > +    //
> > +    if (StrLangFound =3D=3D TRUE) {
> > +      DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: StrLangFound=3DFound,
> DescIndex=3D%x, StrTblEntries=3D%x\n", DescIndex, mDrvObj.UsbdDevObj-
> >StrTblEntries));
> > +
> > +      if (DescIndex < mDrvObj.UsbdDevObj->StrTblEntries) {
> > +        //
> > +        // get the string descriptor for the requested index
> > +        //
> > +        StringDesc =3D (mDrvObj.UsbdDevObj->StringTable + DescIndex);
> > +
> > +        Length =3D MIN (ReqLen, StringDesc->Length);
> > +        DEBUG ((DEBUG_INFO, "ReqLen=3D%x, StringLength=3D%x, Length=3D=
%x\n",
> ReqLen, StringDesc->Length, Length));
> > +
> > +        CopyMem (Buffer, StringDesc, Length);
> > +        *DataLen =3D Length;
> > +        Status =3D EFI_SUCCESS;
> > +      } else {
> > +        DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: Invalid String index i=
n
> USB_REQ_GET_DESCRIPTOR request\n"));
> > +      }
> > +    } else {
> > +      DEBUG ((DEBUG_INFO, "UsbdGetStringDesc: Unsupported String
> Language ID for USB_REQ_GET_DESCRIPTOR request\n"));
> > +    }
> > +  }
> > +
> > +  if (Status =3D=3D EFI_SUCCESS) {
> > +    PrintStringDescriptor (StringDesc);
> > +  }
> > +  return Status;
> > +}
> > +
> > +
> > +#ifdef SUPPORT_SUPER_SPEED
> > +/**
> > +  Returns the configuration descriptor for this device. The data
> > +  Buffer returned will also contain all downstream interface and
> > +  endpoint Buffers.
> > +
> > +  @param Buffer    Pointer to destination Buffer to copy descriptor da=
ta to
> > +  @param ReqLen    the length in bytes of the request Buffer
> > +  @param DataLen   Pointer whos value is to be filled with the byte co=
unt
> of
> > +                   data copied to the output Buffer
> > +
> > +  @return EFI_SUCCESS if descritor successfully copied,
> EFI_DEVICE_ERROR otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdGetBOSDesc (
> > +  IN VOID      *Buffer,
> > +  IN UINT32    ReqLen,
> > +  IN UINT32    *DataLen
> > +  )
> > +{
> > +  EFI_USB_BOS_DESCRIPTOR  *BosDesc =3D 0;
> > +  UINT32                  Length =3D 0;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdGetBOSDesc()\n"));
> > +
> > +  BosDesc =3D mDrvObj.UsbdDevObj->BosDesc;
> > +  Length =3D MIN (ReqLen, mDrvObj.UsbdDevObj->BosDesc->TotalLength);
> > +
> > +  CopyMem(Buffer, BosDesc, Length);
> > +  *DataLen =3D Length;
> > +
> > +  PrintBOSDescriptor (BosDesc);
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +#endif
> > +
> > +/**
> > +  Returns the current status for Device/Interface/Endpoint
> > +
> > +  @param Buffer    Pointer to destination Buffer to copy descriptor da=
ta to
> > +  @param ReqType   The type of status to get
> > +  @param ReqLen    the length in bytes of the request Buffer
> > +  @param DataLen   Pointer whos value is to be filled with the byte co=
unt
> of
> > +                   data copied to the output Buffer
> > +
> > +  @return EFI_SUCCESS if status successfully copied, EFI_DEVICE_ERROR
> otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdGetStatus (
> > +  VOID      *Buffer,
> > +  UINT8     ReqType,
> > +  UINT32    ReqLen,
> > +  UINT32    *DataLen
> > +  )
> > +{
> > +  EFI_STATUS  Status =3D EFI_DEVICE_ERROR;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdGetStatus()\n"));
> > +
> > +  if (ReqLen >=3D 2) { // length of data must be at least 2 bytes
> > +    switch (ReqType & USB_TARGET_MASK) {
> > +      case USB_TARGET_DEVICE:
> > +        *DataLen =3D 2; // two byte for status
> > +        *(UINT16*)Buffer =3D USB_STATUS_SELFPOWERED;
> > +        Status =3D EFI_SUCCESS;
> > +        break;
> > +
> > +      case USB_TARGET_INTERFACE:
> > +        //
> > +        // No implementation needed at this time
> > +        //
> > +        break;
> > +
> > +      case USB_TARGET_ENDPOINT:
> > +        //
> > +        // No implementation needed at this time
> > +        // Should specify if endpoint is halted. Implement as necessar=
y.
> > +        //
> > +        break;
> > +
> > +      case USB_TARGET_OTHER:
> > +        //
> > +        // No implementation needed at this time
> > +        //
> > +        break;
> > +
> > +      default:
> > +        break;
> > +    }
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "UsbdGetStatus() - Invalid data length\n"));
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Sets the address of the device
> > +
> > +  @param address   the address value to set
> > +
> > +  @return EFI_SUCCESS if address was set, EFI_DEVICE_ERROR otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdSetAddress (
> > +  UINT8    Address
> > +  )
> > +{
> > +  EFI_STATUS  Status =3D EFI_DEVICE_ERROR;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdSetAddress: setting address: 0x%x\n",
> Address));
> > +
> > +  if (Address <=3D 0x7F) { // address must not be > 127
> > +    mDrvObj.Address =3D Address;
> > +
> > +    //
> > +    // Configure Address in the XDCI
> > +    //
> > +    Status =3D UsbDeviceSetAddress (mDrvObj.XdciDrvObj,
> mDrvObj.Address);
> > +    if (!EFI_ERROR (Status)) {
> > +      mDrvObj.State =3D UsbDevStateAddress;
> > +    } else {
> > +      DEBUG ((DEBUG_INFO, "UsbdSetAddress: Failed to set address in
> XDCI\n"));
> > +    }
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "UsbdSetAddress: Invalid address: 0x%x\n",
> Address));
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Handles Setup device requests. Standard requests are immediately
> > +  handled here, and any Class/Vendor specific requests are forwarded
> > +  to the class driver
> > +
> > +  @param CtrlRequest  Pointer to a device request
> > +
> > +  @return EFI_SUCCESS if request successfully handled, FALSE otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdSetupHdlr (
> > +  IN EFI_USB_DEVICE_REQUEST    *CtrlRequest
> > +  )
> > +{
> > +  EFI_STATUS              Status =3D EFI_DEVICE_ERROR;
> > +  UINT8                   DescIndex =3D 0;
> > +  USB_DEVICE_DESCRIPTOR   *DevDesc =3D 0;
> > +
> > +  //
> > +  // Initialize the IO object
> > +  //
> > +  mCtrlIoReq.IoInfo.Length =3D 0;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdSetupHdlr start\n"));
> > +  PrintDeviceRequest (CtrlRequest);
> > +
> > +  //
> > +  // Handle Standard Device Requests
> > +  //
> > +  if ((CtrlRequest->RequestType & USB_REQ_TYPE_MASK) =3D=3D
> USB_REQ_TYPE_STANDARD) {
> > +    switch (CtrlRequest->Request) {
> > +      case USB_REQ_GET_DESCRIPTOR:
> > +        DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Host requests get
> descriptor\n"));
> > +        if (CtrlRequest->RequestType =3D=3D USB_RT_TX_DIR_D_TO_H) {
> > +          DescIndex =3D (CtrlRequest->Value & 0xff); // low byte is th=
e index
> requested
> > +          switch (CtrlRequest->Value >> 8) { // high byte contains req=
uest type
> > +            case USB_DESC_TYPE_DEVICE:
> > +              DEBUG ((DEBUG_INFO, "Descriptor tyep: Device\n"));
> > +              DevDesc =3D mDrvObj.UsbdDevObj->DeviceDesc;
> > +              //
> > +              // copy the data to the output Buffer
> > +              //
> > +              mCtrlIoReq.IoInfo.Length =3D MIN (CtrlRequest->Length, D=
evDesc-
> >Length);
> > +              CopyMem (mCtrlIoReq.IoInfo.Buffer, DevDesc,
> mCtrlIoReq.IoInfo.Length);
> > +              PrintDeviceDescriptor (DevDesc);
> > +              break;
> > +
> > +            case USB_DESC_TYPE_CONFIG:
> > +              DEBUG ((DEBUG_INFO, "Descriptor tyep: Configuration\n"))=
;
> > +              Status =3D UsbdGetConfigDesc (
> > +                         mCtrlIoReq.IoInfo.Buffer,
> > +                         DescIndex,
> > +                         CtrlRequest->Length,
> > +                         &(mCtrlIoReq.IoInfo.Length)
> > +                         );
> > +              break;
> > +
> > +            case USB_DESC_TYPE_STRING:
> > +              DEBUG ((DEBUG_INFO, "Descriptor tyep: String\n"));
> > +              Status =3D UsbdGetStringDesc (
> > +                         mCtrlIoReq.IoInfo.Buffer,
> > +                         DescIndex,
> > +                         CtrlRequest->Index,
> > +                         CtrlRequest->Length,
> > +                         &(mCtrlIoReq.IoInfo.Length)
> > +                         );
> > +              break;
> > +
> > +#ifdef SUPPORT_SUPER_SPEED
> > +            case USB_DESC_TYPE_BOS:
> > +              DEBUG ((DEBUG_INFO, "Descriptor tyep: BOS\n"));
> > +              Status =3D UsbdGetBOSDesc (
> > +                         mCtrlIoReq.IoInfo.Buffer,
> > +                         CtrlRequest->Length,
> > +                         &(mCtrlIoReq.IoInfo.Length)
> > +                         );
> > +              break;
> > +
> > +            case USB_DESC_TYPE_SS_ENDPOINT_COMPANION:
> > +              DEBUG ((DEBUG_INFO, "Descriptor tyep: Endpoint
> Companion\n"));
> > +              break;
> > +#endif
> > +
> > +            default:
> > +              DEBUG ((DEBUG_INFO, "Descriptor tyep: Unsupported,
> USB_REQ_GET_DESCRIPTOR request: 0x%x\n", (CtrlRequest->Value >> 8)));
> > +              break;
> > +          }
> > +        } else {
> > +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr() - Invalid direction for
> USB_REQ_GET_DESCRIPTOR request\n"));
> > +        }
> > +        break;
> > +
> > +      case USB_REQ_GET_CONFIG:
> > +        DEBUG ((DEBUG_INFO, "USB_REQ_GET_CONFIG\n"));
> > +        if (CtrlRequest->RequestType =3D=3D USB_RT_TX_DIR_D_TO_H) {
> > +          Status =3D UsbdGetConfig (mCtrlIoReq.IoInfo.Buffer, CtrlRequ=
est-
> >Length, &(mCtrlIoReq.IoInfo.Length));
> > +        } else {
> > +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for
> USB_REQ_GET_CONFIG request\n"));
> > +        }
> > +        break;
> > +
> > +      case USB_REQ_SET_CONFIG:
> > +        DEBUG ((DEBUG_INFO, "USB_REQ_SET_CONFIG\n"));
> > +        if (CtrlRequest->RequestType =3D=3D USB_RT_TX_DIR_H_TO_D) {
> > +          Status =3D UsbdSetConfig ((UINT8)CtrlRequest->Value);
> > +        } else {
> > +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for
> USB_REQ_SET_CONFIG request\n"));
> > +        }
> > +        break;
> > +
> > +      case USB_REQ_SET_ADDRESS:
> > +        DEBUG ((DEBUG_INFO, "USB_REQ_SET_ADDRESS\n"));
> > +        if (CtrlRequest->RequestType =3D=3D USB_RT_TX_DIR_H_TO_D) {
> > +          Status =3D UsbdSetAddress ((UINT8)CtrlRequest->Value);
> > +        } else {
> > +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for
> USB_REQ_SET_ADDRESS request\n"));
> > +        }
> > +        break;
> > +
> > +      case USB_REQ_GET_STATUS:
> > +        DEBUG ((DEBUG_INFO, "USB_REQ_GET_STATUS\n"));
> > +        if (CtrlRequest->RequestType & USB_RT_TX_DIR_D_TO_H) {
> > +          Status =3D UsbdGetStatus (mCtrlIoReq.IoInfo.Buffer, CtrlRequ=
est-
> >RequestType, CtrlRequest->Length, &(mCtrlIoReq.IoInfo.Length));
> > +        } else {
> > +          DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Invalid direction for
> USB_REQ_GET_STATUS request\n"));
> > +        }
> > +        break;
> > +#ifdef SUPPORT_SUPER_SPEED
> > +      case USB_REQ_CLEAR_FEATURE:
> > +      case USB_REQ_SET_FEATURE:
> > +      case USB_REQ_SET_DESCRIPTOR:
> > +      case USB_REQ_GET_INTERFACE:
> > +      case USB_REQ_SET_INTERFACE:
> > +      case USB_REQ_SYNCH_FRAME:
> > +#endif
> > +      default:
> > +         DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Unsupported Standard
> Request: 0x%x\n", CtrlRequest->Request));
> > +          break;
> > +    }
> > +  } else { // This is not a Standard request, it specifies Class/Vendo=
r
> handling
> > +    //
> > +    // Forward request to class driver
> > +    //
> > +    DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Class/Vendor Request\n"));
> > +    if (mDrvObj.UsbdDevObj->SetupCallback !=3D NULL) {
> > +      mDrvObj.UsbdDevObj->SetupCallback (CtrlRequest,
> &(mCtrlIoReq.IoInfo));
> > +    }
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "dataLen=3D%x\n", mCtrlIoReq.IoInfo.Length));
> > +  //
> > +  // Transfer data according to request if necessary
> > +  //
> > +  if (mCtrlIoReq.IoInfo.Length> 0) {
> > +    Status =3D UsbdEpTxData (mDrvObj.XdciDrvObj, &mCtrlIoReq);
> > +    if (EFI_ERROR (Status)) {
> > +      DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Failed to TX data\n"));
> > +    }
> > +  } else {
> > +    //
> > +    // If we are not responding with data, send control status
> > +    //
> > +    Status =3D UsbDeviceEp0TxStatus (mDrvObj.XdciDrvObj);
> > +    if (EFI_ERROR (Status)) {
> > +      DEBUG ((DEBUG_INFO, "UsbdSetupHdlr: Failed to Tx Ep0 Status\n"))=
;
> > +    }
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Handles Connection done events. Sets the device address to zero.
> > +
> > +  @return EFI_SUCCESS if able to set the address, EFI_DEVICE_ERROR
> otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +UsbdConnDoneHdlr (
> > +  VOID
> > +  )
> > +{
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbdConnDoneHdlr()\n"));
> > +
> > +  //
> > +  // reset device address to 0
> > +  //
> > +  Status =3D UsbDeviceSetAddress (mDrvObj.XdciDrvObj, 0x0);
> > +  if (EFI_ERROR (Status)) {
> > +    DEBUG ((DEBUG_INFO, "UsbdConnDoneHdlr() - Failed to set address in
> XDCI\n"));
> > +  }
> > +
> > +  //
> > +  // set the device state to attached/connected
> > +  //
> > +  mDrvObj.State =3D UsbDevStateAttached;
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Handles transmit/receive completion events. Directly handles
> > +  control endpoint events and forwards class/vendor specific events
> > +  to the class drivers.
> > +
> > +  @param   XferInfo   Pointer to Xfer structure
> > +
> > +  @return
> > +
> > +**/
> > +VOID
> > +UsbdXferDoneHdlr (
> > +  IN EFI_USB_DEVICE_XFER_INFO    *XferInfo
> > +  )
> > +{
> > +  //
> > +  // If this is a non-control transfer complete, notify the class driv=
er
> > +  //
> > +  if (XferInfo->EndpointNum > 0) {
> > +    if (mDrvObj.UsbdDevObj->DataCallback !=3D NULL) {
> > +      mDrvObj.UsbdDevObj->DataCallback (XferInfo);
> > +    }
> > +  }
> > +
> > +  return;
> > +}
> > +
> > +
> > +/**
> > +  Binds a USB class driver with this USB device driver core.
> > +  After calling this routine, the driver is ready to begin
> > +  USB processing.
> > +
> > +  @param  UsbdDevObj   Pointer to a usbd device object which contains
> > +                       all relevant information for the class driver d=
evice
> > +
> > +  @return TRUE if binding was successful, FALSE otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceBind (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> > +  IN USB_DEVICE_OBJ                             *UsbdDevObj
> > +  )
> > +{
> > +  EFI_STATUS  Status =3D EFI_SUCCESS;
> > +
> > +  //
> > +  // allocate Tx Buffer
> > +  //
> > +  mCtrlIoReq.IoInfo.Buffer =3D AllocateZeroPool
> (USB_EPO_MAX_PKT_SIZE_ALL);
> > +  if (mCtrlIoReq.IoInfo.Buffer !=3D NULL) {
> > +    mDrvObj.UsbdDevObj =3D UsbdDevObj;
> > +    mDrvObj.ActiveConfigObj =3D NULL;
> > +    mDrvObj.Address =3D 0;
> > +    mDrvObj.State =3D UsbDevStateInit;
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceBind() - Failed to allocate IO
> Buffer\n"));
> > +    Status =3D EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Unbinds the USB class driver from this USB device driver core.
> > +
> > +  @return TRUE if successful, FALSE otherwise
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceUnbind (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  )
> > +{
> > +  mDrvObj.UsbdDevObj =3D NULL;
> > +  mDrvObj.ActiveConfigObj =3D NULL;
> > +  mDrvObj.Address =3D 0;
> > +  mDrvObj.State =3D UsbDevStateOff;
> > +  mDrvObj.XdciInitialized =3D FALSE;
> > +
> > +  //
> > +  // release allocated Buffer data
> > +  //
> > +  if (mCtrlIoReq.IoInfo.Buffer) {
> > +    FreePool (mCtrlIoReq.IoInfo.Buffer);
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Performs continual USB device event processing until a cancel
> > +  event occurs
> > +
> > +  @param   TimeoutMs   Connection timeout in ms. If 0, waits forever.
> > +  @return  TRUE if run executed normally, FALSE if error ocurred
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceRun (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> > +  IN UINT32                                     TimeoutMs
> > +  )
> > +{
> > +  EFI_STATUS              Status =3D EFI_DEVICE_ERROR;
> > +  USB_XDCI_DEV_CONTEXT    *XdciDevContext;
> > +
> > +  XdciDevContext =3D USBUSBD_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  //
> > +  // can only run if XDCI is initialized
> > +  //
> > +  if ((mDrvObj.XdciInitialized =3D=3D TRUE)) {
> > +
> > +    if ((mDrvObj.State =3D=3D UsbDevStateConfigured) && (XdciDevContex=
t-
> >XdciPollTimer =3D=3D NULL)) {
> > +      Status =3D gBS->CreateEvent (
> > +                      EVT_TIMER | EVT_NOTIFY_SIGNAL,
> > +                      TPL_NOTIFY,
> > +                      UsbdMonitorEvents,
> > +                      XdciDevContext,
> > +                      &XdciDevContext->XdciPollTimer
> > +                      );
> > +      if (!EFI_ERROR (Status)) {
> > +        Status =3D gBS->SetTimer (XdciDevContext->XdciPollTimer,
> TimerPeriodic, EFI_TIMER_PERIOD_MILLISECONDS (20));
> > +        DEBUG ((EFI_D_ERROR, "UsbDeviceRun Create Event\n"));
> > +      }
> > +    }
> > +
> > +    mXdciRun =3D TRUE; // set the run flag to active
> > +    Status =3D EFI_SUCCESS;
> > +
> > +    //
> > +    // start the Event processing loop
> > +    //
> > +    while (TRUE) {
> > +      if (XdciDevContext->XdciPollTimer =3D=3D NULL) {
> > +        if (UsbDeviceIsrRoutine (mDrvObj.XdciDrvObj) !=3D EFI_SUCCESS)=
 {
> > +          DEBUG ((DEBUG_INFO, "UsbDeviceRun() - Failed to execute even=
t
> ISR\n"));
> > +        }
> > +      }
> > +
> > +      //
> > +      // Check if a run cancel request exists, if so exit processing l=
oop
> > +      //
> > +      if (mXdciRun =3D=3D FALSE) {
> > +        if (XdciDevContext->XdciPollTimer !=3D NULL) {
> > +          DEBUG ((EFI_D_ERROR, "UsbDeviceRun close Event\n"));
> > +          gBS->SetTimer (XdciDevContext->XdciPollTimer, TimerCancel, 0=
);
> > +          gBS->CloseEvent (XdciDevContext->XdciPollTimer);
> > +          XdciDevContext->XdciPollTimer =3D NULL;
> > +        }
> > +        Status =3D EFI_SUCCESS;
> > +        DEBUG ((DEBUG_INFO, "UsbDeviceRun() - processing was
> cancelled\n"));
> > +        break;
> > +      }
> > +
> > +      //
> > +      // check for timeout
> > +      //
> > +      if (TimeoutMs =3D=3D 0)
> > +        return EFI_TIMEOUT;
> > +      gBS->Stall (50);
> > +      TimeoutMs--;
> > +    }
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Sets a flag to stop the running device processing loop
> > +
> > +  @return TRUE always
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceStop (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  )
> > +{
> > +  mXdciRun =3D FALSE; // set run flag to FALSE to stop processing
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceInitXdci (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  )
> > +{
> > +  EFI_STATUS            Status =3D EFI_DEVICE_ERROR;
> > +  USB_XDCI_DEV_CONTEXT  *XdciDevContext;
> > +
> > +  XdciDevContext =3D USBUSBD_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  PlatformSpecificInit ();
> > +
> > +  if (mDrvObj.XdciInitialized =3D=3D FALSE) {
> > +    if (XdciDevContext->XdciMmioBarAddr !=3D 0) {
> > +
> > +      //
> > +      // Initialize device controller driver
> > +      //
> > +      DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Initializing
> Controller...\n"));
> > +
> > +      //
> > +      // Initialize the device controller interface
> > +      //
> > +      if (UsbdInit ((UINT32)XdciDevContext->XdciMmioBarAddr,
> &mDrvObj.XdciDrvObj) =3D=3D EFI_SUCCESS) {
> > +
> > +        //
> > +        // Setup callbacks
> > +        //
> > +        if (UsbdRegisterCallbacks (mDrvObj.XdciDrvObj) =3D=3D EFI_SUCC=
ESS) {
> > +
> > +          mDrvObj.XdciInitialized =3D TRUE;
> > +          Status =3D EFI_SUCCESS;
> > +
> > +          DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Controller initia=
lization
> complete\n"));
> > +        } else {
> > +          DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Failed to registe=
r UDCI
> callbacks\n"));
> > +        }
> > +      } else {
> > +        DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - Failed to initializ=
e
> UDCI\n"));
> > +      }
> > +    } else {
> > +      DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - XDCI MMIO BAR not
> set\n"));
> > +    }
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceInitXdci() - XDCI already
> initialized\n"));
> > +    Status =3D EFI_ALREADY_STARTED;
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceConnect(
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  )
> > +{
> > +  EFI_STATUS  Status =3D EFI_DEVICE_ERROR;
> > +
> > +  DEBUG ((DEBUG_INFO,  "UsbDeviceConnect \n"));
> > +  if (UsbXdciDeviceConnect (mDrvObj.XdciDrvObj) =3D=3D EFI_SUCCESS) {
> > +    Status =3D EFI_SUCCESS;
> > +  }
> > +  return Status;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceDisConnect (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  )
> > +{
> > +  EFI_STATUS  Status =3D EFI_DEVICE_ERROR;
> > +
> > +  DEBUG ((DEBUG_INFO,  "UsbDeviceDisConnect \n"));
> > +  if (UsbDeviceDisconnect (mDrvObj.XdciDrvObj) =3D=3D EFI_SUCCESS) {
> > +    mDrvObj.State =3D UsbDevStateInit;
> > +    Status =3D EFI_SUCCESS;
> > +  }
> > +
> > +  XhciSwitchSwid(FALSE);
> > +  return Status;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceEpTxData(
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> > +  IN USB_DEVICE_IO_REQ                          *IoRequest
> > +  )
> > +{
> > +  EFI_STATUS  Status;
> > +
> > +  Status =3D UsbdEpTxData (mDrvObj.XdciDrvObj, IoRequest);
> > +  return Status;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +UsbDeviceEpRxData(
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> > +  IN USB_DEVICE_IO_REQ                          *IoRequest
> > +  )
> > +{
> > +  EFI_STATUS  Status;
> > +
> > +  Status =3D UsbdEpRxData (mDrvObj.XdciDrvObj, IoRequest);
> > +  return Status;
> > +}
> > +
> > +
> > +//
> > +// The Runtime UsbDeviceMode Protocol instance produced by this driver
> > +//
> > +EFI_USB_DEVICE_MODE_PROTOCOL  mUsbDeviceModeProtocol =3D {
> > +  UsbDeviceInitXdci,
> > +  UsbDeviceConnect,
> > +  UsbDeviceDisConnect,
> > +  UsbDeviceEpTxData,
> > +  UsbDeviceEpRxData,
> > +  UsbDeviceBind,
> > +  UsbDeviceUnbind,
> > +  UsbDeviceRun,
> > +  UsbDeviceStop
> > +};
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
> > new file mode 100644
> > index 0000000000..ac9c89b2f1
> > --- /dev/null
> > +++
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbDeviceMode.h
> > @@ -0,0 +1,39 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#ifndef _USB_DEVICE_MODE_DXE_H_
> > +#define _USB_DEVICE_MODE_DXE_H_
> > +
> > +#include <Uefi.h>
> > +#include <PiDxe.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/UefiDriverEntryPoint.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Library/UsbDeviceLib.h>
> > +#include <Protocol/UsbDeviceModeProtocol.h>
> > +#include "XdciCommon.h"
> > +#include "XdciDevice.h"
> > +
> > +
> > +///
> > +/// Function declaration
> > +///
> > +EFI_STATUS
> > +UsbdSetupHdlr (
> > +  IN EFI_USB_DEVICE_REQUEST    *CtrlRequest
> > +  );
> > +
> > +extern EFI_USB_DEVICE_MODE_PROTOCOL  mUsbDeviceModeProtocol;
> > +
> > +#endif
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
> > new file mode 100644
> > index 0000000000..a4138328fd
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.c
> > @@ -0,0 +1,2221 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#include "UsbDeviceDxe.h"
> > +
> > +//
> > +// 16 bytes in a guid x 2 characters per byte, 4 chars for dashes and =
a NUL
> > +//
> > +#define CHARS_IN_GUID (sizeof(GUID) * 2 + 4 + 1)
> > +
> > +//
> > +// Strings that get sent with the USB Connection
> > +//
> > +static CHAR16 mUsbFnDxeMfgString[] =3D L"Intel Corporation";
> > +static CHAR16 mUsbFnDxeProductString[] =3D L"Broxton";
> > +static CHAR16 mUsbFnDxeSerialNumber[] =3D L"INT123456";
> > +
> > +//
> > +// Duplicated from MiscSystemManufacturerData.c Some parts of it will
> > +// replaced with device-specific unique values.
> > +//
> > +static GUID mSmBiosUniqueGuid =3D {
> > +        0x5e24fe9c, 0xc8d0, 0x45bd, 0xa7, 0x9f, 0x54, 0xea, 0x5f, 0xbd=
, 0x3d,
> 0x97
> > +    };
> > +
> > +EFI_USBFN_IO_PROTOCOL         mUsbFunIoProtocol =3D {
> > +  EFI_USBFN_IO_PROTOCOL_REVISION,
> > +  DetectPort,
> > +  ConfigureEnableEndpoints,
> > +  GetEndpointMaxPacketSize,
> > +  GetDeviceInfo,
> > +  GetVendorIdProductId,
> > +  AbortTransfer,
> > +  GetEndpointStallState,
> > +  SetEndpointStallState,
> > +  EventHandler,
> > +  Transfer,
> > +  GetMaxTransferSize,
> > +  AllocateTransferBuffer,
> > +  FreeTransferBuffer,
> > +  StartController,
> > +  StopController,
> > +  SetEndpointPolicy,
> > +  GetEndpointPolicy
> > +};
> > +
> > +
> > +EFI_STATUS
> > +PrintEventBuffer(
> > +  IN  EFI_USBFN_IO_PROTOCOL  *This
> > +  )
> > +{
> > +  UINT32                          EventCount;
> > +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> > +  XDCI_CORE_HANDLE                *XdciCorePtr;
> > +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> > +  UINT32                          Index;
> > +  UINT32                          *DbBufPtr;
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  UsbDeviceCorePtr =3D UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr =3D UsbDeviceCorePtr->ControllerHandle;
> > +
> > +  EventCount =3D UsbRegRead ((UINT32)UsbFuncIoDevPtr-
> >XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(0));
> > +
> > +  DbBufPtr =3D (UINT32*)(UINTN)XdciCorePtr->CurrentEventBuffer;
> > +  XdciCorePtr =3D UsbDeviceCorePtr->ControllerHandle;
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: XdciCorePtr-
> >AlignedEventBuffers 0x%08x\n", (UINTN)XdciCorePtr-
> >AlignedEventBuffers));
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: DUMP BUF_S\n"));
> > +  for (Index =3D 0; Index < ((EventCount / 4) + 1); Index++) {
> > +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "0x%08x\n", DbBufPtr[Index]));
> > +  }
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: DUMP BUF_E\n"));
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +Debug End
> > +**/
> > +
> > +/**
> > +  Returns information about what type of device was attached.
> > +
> > +  @param[in]  This               A pointer to the EFI_USBFN_IO_PROTOCO=
L
> instance.
> > +  @param[out] PortType           Returns the USB port type.
> > +
> > +
> > +  @retval EFI_SUCCESS            The operation completed successfully.
> > +  @retval EFI_INVALID_PARAMETER  A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR       The physical device reported an error=
.
> > +  @retval EFI_NOT_READY          The physical device is busy or not re=
ady to
> > +                                 process this request or the device is=
 not
> > +                                 attached to the host.
> > +
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DetectPort (
> > +  IN  EFI_USBFN_IO_PROTOCOL  *This,
> > +  OUT EFI_USBFN_PORT_TYPE    *PortType
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> > +  EFI_STATUS            Status;
> > +  UINT8                 Value8;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_INFO, "DetectPort - Entry\n"));
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  //
> > +  // USBSRCDETRSLT Bit[5:2]
> > +  // Result of USB HW Source Detection algorithm
> > +  // Power-Domain: VRTC
> > +  // Result of USB HW Source Detection algorithm :
> > +  // 0000 =3D Not determined
> > +  // 0001 =3D SDP Attached
> > +  // 0010 =3D DCP Attached
> > +  // 0011 =3D CDP Attached
> > +  // 0100 =3D ACA Attached
> > +  // 0101 =3D SE1 Attached
> > +  // 0110 =3D MHL Attached
> > +  // 0111 =3D Floating D+/D- Attached
> > +  // 1000 =3D Other Attached
> > +  // 1001 =3D DCP detected by ext. USB PHY
> > +  // 1010-1111 =3D Rsvd
> > +  // Reset: 0000B
> > +  //
> > +
> > +  Value8 =3DPmicRead8 (0x5E, 0X29);
> > +  if ((Value8 & 0x03) !=3D 0x02) {
> > +    *PortType =3D EfiUsbUnknownPort;
> > +    Status =3D EFI_NOT_READY;
> > +    goto out;
> > +  }
> > +
> > +  Value8 =3D Value8 >> 2 & 0x0f;
> > +  Status =3D EFI_SUCCESS;
> > +  switch (Value8) {
> > +    case 1:
> > +      *PortType =3D EfiUsbStandardDownstreamPort;
> > +      break;
> > +    case 2:
> > +      *PortType =3D EfiUsbDedicatedChargingPort;
> > +      break;
> > +    case 3:
> > +      *PortType =3D EfiUsbChargingDownstreamPort;
> > +      break;
> > +
> > +    case 4:
> > +    case 5:
> > +    case 6:
> > +    case 7:
> > +    case 8:
> > +    case 9:
> > +      *PortType =3D EfiUsbUnknownPort;
> > +      break;
> > +    case 0:
> > +    case 10:
> > +    case 11:
> > +    case 12:
> > +    case 13:
> > +    case 14:
> > +    case 15:
> > +      *PortType =3D EfiUsbUnknownPort;
> > +      Status =3D EFI_NOT_READY;
> > +     break;
> > +  }
> > +
> > +out:
> > +  DEBUG ((USB_FUIO_DEBUG_INFO, "DetectPort - Exit\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  The AllocateTransferBuffer function allocates a memory region of Siz=
e
> bytes
> > +  and returns the address of the allocated memory that satisfies
> underlying
> > +  controller requirements in the location referenced by Buffer.
> > +
> > +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in] Size               The number of bytes to allocate for th=
e transfer
> > +                                Buffer.
> > +  @param[in] Buffer             A pointer to a pointer to the allocate=
d Buffer
> > +                                if the call succeeds; undefined otherw=
ise.
> > +
> > +  @retval EFI_SUCCESS           The operation completed successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval The requested transfer Buffer could not be allocated.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +AllocateTransferBuffer (
> > +  IN EFI_USBFN_IO_PROTOCOL    *This,
> > +  IN UINTN                    Size,
> > +  OUT VOID                    **Buffer
> > +  )
> > +{
> > +  EFI_STATUS            Status;
> > +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> > +  VOID                  *AllocateBufferPtr;
> > +  USB_MEM_NODE          *NodePtr;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer - Entry\n"));
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  if (Size =3D=3D 0) {
> > +    Status =3D EFI_INVALID_PARAMETER;
> > +    goto ErrorExit;
> > +  }
> > +
> > +  AllocateBufferPtr =3D AllocateZeroPool (Size);
> > +
> > +  if (AllocateBufferPtr =3D=3D NULL) {
> > +    Status =3D EFI_OUT_OF_RESOURCES;
> > +    goto ErrorExit;
> > +  }
> > +
> > +  //
> > +  // Create new node
> > +  //
> > +  Status =3D InsertNewNodeToHead (This, &NodePtr);
> > +  if (EFI_ERROR (Status)) {
> > +    Status =3D EFI_OUT_OF_RESOURCES;
> > +    goto ErrorExit;
> > +  }
> > +
> > +  NodePtr->Size =3D Size;
> > +  NodePtr->AllocatePtr =3D AllocateBufferPtr;
> > +
> > +  *Buffer =3D AllocateBufferPtr;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer addr
> 0x%08x\n", AllocateBufferPtr));
> > +  DEBUG ((USB_FUIO_DEBUG_INFO, "AllocateTransferBuffer - Exit\n"));
> > +  return EFI_SUCCESS;
> > +
> > +ErrorExit:
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_ERROR, "AllocateTransferBuffer - ERRROR
> %r\n",Status));
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Deallocates the memory allocated for the transfer Buffer by
> > +  AllocateTransferBuffer function.
> > +
> > +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in] Buffer             Buffer Pointer to the transfer Buffer
> > +                                to deallocate.
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +FreeTransferBuffer (
> > +  IN EFI_USBFN_IO_PROTOCOL    *This,
> > +  IN VOID                     *Buffer
> > +  )
> > +{
> > +  EFI_STATUS            Status;
> > +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FreeTransferBuffer - Entry\n"));
> > +
> > +  Status =3D RemoveNode (This, Buffer);
> > +  if (EFI_ERROR(Status)) {
> > +    DEBUG ((USB_FUIO_DEBUG_LOAD, "FreeTransferBuffer - ERROR\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FreeTransferBuffer - Exit\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  Configure endpoints Based on supplied device and configuration
> descriptors.
> > +
> > +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in] DeviceInfo         A pointer to EFI_USBFN_DEVICE_INFO
> instance.
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_NOT_READY         The physical device is busy or not rea=
dy to
> > +                                process this request.
> > +  @retval EFI_OUT_OF_RESOURCES  The request could not be completed
> due to
> > +                                lack of resources.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +ConfigureEnableEndpoints (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN EFI_USB_DEVICE_INFO           *DeviceInfo
> > +  )
> > +{
> > +  EFI_STATUS                        Status;
> > +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  Status =3D EFI_SUCCESS;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "ConfigureEnableEndpoints -
> Entry\n"));
> > +  //
> > +  //Assuming that the hardware has already been initialized,
> > +  //this function configures the endpoints using supplied
> > +  //DeviceInfo, activates the port, and starts receiving USB events
> > +  //
> > +  Status =3D EFI_SUCCESS;
> > +  if (DeviceInfo =3D=3D NULL) {
> > +    Status =3D EFI_INVALID_PARAMETER;
> > +    goto FUNC_EXIT;
> > +  }
> > +
> > +  UsbFuncIoDevPtr->DevInfoPtr->DeviceDescriptor =3D DeviceInfo-
> >DeviceDescriptor;
> > +
> > +  //
> > +  // Set Configure table
> > +  //
> > +  if (DeviceInfo->DeviceDescriptor->NumConfigurations > 1) {
> > +    DEBUG ((EFI_D_ERROR, "!!!Error ConfigNum over '1' %d\n", DeviceInf=
o-
> >DeviceDescriptor->NumConfigurations));
> > +  }
> > +  UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor =3D DeviceInfo-
> >ConfigInfoTable[0]->ConfigDescriptor;
> > +  UsbFuncIoDevPtr->IndexPtrConfig.InterfaceInfoTable[0] =3D DeviceInfo=
-
> >ConfigInfoTable[0]->InterfaceInfoTable[0];
> > +
> > +  //
> > +  // Set Interface
> > +  //
> > +  if (DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces =
>
> 1) {
> > +    DEBUG ((EFI_D_ERROR, "!!!Error NumInterfaces[0] over '1' %d\n",
> DeviceInfo->ConfigInfoTable[0]->ConfigDescriptor->NumInterfaces));
> > +  }
> > +  UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor =3D DeviceInfo=
-
> >ConfigInfoTable[0]->InterfaceInfoTable[0]->InterfaceDescriptor;
> > +
> > +  //
> > +  // Set Endpoint
> > +  //
> > +  if (UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor-
> >NumEndpoints > 2) {
> > +    DEBUG ((EFI_D_ERROR, "!!!Error NumEndPoint[0] over '2' %d\n",
> UsbFuncIoDevPtr->IndexPtrInteface.InterfaceDescriptor->NumEndpoints));
> > +  }
> > +
> > +  UsbFuncIoDevPtr->IndexPtrInEp.EndpointCompDesc =3D NULL;
> > +  UsbFuncIoDevPtr->IndexPtrOutEp.EndpointCompDesc =3D NULL;
> > +
> > +  if ((DeviceInfo->ConfigInfoTable[0]->InterfaceInfoTable[0]-
> >EndpointDescriptorTable[0]->EndpointAddress & USB_ENDPOINT_DIR_IN)
> !=3D 0) {
> > +    UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc =3D DeviceInfo-
> >ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0];
> > +    UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc =3D DeviceInfo-
> >ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[1];
> > +  } else {
> > +    UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc =3D DeviceInfo-
> >ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[1];
> > +    UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc =3D DeviceInfo-
> >ConfigInfoTable[0]->InterfaceInfoTable[0]->EndpointDescriptorTable[0];
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, " In Ep Num 0x%02x\n",
> UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc->EndpointAddress));
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, " Out Ep Num 0x%02x\n",
> UsbFuncIoDevPtr->IndexPtrOutEp.EndpointDesc->EndpointAddress));
> > +
> > +FUNC_EXIT:
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "ConfigureEnableEndpoints - exit
> %r\n", Status));
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Returns the maximum packet size of the specified endpoint type for
> > +  the supplied bus Speed.
> > +
> > +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in] EndpointType       Endpoint type as defined as
> EFI_USB_ENDPOINT_TYPE.
> > +  @param[in] BusSpeed           Bus Speed as defined as
> EFI_USB_BUS_SPEED.
> > +  @param[in] MaxPacketSize      The maximum packet size, in bytes,
> > +                                of the specified endpoint type.
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_NOT_READY         The physical device is busy or not rea=
dy to
> > +                                process this request.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetEndpointMaxPacketSize (
> > +  IN EFI_USBFN_IO_PROTOCOL      *This,
> > +  IN EFI_USB_ENDPOINT_TYPE      EndpointType,
> > +  IN EFI_USB_BUS_SPEED          BusSpeed,
> > +  OUT UINT16                    *MaxPacketSize
> > +  )
> > +{
> > +  EFI_STATUS                        Status;
> > +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> > +  USB_DEV_CORE                      *DevCorePtr;
> > +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  DevCorePtr =3D UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr =3D DevCorePtr->ControllerHandle;
> > +  Status =3D EFI_SUCCESS;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointMaxPacketSize -
> Entry\n"));
> > +
> > +  switch (EndpointType) {
> > +    case UsbEndpointControl:
> > +#ifdef SUPPORT_SUPER_SPEED
> > +      *MaxPacketSize =3D USB_EP0_MAX_PKT_SIZE_SS; // Default to super
> Speed
> > +#else
> > +      *MaxPacketSize =3D USB_EP0_MAX_PKT_SIZE_HS; // Default to high
> Speed
> > +#endif
> > +      break;
> > +
> > +    case UsbEndpointBulk:
> > +#ifdef SUPPORT_SUPER_SPEED
> > +      *MaxPacketSize =3D USB_BULK_EP_PKT_SIZE_SS; // Default to super
> Speed
> > +#else
> > +      *MaxPacketSize =3D USB_BULK_EP_PKT_SIZE_HS; // Default to high
> Speed
> > +#endif
> > +      break;
> > +
> > +    case UsbEndpointInterrupt:
> > +      *MaxPacketSize =3D 1;
> > +      break;
> > +
> > +    case UsbEndpointIsochronous:
> > +    default:
> > +      Status =3D EFI_DEVICE_ERROR;
> > +      break;
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointMaxPacketSize - Exit
> %r\n", Status));
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Returns the maximum supported transfer size.
> > +
> > +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in] MaxTransferSize    The maximum supported transfer size, i=
n
> bytes.
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_NOT_READY         The physical device is busy or not rea=
dy to
> > +                                process this request.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetMaxTransferSize (
> > +  IN EFI_USBFN_IO_PROTOCOL     *This,
> > +  OUT UINTN                    *MaxTransferSize
> > +  )
> > +{
> > +  //
> > +  // Need to check, Make max transfer package to 8MB
> > +  //
> > +  *MaxTransferSize =3D MAX_TRANSFER_PACKET;
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  This function returns the unique device ID of the device--this match=
es
> > +  what is populated in the SMBIOS table.
> > +
> > +  @param[in/out] BufferSize     On input, the size of the Buffer in by=
tes.
> > +                                On output, the amount of data returned=
 in Buffer
> > +                                in bytes.
> > +
> > +  @param[out] Buffer            A pointer to a Buffer to return the re=
quested
> > +                                information as a Unicode string. What =
string are
> > +                                we talking about
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_BUFFER_TOO_SMALL  A parameter is invalid.
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +EFIAPI
> > +GetDeviceSerialNumber (
> > +    IN OUT UINTN *BufferSize,
> > +    OUT VOID *Buffer OPTIONAL
> > +  )
> > +{
> > +    EFI_STATUS Status =3D EFI_SUCCESS;
> > +    CHAR16 UuidString[CHARS_IN_GUID];
> > +    UINTN CharsCopied;
> > +
> > +    DEBUG ((USB_FUIO_DEBUG_LOAD, "+GetDeviceSerialNumber\n"));
> > +    //
> > +    // check bounds
> > +    //
> > +    if (*BufferSize < sizeof(UuidString)) {
> > +        Status =3D EFI_BUFFER_TOO_SMALL;
> > +        *BufferSize =3D 0;
> > +        goto Error;
> > +    }
> > +
> > +    //
> > +    // The rest of mSmBiosUniqueGuid will be same. Note that we cannot
> > +    // read the SMBIOS table directly, as it might not be ready by the=
 time
> we
> > +    // are to read it. The population of the data from the eMMC is rea=
dy
> > +    // by the time we are here.
> > +    //
> > +
> > +    //
> > +    // Print to to a string, and copy it off
> > +    //
> > +    CharsCopied =3D UnicodeSPrint(UuidString, sizeof(UuidString), L"%g=
",
> &mSmBiosUniqueGuid);
> > +    if (CharsCopied !=3D (CHARS_IN_GUID - 1))
> > +    {
> > +        Status =3D EFI_BUFFER_TOO_SMALL;
> > +        *BufferSize =3D 0;
> > +        goto Error;
> > +    }
> > +    CopyMem(Buffer, UuidString, sizeof(UuidString));
> > +    *BufferSize =3D sizeof(UuidString);
> > +
> > +Error:
> > +
> > +    DEBUG ((USB_FUIO_DEBUG_LOAD, "-GetDeviceSerialNumber, Status =3D
> 0x%08x\r\n", Status));
> > +
> > +    return Status;
> > +}
> > +
> > +
> > +/**
> > +  Returns device specific information Based on the supplied identifier=
 as
> > +  a Unicode string
> > +
> > +  @param[in] This               A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in] Id                 Requested information id.
> > +  @param[in] BufferSize         On input, the size of the Buffer in by=
tes.
> > +                                On output, the amount of data returned=
 in Buffer
> > +                                in bytes.
> > +  @param[in] Buffer             A pointer to a Buffer to return the re=
quested
> > +                                information as a Unicode string. What =
string are
> > +                                we talking about
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_NOT_READY         The physical device is busy or not rea=
dy to
> > +                                process this request.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetDeviceInfo (
> > +  IN EFI_USBFN_IO_PROTOCOL      *This,
> > +  IN EFI_USBFN_DEVICE_INFO_ID   Id,
> > +  IN OUT UINTN                  *BufferSize,
> > +  OUT VOID                      *Buffer OPTIONAL
> > +  )
> > +{
> > +  EFI_STATUS                    Status;
> > +  USB_XDCI_DEV_CONTEXT          *UsbFuncIoDevPtr;
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  Status =3D EFI_SUCCESS;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetDeviceInfo - Entry\n"));
> > +
> > +  if ((BufferSize =3D=3D 0) || (Buffer =3D=3D NULL)) {
> > +    Status =3D EFI_INVALID_PARAMETER;
> > +    goto FUN_EXIT;
> > +  }
> > +
> > +  switch (Id) {
> > +
> > +    //
> > +    // FIXME: Get real serial number of board
> > +    //
> > +    case EfiUsbDeviceInfoSerialNumber:
> > +        if (*BufferSize < sizeof(mUsbFnDxeSerialNumber)) {
> > +            Status =3D EFI_BUFFER_TOO_SMALL;
> > +            *BufferSize =3D 0;
> > +            goto FUN_EXIT;
> > +        }
> > +        CopyMem(Buffer, mUsbFnDxeSerialNumber,
> sizeof(mUsbFnDxeSerialNumber));
> > +        *BufferSize =3D sizeof(mUsbFnDxeSerialNumber);
> > +        break;
> > +
> > +    case EfiUsbDeviceInfoManufacturerName:
> > +        if (*BufferSize < sizeof(mUsbFnDxeMfgString)) {
> > +            Status =3D EFI_BUFFER_TOO_SMALL;
> > +            *BufferSize =3D 0;
> > +            goto FUN_EXIT;
> > +        }
> > +        CopyMem(Buffer, mUsbFnDxeMfgString,
> sizeof(mUsbFnDxeMfgString));
> > +        *BufferSize =3D sizeof(mUsbFnDxeMfgString);
> > +        break;
> > +
> > +    case EfiUsbDeviceInfoProductName:
> > +        if (*BufferSize < sizeof(mUsbFnDxeProductString)) {
> > +            Status =3D EFI_BUFFER_TOO_SMALL;
> > +            *BufferSize =3D 0;
> > +            goto FUN_EXIT;
> > +        }
> > +        CopyMem(Buffer, mUsbFnDxeProductString,
> sizeof(mUsbFnDxeProductString));
> > +        *BufferSize =3D sizeof(mUsbFnDxeProductString);
> > +        break;
> > +
> > +    case EfiUsbDeviceInfoUnknown:
> > +    default:
> > +      Status =3D EFI_UNSUPPORTED;
> > +      *BufferSize =3D 0;
> > +      DEBUG ((USB_FUIO_DEBUG_ERROR, "Unknown ID %d
> encountered.\r\n", Id));
> > +      break;
> > +  }
> > +
> > +FUN_EXIT:
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - ConfigDescriptor
> addr 0x%08x \n", (UINTN)UsbFuncIoDevPtr-
> >IndexPtrConfig.ConfigDescriptor));
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetDeviceInfo - Exit %r\n", Status));
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Returns vendor-id and product-id of the device.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[out] Vid               Returned vendor-id of the device.
> > +  @param[out] Pid               Returned product-id of the device.
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_NOT_FOUND         Unable to return vid or pid.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetVendorIdProductId (
> > +  IN EFI_USBFN_IO_PROTOCOL      *This,
> > +  OUT UINT16                    *Vid,
> > +  OUT UINT16                    *Pid
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  //
> > +  //   *Vid =3D 0x8086
> > +  //   *Pid =3D 0x0A65
> > +  //
> > +  *Vid =3D UsbFuncIoDevPtr->VendorId;
> > +  *Pid =3D UsbFuncIoDevPtr->DeviceId;
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  Aborts transfer on the specified endpoint.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  EndpointIndex     Indicates the endpoint on which the
> ongoing
> > +                                transfer needs to be canceled.
> > +  @param[in]  Direction         Direction of the endpoint.
> > +
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_NOT_READY         The physical device is busy or not rea=
dy to
> > +                                process this request.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +AbortTransfer (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> > +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> > +  USB_DEV_CORE                      *UsbDeviceCorePtr;
> > +  USB_EP_INFO                       EpInfo;
> > +  EFI_STATUS                        Status;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:AbortTransfer - Entry\n"));
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  UsbDeviceCorePtr =3D UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr =3D UsbDeviceCorePtr->ControllerHandle;
> > +  Status =3D EFI_SUCCESS;
> > +
> > +  if (UsbFuncIoDevPtr->DevResetFlag =3D=3D TRUE) {
> > +    return Status;
> > +  }
> > +
> > +  EpInfo.EpNum =3D EndpointIndex;
> > +  EpInfo.EpDir =3D Direction? UsbEpDirIn : UsbEpDirOut;
> > +
> > +  Status =3D UsbDeviceEpCancelTransfer (UsbFuncIoDevPtr->DrvCore,
> &EpInfo);
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:AbortTransfer - Exit %r\n",
> Status));
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Returns the stall state on the specified endpoint.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  EndpointIndex     Indicates the endpoint on which the
> ongoing
> > +                                transfer needs to be canceled.
> > +  @param[in]  Direction         Direction of the endpoint.
> > +  @param[in]  State             Boolean, true value indicates that the=
 endpoint
> > +                                is in a stalled state, false otherwise=
.
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_NOT_READY         The physical device is busy or not rea=
dy to
> > +                                process this request.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetEndpointStallState (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> > +  IN OUT BOOLEAN                  *State
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> > +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> > +  UINT32                            EndPoint;
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointStallState - Entry\n"));
> > +
> > +  EndPoint =3D UsbGetPhysicalEpNum (EndpointIndex, Direction ?
> UsbEpDirIn : UsbEpDirOut);
> > +
> > +  XdciCorePtr =3D UsbFuncIoDevPtr->XdciDrvIfHandle;
> > +
> > +  if (XdciCorePtr->EpHandles[EndPoint].State =3D=3D USB_EP_STATE_STALL=
ED) {
> > +    *State =3D TRUE;
> > +  } else {
> > +    *State =3D FALSE;
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointStallState - Exit\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +UsbSetAddress (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT32                        Address
> > +  )
> > +{
> > +  EFI_STATUS                        Status;
> > +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> > +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> > +  USB_DEV_CORE                      *UsbDeviceCorePtr;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetAddress - 0x%04x Entry\n",
> Address));
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  UsbDeviceCorePtr =3D UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr =3D UsbDeviceCorePtr->ControllerHandle;
> > +  Status =3D EFI_SUCCESS;
> > +
> > +  Status =3D UsbDeviceSetAddress (UsbDeviceCorePtr, (UINT32)Address);
> > +
> > +  if (Status !=3D EFI_SUCCESS) {
> > +    Status =3D EFI_DEVICE_ERROR;
> > +    goto EXIT_SET_ADDRESS;
> > +  }
> > +
> > +  Status =3D UsbDeviceEp0TxStatus (UsbDeviceCorePtr);
> > +
> > +  if (Status !=3D EFI_SUCCESS) {
> > +    Status =3D EFI_NO_RESPONSE;
> > +    goto EXIT_SET_ADDRESS;
> > +  }
> > +
> > +EXIT_SET_ADDRESS:
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetAddress - Exit %r\n", Status));
> > +  return Status;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +UsbSetconfigure (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT32                       InterFaceIndex
> > +  )
> > +{
> > +  EFI_STATUS                      Status;
> > +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> > +  XDCI_CORE_HANDLE                *XdciCorePtr;
> > +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> > +  UINT32                          InterfaceNum;
> > +  UINT32                          EndPointNum;
> > +  UINT32                          EndPointIndex;
> > +  EFI_USB_INTERFACE_INFO          *InterfaceInfoPtr;
> > +  USB_EP_INFO                     EpInfo;
> > +  USB_DEVICE_ENDPOINT_INFO        EpDescInfo;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - 0x%04x Entry\n",
> InterFaceIndex));
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  UsbDeviceCorePtr =3D UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr =3D UsbDeviceCorePtr->ControllerHandle;
> > +  Status =3D EFI_SUCCESS;
> > +
> > +  InterfaceNum =3D UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor-
> >NumInterfaces;
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - ConfigDescriptor
> addr 0x%08x \n", (UINTN)UsbFuncIoDevPtr-
> >IndexPtrConfig.ConfigDescriptor));
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - DescriptorType
> 0x%04x ; ConfigurationValue 0x%04x\n",
> > +          UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor-
> >DescriptorType,
> > +          UsbFuncIoDevPtr->IndexPtrConfig.ConfigDescriptor-
> >ConfigurationValue
> > +          ));
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - InterfaceNum
> 0x%04x \n", InterfaceNum));
> > +  if (InterfaceNum < InterFaceIndex) {
> > +    Status =3D EFI_INVALID_PARAMETER;
> > +    goto EXIT__SET_CONFIGURE;
> > +  }
> > +
> > +  //
> > +  // Arry strart form '0', Index start from '1'.
> > +  //
> > +  InterfaceInfoPtr =3D UsbFuncIoDevPtr-
> >IndexPtrConfig.InterfaceInfoTable[InterFaceIndex - 1];
> > +  EndPointNum =3D InterfaceInfoPtr->InterfaceDescriptor->NumEndpoints;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - Total EP NUM
> 0x%04x \n", EndPointNum));
> > +
> > +  for (EndPointIndex =3D 0; EndPointIndex < EndPointNum; EndPointIndex=
++)
> {
> > +    EpDescInfo.EndpointDesc =3D InterfaceInfoPtr-
> >EndpointDescriptorTable[EndPointIndex];
> > +    EpDescInfo.EndpointCompDesc =3D NULL;
> > +    UsbFnSetEpInfo (&EpInfo, &EpDescInfo);
> > +    DEBUG ((USB_FUIO_DEBUG_LOAD, "EndpointAddress 0x%02x\n",
> EpDescInfo.EndpointDesc->EndpointAddress));
> > +
> > +    if (UsbDeviceInitEp (UsbDeviceCorePtr, &EpInfo) =3D=3D EFI_SUCCESS=
) {
> > +       if (UsbDeviceEpEnable (UsbDeviceCorePtr, &EpInfo) =3D=3D EFI_SU=
CCESS) {
> > +       } else {
> > +         Status =3D EFI_DEVICE_ERROR;
> > +         DEBUG ((DEBUG_INFO, "UsbDeviceEpEnable() - Failed to enable
> endpoint\n"));
> > +       }
> > +    } else {
> > +       Status =3D EFI_DEVICE_ERROR;
> > +       DEBUG ((DEBUG_INFO, "UsbDeviceInitEp() - Failed to initialize
> endpoint\n"));
> > +    }
> > +  }
> > +
> > +  Status =3D UsbDeviceEp0TxStatus (UsbDeviceCorePtr);
> > +
> > +  if (Status !=3D EFI_SUCCESS) {
> > +    Status =3D EFI_NO_RESPONSE;
> > +    goto EXIT__SET_CONFIGURE;
> > +  }
> > +
> > +
> > +EXIT__SET_CONFIGURE:
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbSetconfigure - Exit %r\n",
> Status));
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  Sets or clears the stall state on the specified endpoint.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  EndpointIndex     Indicates the endpoint on which the
> ongoing
> > +                                transfer needs to be canceled.
> > +  @param[in]  Direction         Direction of the endpoint.
> > +  @param[in]  State             Requested stall state on the specified=
 endpoint.
> > +                                True value causes the endpoint to stal=
l;
> > +                                false value clears an existing stall.
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_NOT_READY         The physical device is busy or not rea=
dy to
> > +                                process this request.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +SetEndpointStallState (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> > +  IN BOOLEAN                      State
> > +  )
> > +{
> > +  EFI_STATUS                        Status;
> > +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> > +  USB_EP_INFO                       pEpInfo;
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "SetEndpointStallState - Entry\n"));
> > +  Status =3D EFI_SUCCESS;
> > +
> > +  pEpInfo.EpNum =3D EndpointIndex;
> > +  pEpInfo.EpDir =3D Direction? UsbEpDirIn : UsbEpDirOut;
> > +
> > +  if (State =3D=3D TRUE) {
> > +    Status =3D UsbDeviceEpStall (UsbFuncIoDevPtr->DrvCore, (VOID*)(UIN=
TN)
> &pEpInfo);
> > +  } else {
> > +    Status =3D UsbDeviceEpClearStall (UsbFuncIoDevPtr->DrvCore,
> (VOID*)(UINTN) &pEpInfo);
> > +  }
> > +
> > +  if (Status !=3D EFI_SUCCESS) {
> > +    Status =3D EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "SetEndpointStallState - Exit\n"));
> > +  return Status;
> > +}
> > +
> > +EFI_STATUS
> > +DeviceEventCheck(
> > +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> > +  IN  USBD_EVENT_BUF              *EventIndex,
> > +  OUT UINT32                      *ProcessSize,
> > +  OUT EFI_USBFN_MESSAGE           *Message,
> > +  OUT BOOLEAN                     *EventFlag
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> > +  UINT32                          EventReg;
> > +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> > +  XDCI_CORE_HANDLE                *XdciCorePtr;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "\n FUEV::DeviceEvent
> entry....\n"));
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  UsbDeviceCorePtr =3D UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr =3D UsbDeviceCorePtr->ControllerHandle;
> > +  EventReg =3D (EventIndex->Event &
> DWC_XDCI_EVENT_BUFF_DEV_EVT_MASK);
> > +  EventReg >>=3D DWC_XDCI_EVENT_BUFF_DEV_EVT_BIT_POS;
> > +  *EventFlag =3D FALSE;
> > +
> > +  //
> > +  // Assume default event size. Change it in switch case if
> > +  // different
> > +  //
> > +  *ProcessSize =3D  DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
> > +
> > +  switch (EventReg) {
> > +    case DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT\n"));
> > +      *Message =3D EfiUsbMsgBusEventDetach;
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT\n"));
> > +      //
> > +      //  In resetDet will prepare setup Xfer package
> > +      //
> > +      UsbFuncIoDevPtr->DevReConnect =3D FALSE;
> > +      UsbFuncIoDevPtr->DevResetFlag =3D TRUE;
> > +
> > +      usbProcessDeviceResetDet (XdciCorePtr);
> > +      UsbDeviceSetAddress (UsbDeviceCorePtr, 0);
> > +      *Message =3D EfiUsbMsgBusEventReset;
> > +      *EventFlag =3D TRUE;
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT\n"));
> > +      usbProcessDeviceResetDone(XdciCorePtr);
> > +      UsbDeviceSetAddress(UsbDeviceCorePtr, 0);
> > +      UsbFuncIoDevPtr->DevReConnect =3D TRUE;
> > +      UsbFuncIoDevPtr->DevResetFlag =3D FALSE;
> > +      *EventFlag =3D TRUE;
> > +      *Message =3D EfiUsbMsgNone;
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT\n"));
> > +      *Message =3D EfiUsbMsgBusEventSuspend;
> > +      *EventFlag =3D TRUE;
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT\n"));
> > +      *Message =3D EfiUsbMsgBusEventResume;
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT:
> > +      *ProcessSize =3D DWC_XDCI_DEV_EVENT_TST_LMP_SIZE_IN_BYTES;
> > +      *Message =3D EfiUsbMsgNone;
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D,
> "USBFUDwcXdciProcessDeviceEvent: UNHANDLED device event: %x\n",
> EventReg));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_Device
> DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT\n"));
> > +      break;
> > +
> > +    default:
> > +      *EventFlag =3D FALSE;
> > +      *Message =3D EfiUsbMsgNone;
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_I,
> "USBFUWcXdciProcessDeviceEvent: UNHANDLED device event: %x\n",
> EventReg));
> > +      break;
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "\n FUEV::DeviceEvent entry
> exit.... \n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +Ep0XferDone(
> > +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> > +  IN  UINT32                      EndPointNum,
> > +  OUT EFI_USBFN_MESSAGE           *Message,
> > +  IN OUT UINTN                    *PayloadSize,
> > +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
> > +  )
> > +{
> > +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> > +  XDCI_CORE_HANDLE                *XdciCorePtr;
> > +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> > +  DWC_XDCI_ENDPOINT               *EpHandle;
> > +  DWC_XDCI_TRB                    *Trb;
> > +  UINT32                          TrbCtrl;
> > +  UINT32                          TrbSts;
> > +  UINT32                          BufferLen;
> > +  EFI_STATUS                      DevStatus;
> > +  USB_EP_INFO                     EpInfo;
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  UsbDeviceCorePtr =3D UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr =3D UsbDeviceCorePtr->ControllerHandle;
> > +  EpHandle =3D &XdciCorePtr->EpHandles[EndPointNum];
> > +  Trb =3D XdciCorePtr->Trbs + (EndPointNum * DWC_XDCI_TRB_NUM);
> > +
> > +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> > +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0XferDone. HW owns TRB:
> %x!!!\n", (UINT32)(UINTN)Trb));
> > +  }
> > +
> > +  DevStatus =3D EFI_SUCCESS;
> > +  BufferLen =3D 0;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "EndPointNum:%d, TRB: Addr
> 0x%08x!!!\n", EndPointNum, (UINTN)Trb));
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->TrbCtrl: %x!!!\n",
> (UINT32)Trb->TrbCtrl));
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->LenXferParams:
> %x!!!\n", (UINT32)Trb->LenXferParams));
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->BuffPtrLow:
> %x!!!\n", (UINT32)Trb->BuffPtrLow));
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done Trb->BuffPtrHigh:
> %x!!!\n", (UINT32)Trb->BuffPtrHigh));
> > +
> > +  //
> > +  // Set CheckFlag to FALSE for 'DwcXdciEpRxData' function
> > +  // check the RX request complete and continue next transfer request
> > +  //
> > +  EpHandle->CheckFlag =3D FALSE;
> > +  EpHandle->CurrentXferRscIdx =3D 0;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D01!!\n"));
> > +  TrbCtrl =3D (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_TYPE_MASK) >>
> DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D02!!\n"));
> > +  TrbSts =3D (Trb->LenXferParams & DWC_XDCI_TRB_STATUS_MASK) >>
> DWC_XDCI_TRB_STATUS_BIT_POS;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D03!!\n" ));
> > +  BufferLen =3D Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D04 TrbCtrl :: %x!!\n",
> TrbCtrl));
> > +  switch (TrbCtrl) {
> > +    case DWC_XDCI_TRB_CTRL_TYPE_SETUP:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Ep0 done
> DWC_XDCI_TRB_CTRL_TYPE_SETUP!!\n"));
> > +      //
> > +      // This is delay for other host USB controller(none Intel), iden=
tify
> device get fail issue.
> > +      //
> > +      gBS->Stall(130);
> > +      BufferLen =3D 8;
> > +
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D,
> "DWC_XDCI_TRB_CTRL_TYPE_SETUP!!\n"));
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D,
> "AlignedSetupBuffer::0x%08x!!\n", XdciCorePtr->AlignedSetupBuffer));
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Payload::0x%08x!!\n",
> (UINTN)Payload));
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "BufferLen::0x%08x!!\n",
> (UINTN)BufferLen));
> > +      *Message =3D EfiUsbMsgSetupPacket;
> > +      CopyMem (Payload, XdciCorePtr->AlignedSetupBuffer, BufferLen);
> > +
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D06!!\n"));
> > +      if (!(XdciCorePtr->AlignedSetupBuffer[0] &
> USB_SETUP_DATA_PHASE_DIRECTION_MASK)) {
> > +        if ((XdciCorePtr->AlignedSetupBuffer[0]  =3D=3D 0x00) ) {
> > +          if ((XdciCorePtr->AlignedSetupBuffer[1]  =3D=3D
> USB_DEV_SET_ADDRESS)) {
> > +            //
> > +            // set address
> > +            //
> > +            UsbSetAddress (
> > +              This,
> > +              (UINT32)(XdciCorePtr->AlignedSetupBuffer[3] << 8 | XdciC=
orePtr-
> >AlignedSetupBuffer[2])
> > +              );
> > +
> > +            *Message =3D EfiUsbMsgNone;
> > +          } else if ((XdciCorePtr->AlignedSetupBuffer[1]  =3D=3D
> USB_DEV_SET_CONFIGURATION)) {
> > +            DEBUG ((USB_FUIO_DEBUG_EVENT_I, "\n set configure !!!"));
> > +            UsbSetconfigure (
> > +              This,
> > +              (UINT32)(XdciCorePtr->AlignedSetupBuffer[3] << 8 | XdciC=
orePtr-
> >AlignedSetupBuffer[2])
> > +              );
> > +            *Message =3D EfiUsbMsgNone;
> > +          }
> > +        }
> > +      }
> > +
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "Ep0 done D07!!\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_TRB_CTRL_TYPE_DATA:
> > +      DEBUG ((DEBUG_INFO, "Ep0 done
> DWC_XDCI_TRB_CTRL_TYPE_DATA!!\n"));
> > +	  //
> > +      // Notify upper layer of control transfer completion
> > +      // if a callback function was registerd
> > +      //
> > +      if ((EndPointNum & 0x01) =3D=3D 0) {
> > +        *Message =3D EfiUsbMsgEndpointStatusChangedRx;
> > +      } else {
> > +        *Message =3D EfiUsbMsgEndpointStatusChangedTx;
> > +      }
> > +      Payload->utr.EndpointIndex =3D (UINT8)(EndPointNum >> 1);
> > +      Payload->utr.Direction =3D (UINT8)(EndPointNum & 0x01);
> > +      Payload->utr.Buffer =3D (VOID*)(UINTN)(Trb->BuffPtrLow);
> > +
> > +      DEBUG ((DEBUG_INFO, "Ep0 EndPointNum: %x!!!\n",
> (UINT32)EndPointNum));
> > +      DEBUG ((DEBUG_INFO, "Ep0 done XferLength: %x!!!\n",
> (UINT32)UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].XferLength));
> > +      Payload->utr.Buffer =3D (VOID*)UsbFuncIoDevPtr-
> >EndPointXferRec[EndPointNum].XferAddress;
> > +      Payload->utr.BytesTransferred =3D UsbFuncIoDevPtr-
> >EndPointXferRec[EndPointNum].XferLength;
> > +
> > +      if (TrbSts =3D=3D 0) {
> > +        if ((Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK) =3D=3D =
0) {
> > +          Payload->utr.TransferStatus =3D UsbTransferStatusComplete;
> > +        } else {
> > +          Payload->utr.TransferStatus =3D UsbTransferStatusActive;
> > +        }
> > +      } else if (TrbSts !=3D 0) {
> > +        Trb->TrbCtrl |=3D DWC_XDCI_TRB_CTRL_HWO_MASK;
> > +        *Message =3D EfiUsbMsgNone;
> > +        Payload->utr.TransferStatus =3D UsbTransferStatusAborted;
> > +        DEBUG ((DEBUG_INFO, "Flush FIFO!!!\n" ));
> > +        EpInfo.EpNum =3D 0;
> > +        EpInfo.EpDir =3DUsbEpDirIn;
> > +        UsbXdciCoreFlushEpFifo(XdciCorePtr, &EpInfo);
> > +        EpInfo.EpNum =3D 0;
> > +        EpInfo.EpDir =3DUsbEpDirOut;
> > +        UsbXdciCoreFlushEpFifo(XdciCorePtr, &EpInfo);
> > +        DevStatus =3D UsbDeviceEp0RxSetup (UsbDeviceCorePtr, XdciCoreP=
tr-
> >AlignedSetupBuffer);
> > +      }
> > +
> > +      break;
> > +
> > +    case DWC_XDCI_TRB_CTRL_TYPE_STATUS2:
> > +    case DWC_XDCI_TRB_CTRL_TYPE_STATUS3:
> > +      Payload->utr.Buffer =3D (VOID*) UsbFuncIoDevPtr-
> >EndPointXferRec[EndPointNum].XferAddress;
> > +      Payload->utr.BytesTransferred =3D 0;
> > +      Payload->utr.EndpointIndex =3D (UINT8)(EndPointNum >> 1);
> > +      if ((EndPointNum & 0x01) =3D=3D 0) {
> > +        *Message =3D EfiUsbMsgEndpointStatusChangedRx;
> > +      } else {
> > +        *Message =3D EfiUsbMsgEndpointStatusChangedTx;
> > +      }
> > +
> > +      if (TrbSts =3D=3D 0) {
> > +        if ((Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK) =3D=3D =
0) {
> > +          Payload->utr.TransferStatus =3D UsbTransferStatusComplete;
> > +        } else {
> > +          Payload->utr.TransferStatus =3D UsbTransferStatusActive;
> > +        }
> > +      } else if (TrbSts !=3D 0) {
> > +        Payload->utr.TransferStatus =3D UsbTransferStatusAborted;
> > +      }
> > +
> > +      DevStatus =3D UsbDeviceEp0RxSetup (UsbDeviceCorePtr, XdciCorePtr=
-
> >AlignedSetupBuffer);
> > +
> > +      if (DevStatus) {
> > +        DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: FAILED
> to queue SETUP\n"));
> > +      }
> > +      DEBUG ((DEBUG_INFO, "Status phase done. Queue next SETUP
> packet=3D=3D>\n"));
> > +      break;
> > +
> > +    default:
> > +      *Message =3D EfiUsbMsgNone;
> > +      DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone:
> UNHANDLED STATE in TRB\n"));
> > +      break;
> > +  }
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +NoneEp0XferDone(
> > +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> > +  IN  UINT32                      EndPointNum,
> > +  OUT EFI_USBFN_MESSAGE           *Message,
> > +  IN OUT UINTN                    *PayloadSize,
> > +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
> > +  )
> > +{
> > +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> > +  XDCI_CORE_HANDLE                *XdciCorePtr;
> > +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> > +  DWC_XDCI_ENDPOINT               *EpHandle;
> > +  DWC_XDCI_TRB                    *Trb;
> > +  UINT32                          TrbCtrl;
> > +  UINT32                          TrbSts;
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  UsbDeviceCorePtr =3D UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr =3D UsbDeviceCorePtr->ControllerHandle;
> > +  EpHandle =3D &XdciCorePtr->EpHandles[EndPointNum];
> > +  Trb =3D XdciCorePtr->Trbs + (EndPointNum * DWC_XDCI_TRB_NUM);
> > +
> > +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> > +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "NoneEp0XferDone. HW owns
> TRB: %x!!!, EndPointNum: %x\n", (UINT32)(UINTN)Trb, EndPointNum));
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " TRB: Addr 0x%08x!!!\n",
> (UINTN)Trb));
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->BuffPtrLow:
> %x!!!\n", (UINT32)Trb->BuffPtrLow));
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->BuffPtrHigh:
> %x!!!\n", (UINT32)Trb->BuffPtrHigh));
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->LenXferParams:
> %x!!!\n", (UINT32)Trb->LenXferParams));
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, " Xfer done Trb->TrbCtrl:
> %x!!!\n", (UINT32)Trb->TrbCtrl));
> > +
> > +  //
> > +  // Set CheckFlag to FALSE for 'DwcXdciEpRxData' function
> > +  // check the RX request complete and continue next transfer request
> > +  //
> > +  EpHandle->CheckFlag =3D FALSE;
> > +  EpHandle->CurrentXferRscIdx =3D 0;
> > +  *Message =3D EfiUsbMsgNone;
> > +
> > +  TrbCtrl =3D (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_TYPE_MASK) >>
> DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
> > +  TrbSts =3D (Trb->LenXferParams & DWC_XDCI_TRB_STATUS_MASK) >>
> DWC_XDCI_TRB_STATUS_BIT_POS;
> > +
> > +  Payload->utr.BytesTransferred =3D UsbFuncIoDevPtr-
> >EndPointXferRec[EndPointNum].XferLength;
> > +  Payload->utr.EndpointIndex =3D UsbFuncIoDevPtr-
> >EndPointXferRec[EndPointNum].LogEpNum;
> > +  Payload->utr.Direction =3D UsbFuncIoDevPtr-
> >EndPointXferRec[EndPointNum].Direction;
> > +  Payload->utr.Buffer =3D (VOID*)(UINTN)(Trb->BuffPtrLow);
> > +  UsbFuncIoDevPtr->EndPointXferRec[EndPointNum].Complete =3D TRUE;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "EndPointAddress =3D 0x%08x\n",
> Payload->utr.EndpointIndex));
> > +  if (Payload->utr.Direction =3D=3D EfiUsbEndpointDirectionDeviceTx) {
> > +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "
> Direction::EfiUsbEndpointDirectionDeviceTx\n"));
> > +    *Message =3D EfiUsbMsgEndpointStatusChangedTx;
> > +  } else {
> > +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "
> Direction::EfiUsbEndpointDirectionDeviceRx\n"));
> > +    *Message =3D EfiUsbMsgEndpointStatusChangedRx;
> > +  }
> > +
> > +  if (TrbSts =3D=3D 0) {
> > +    if ((Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK) =3D=3D 0) {
> > +      Payload->utr.TransferStatus =3D UsbTransferStatusComplete;
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D,
> "XferStatus::UsbTransferStatusComplete\n"));
> > +    } else {
> > +      Payload->utr.TransferStatus =3D UsbTransferStatusComplete;
> > +      Payload->utr.BytesTransferred -=3D (Trb->LenXferParams &
> DWC_XDCI_TRB_BUFF_SIZE_MASK);
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D,
> "XferStatus::UsbTransferStatusComplete\n"));
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "XferStatus::Length %d \n",
> Payload->utr.BytesTransferred ));
> > +    }
> > +  } else if (TrbSts !=3D 0) {
> > +    Payload->utr.TransferStatus =3D UsbTransferStatusAborted;
> > +    DEBUG ((USB_FUIO_DEBUG_EVENT_D,
> "XferStatus::UsbTransferStatusAborted\n"));
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +EFI_STATUS
> > +Ep0XferNotReady(
> > +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> > +  IN  UINT32                      EndPointNum,
> > +  OUT EFI_USBFN_MESSAGE           *Message,
> > +  IN OUT UINTN                    *PayloadSize,
> > +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload,
> > +  IN  UINT32                      EpStatus
> > +  )
> > +{
> > +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> > +  XDCI_CORE_HANDLE                *XdciCorePtr;
> > +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL(This);
> > +  UsbDeviceCorePtr =3D UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr =3D UsbDeviceCorePtr->ControllerHandle;
> > +
> > +  *Message =3D EfiUsbMsgNone;
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +EpEventCheck(
> > +  IN  EFI_USBFN_IO_PROTOCOL       *This,
> > +  IN  USBD_EVENT_BUF              *EventIndex,
> > +  OUT UINT32                      *ProcessSize,
> > +  OUT EFI_USBFN_MESSAGE           *Message,
> > +  IN OUT UINTN                    *PayloadSize,
> > +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload,
> > +  OUT BOOLEAN                     *EventFlag
> > +  )
> > +{
> > +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> > +  XDCI_CORE_HANDLE                *XdciCorePtr;
> > +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> > +  UINT32                          EventReg;
> > +  UINT32                          EpEvent;
> > +  UINT32                          EndPointNumber;
> > +  UINT32                          EventStatus;
> > +  USB_EP_STATE                    Ep_State;
> > +  UINTN                           TmpBufferSize;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::EndPoint Event....\n"));
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL(This);
> > +
> > +  UsbDeviceCorePtr =3D UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr =3D UsbDeviceCorePtr->ControllerHandle;
> > +  EventReg =3D EventIndex->Event;
> > +  *ProcessSize =3D DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
> > +  *EventFlag =3D TRUE;
> > +  TmpBufferSize =3D 0;
> > +
> > +  //
> > +  // Get EP num
> > +  //
> > +  EndPointNumber =3D (EventReg &
> DWC_XDCI_EVENT_BUFF_EP_NUM_MASK) >>
> DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS;
> > +
> > +  EventStatus =3D EventReg &
> DWC_XDCI_EVENT_BUFF_EP_EVENT_STATUS_MASK;
> > +
> > +  //
> > +  // Interpret event and handle transfer completion here
> > +  //
> > +  EpEvent =3D (EventReg & DWC_XDCI_EVENT_BUFF_EP_EVENT_MASK) >>
> DWC_XDCI_EVENT_BUFF_EP_EVENT_BIT_POS;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFU_EP EventReg 0x%08x\n",
> EventReg));
> > +
> > +  switch (EpEvent) {
> > +    case DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP
> DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT\n"));
> > +      if (EndPointNumber > 1) {
> > +        DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP None_Control
> transfer\n"));
> > +        NoneEp0XferDone (This, EndPointNumber, Message, PayloadSize,
> Payload);
> > +      } else {
> > +        //
> > +        // Control transfer
> > +        //
> > +        DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP Control
> transfer\n"));
> > +        Ep0XferDone (This, EndPointNumber, Message, PayloadSize,
> Payload);
> > +      }
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D,
> "DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY\n"));
> > +      *Message =3D EfiUsbMsgNone;
> > +      if(EndPointNumber < (sizeof(UsbFuncIoDevPtr->EndPointXferRec) /
> sizeof(UsbFuncIoDevPtr->EndPointXferRec[0]))) {
> > +        if ((UsbFuncIoDevPtr->EndPointXferRec[EndPointNumber].ZlpFlag =
=3D=3D
> TRUE) && \
> > +              (UsbFuncIoDevPtr->EndPointXferRec[EndPointNumber].Comple=
te
> =3D=3D TRUE)) {
> > +          DEBUG ((USB_FUIO_DEBUG_EVENT_D, "Request send ZLP\n"));
> > +          if ((EndPointNumber & 0x01) !=3D 0) {
> > +            Transfer(This,
> > +                     UsbFuncIoDevPtr->IndexPtrInEp.EndpointDesc-
> >EndpointAddress,
> > +                     EfiUsbEndpointDirectionDeviceTx,
> > +                     &TmpBufferSize,
> > +                     NULL
> > +                    );
> > +            UsbFuncIoDevPtr->EndPointXferRec[EndPointNumber].ZlpFlag =
=3D
> FALSE;
> > +          }
> > +
> > +        }
> > +      } else {
> > +        //
> > +        // Is it data stage or status stage
> > +        //
> > +        // Data Statge
> > +        //
> > +        Ep_State =3D USB_EP_STATE_DATA;
> > +        //
> > +        // Control transfer
> > +        //
> > +        DEBUG ((USB_FUIO_DEBUG_EVENT_D, "USBFU_EP Control transfer
> not ready\n"));
> > +        Ep0XferNotReady (This, EndPointNumber, Message, PayloadSize,
> Payload, EventStatus);
> > +        *EventFlag =3D FALSE;
> > +      }
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_D,
> "DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS\n"));
> > +      break;
> > +
> > +    default:
> > +      DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFUDwcXdciProcessEpEvent:
> UNKNOWN EP event\n"));
> > +      break;
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV::EndPoint
> Event....exit\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +ProcessIntLineEvents(
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT32                       EventCount,
> > +  IN UINT32                       *ProceSsEvent,
> > +  OUT EFI_USBFN_MESSAGE           *Message,
> > +  IN OUT UINTN                    *PayloadSize,
> > +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload,
> > +  OUT BOOLEAN                     *EventFlag
> > +  )
> > +{
> > +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> > +  XDCI_CORE_HANDLE                *XdciCorePtr;
> > +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> > +  UINT32                          CurrentEventAddr;
> > +  UINT32                          ProceSsEventSize;
> > +  BOOLEAN                         EventReport;
> > +  BOOLEAN                         EpEventReport;
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  UsbDeviceCorePtr =3D UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr =3D UsbDeviceCorePtr->ControllerHandle;
> > +  CurrentEventAddr =3D (UINT32)(UINTN)(XdciCorePtr->CurrentEventBuffer=
);
> > +  EventReport =3D FALSE;
> > +  EpEventReport =3D FALSE;
> > +  ProceSsEventSize =3D 0;
> > +   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: ProcessIntLineEvents
> Entry\n"));
> > +
> > +   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: XdciCorePtr-
> >CurrentEventBuffer 0x%08x\n", XdciCorePtr->CurrentEventBuffer));
> > +   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::EventCount0x%08x\n",
> EventCount));
> > +   DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV::CurrentEventAddr
> 0x%08x\n", CurrentEventAddr));
> > +
> > +  while ((EventCount !=3D 0) && (EventReport =3D=3D FALSE)) {
> > +     DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV::event0x%08x\n",
> XdciCorePtr->CurrentEventBuffer->Event));
> > +     if ((XdciCorePtr->CurrentEventBuffer->Event &
> DWC_XDCI_EVENT_DEV_MASK) !=3D 0) {
> > +       //
> > +       // Device event
> > +       //
> > +       DeviceEventCheck (
> > +         This,
> > +         (USBD_EVENT_BUF*)(UINTN)CurrentEventAddr,
> > +         &ProceSsEventSize,
> > +         Message,
> > +         &EventReport
> > +         );
> > +       if (EventReport =3D=3D TRUE) {
> > +         *EventFlag =3D TRUE;
> > +       }
> > +
> > +     } else {
> > +       //
> > +       // EndPoint Event
> > +       //
> > +       EpEventCheck (
> > +         This,
> > +         (USBD_EVENT_BUF*)(UINTN)CurrentEventAddr,
> > +         &ProceSsEventSize,
> > +         Message,
> > +         PayloadSize,
> > +         Payload,
> > +         &EpEventReport
> > +         );
> > +     }
> > +
> > +     if ((*Message !=3D EfiUsbMsgNone) || (EpEventReport =3D=3D TRUE))=
 {
> > +       EventReport =3D TRUE;
> > +       *EventFlag =3D TRUE;
> > +     }
> > +
> > +     DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: CurrentEventAddr
> 0x%08x :: ProceSsEventSize 0x%08x\n",
> (UINTN)CurrentEventAddr,ProceSsEventSize));
> > +
> > +     EventCount -=3D ProceSsEventSize;
> > +     *ProceSsEvent +=3D ProceSsEventSize;
> > +     if ((CurrentEventAddr + ProceSsEventSize) >=3D \
> > +         ((UINT32)(UINTN)(XdciCorePtr->AlignedEventBuffers) +
> > +          (sizeof(DWC_XDCI_EVENT_BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER))) {
> > +       CurrentEventAddr =3D (UINT32)(UINTN)(XdciCorePtr-
> >AlignedEventBuffers);
> > +    } else {
> > +      CurrentEventAddr +=3D ProceSsEventSize;
> > +    }
> > +    DEBUG ((USB_FUIO_DEBUG_EVENT_D, "FUEV:: CurrentEventAddr
> Update 0x%08x :: ProceSsEventSize 0x%08x\n",
> CurrentEventAddr,ProceSsEventSize));
> > +
> > +    XdciCorePtr->CurrentEventBuffer =3D
> (DWC_XDCI_EVENT_BUFFER*)(UINTN)CurrentEventAddr;
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "FUEV:: ProcessIntLineEvents
> Exit\n\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  ISR inokes Event Handler.  Look at which interrupt has happened and =
see
> > +  if there are event handler registerd and if so fire them 1 by one.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  Message           Indicates the event that initiated thi=
s
> > +                                notification.
> > +  @param[in]  PayloadSize       On input, the size of the memory point=
ed by
> Payload.
> > +                                On output, the amount of data returned=
 in Payload.
> > +  @param[in]  Payload           A pointer to EFI_USBFN_MESSAGE_PAYLOAD
> instance to
> > +                                return additional payload for current =
message.
> > +
> > +
> > +
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_NOT_READY         The physical device is busy or not rea=
dy to
> > +                                process this request.
> > +  @retval EFI_BUFFER_TOO_SMALL  Supplied Buffer not large enough to
> hold
> > +                                the message payload.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +EventHandler(
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  OUT EFI_USBFN_MESSAGE           *Message,
> > +  IN OUT UINTN                    *PayloadSize,
> > +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
> > +  )
> > +{
> > +  UINT32                          EventCount;
> > +  UINT32                          PeventCount;
> > +  USB_XDCI_DEV_CONTEXT            *UsbFuncIoDevPtr;
> > +  UINT32                          MaxIntNum;
> > +  UINT32                          IntIndex;
> > +  USB_DEV_CORE                    *UsbDeviceCorePtr;
> > +  XDCI_CORE_HANDLE                *XdciCorePtr;
> > +  BOOLEAN                         EventFlag;
> > +  EFI_TPL                         OriginalTpl;
> > +
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFU_ EventHandler Entry\n"));
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  if (UsbFuncIoDevPtr->StartUpController =3D=3D FALSE) {
> > +    UsbFnInitDevice (This);
> > +  }
> > +  OriginalTpl =3D gBS->RaiseTPL (TPL_HIGH_LEVEL);
> > +  *Message =3D EfiUsbMsgNone;
> > +  MaxIntNum =3D (UsbRegRead ((UINT32)UsbFuncIoDevPtr-
> >XdciMmioBarAddr, DWC_XDCI_GHWPARAMS1_REG) &
> > +                 DWC_XDCI_GHWPARAMS1_NUM_INT_MASK) >>
> > +                 DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS;
> > +
> > +  UsbDeviceCorePtr =3D UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr =3D UsbDeviceCorePtr->ControllerHandle;
> > +  EventFlag =3D TRUE;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "XdciCorePtr->MaxDevIntLines
> 0x%08x\n", XdciCorePtr->MaxDevIntLines));
> > +  EventCount =3D UsbRegRead ((UINT32)UsbFuncIoDevPtr-
> >XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(0));
> > +
> > +  for (IntIndex =3D 0; IntIndex < XdciCorePtr->MaxDevIntLines ; IntInd=
ex++) {
> > +    //
> > +    // Get the number of events HW has written for this
> > +    //  interrupt line
> > +    //
> > +    EventCount =3D UsbRegRead ((UINT32)UsbFuncIoDevPtr-
> >XdciMmioBarAddr, DWC_XDCI_EVNTCOUNT_REG(IntIndex));
> > +    EventCount &=3D DWC_XDCI_EVNTCOUNT_MASK;
> > +    PeventCount =3D 0;
> > +
> > +    //
> > +    // Process interrupt line Buffer only if count is non-zero
> > +    //
> > +    if (EventCount) {
> > +      //
> > +      // Process events in this Buffer
> > +      //
> > +      ProcessIntLineEvents (
> > +        This,
> > +        EventCount,
> > +        &PeventCount,
> > +        Message,
> > +        PayloadSize,
> > +        Payload,
> > +        &EventFlag
> > +        );
> > +
> > +      //
> > +      // Write back the Processed number of events so HW decrements it
> from current
> > +      // event count
> > +      //
> > +      UsbRegWrite ((UINT32)UsbFuncIoDevPtr->XdciMmioBarAddr,
> DWC_XDCI_EVNTCOUNT_REG(IntIndex), PeventCount);
> > +
> > +      //
> > +      // for debug
> > +      //
> > +      if (*Message !=3D EfiUsbMsgNone) {
> > +        break;
> > +      }
> > +
> > +      if (EventFlag =3D=3D TRUE) {
> > +        break;
> > +      }
> > +    }
> > +  }
> > +
> > +  gBS->RestoreTPL (OriginalTpl);
> > +  //
> > +  //EVENT_EXIT:
> > +  //
> > +  DEBUG ((USB_FUIO_DEBUG_EVENT_I, "USBFU_ EventHandler Exit\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +
> > +/**
> > +  Copies relevant endpoint data from standard USB endpoint descriptors
> > +  to the usbEpInfo structure used by the XDCI
> > +
> > +  @param pEpDest   destination structure
> > +  @param pEpSrc    source structure
> > +
> > +  @return VOID
> > +
> > +**/
> > +VOID
> > +UsbFnSetEpInfo (
> > +  IN USB_EP_INFO                 *EpDest,
> > +  IN USB_DEVICE_ENDPOINT_INFO    *EpSrc
> > +  )
> > +{
> > +  EFI_USB_ENDPOINT_DESCRIPTOR              *EpDesc =3D NULL;
> > +  EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpCompDesc =3D NULL;
> > +
> > +  //
> > +  // start by clearing all data in the destination
> > +  //
> > +  SetMem (EpDest, sizeof(USB_EP_INFO), 0);
> > +  EpDesc =3D EpSrc->EndpointDesc;
> > +  EpCompDesc =3D EpSrc->EndpointCompDesc;
> > +
> > +  if (EpDesc !=3D NULL) {
> > +    EpDest->EpNum =3D EpDesc->EndpointAddress & 0x0F; // Bits 0-3 are =
ep
> num
> > +    EpDest->EpDir =3D ((EpDesc->EndpointAddress & USB_ENDPOINT_DIR_IN)
> > 0) ? UsbEpDirIn : UsbEpDirOut;
> > +    DEBUG ((DEBUG_INFO, "EpDest->EpNum 0x%02x\n", EpDest->EpNum));
> > +    DEBUG ((DEBUG_INFO, "EpDest->EpDir 0x%02x\n", EpDest->EpDir));
> > +    EpDest->EpType =3D EpDesc->Attributes & USB_ENDPOINT_TYPE_MASK;
> > +    EpDest->MaxPktSize =3D EpDesc->MaxPacketSize;
> > +    EpDest->Interval =3D EpDesc->Interval;
> > +  }
> > +  if (EpCompDesc !=3D NULL) {
> > +    EpDest->MaxStreams =3D EpCompDesc->Attributes &
> USB_EP_BULK_BM_ATTR_MASK;
> > +    EpDest->BurstSize =3D EpCompDesc->MaxBurst;
> > +    EpDest->Mult =3D EpCompDesc->BytesPerInterval;
> > +  }
> > +
> > +  return;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +SetFnIoReqInfo(
> > +  IN     EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN     UINT8                         EndpointIndex,
> > +  IN     EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> > +  IN OUT UINTN                         *BufferSize,
> > +  IN OUT VOID                          *Buffer,
> > +  IN OUT USB_XFER_REQUEST              *XfIoreq
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT     *UsbFuncIoDevPtr;
> > +  EFI_STATUS               Status;
> > +  UINTN                    ReqPacket;
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  Status =3D EFI_SUCCESS;
> > +  ReqPacket =3D 0;
> > +
> > +  switch (EndpointIndex) {
> > +    case 0: // Control endpoint
> > +      XfIoreq->EpInfo.EpNum =3D 0;
> > +      XfIoreq->EpInfo.EpDir =3D Direction? UsbEpDirIn : UsbEpDirOut;
> > +      break;
> > +
> > +
> > +    default:
> > +      if (Direction =3D=3D EfiUsbEndpointDirectionDeviceTx) {
> > +        UsbFnSetEpInfo (&XfIoreq->EpInfo, &UsbFuncIoDevPtr-
> >IndexPtrInEp);
> > +      } else {
> > +        UsbFnSetEpInfo (&XfIoreq->EpInfo, &UsbFuncIoDevPtr-
> >IndexPtrOutEp);
> > +        //
> > +        // reference from "UsbDeviceMode.c", function UsbdEpRxData
> > +        //
> > +
> > +        //
> > +        // Transfer length should be multiple of USB packet size.
> > +        //
> > +        ReqPacket =3D *BufferSize/ XfIoreq->EpInfo.MaxPktSize;
> > +        ReqPacket =3D ((XfIoreq->XferLen % XfIoreq->EpInfo.MaxPktSize)=
 =3D=3D 0)?
> ReqPacket : ReqPacket + 1;
> > +        XfIoreq->XferLen =3D (UINT32)ReqPacket * XfIoreq->EpInfo.MaxPk=
tSize;
> > +
> > +      }
> > +      break;
> > +  }
> > +
> > +  if (EFI_ERROR(Status)) {
> > +    return EFI_UNSUPPORTED;
> > +  }
> > +
> > +  XfIoreq->XferBuffer =3D Buffer;
> > +  XfIoreq->XferLen =3D (UINT32)(*BufferSize);
> > +  XfIoreq->XferDone =3D NULL;
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Primary function to handle transfer in either direction Based on spe=
cified
> > +  direction and on the specified endpoint.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  EndpointIndex     Indicates the endpoint on which TX or =
RX
> transfer
> > +                                needs to take place.
> > +  @param[in]  Direction         Direction of the endpoint.
> > +  @param[in]  BufferSize        If Direction is
> EfiUsbEndpointDirectionDeviceRx:
> > +                                On input, the size of the Buffer in by=
tes.
> > +                                On output, the amount of data returned=
 in Buffer in
> bytes.
> > +                                If Direction is EfiUsbEndpointDirectio=
nDeviceTx:
> > +                                On input, the size of the Buffer in by=
tes.
> > +                                On output, the amount of data actually=
 transmitted in
> bytes.
> > +  @param[in]  Buffer            If Direction is
> EfiUsbEndpointDirectionDeviceRx:
> > +                                The Buffer to return the received data=
.
> > +                                If Direction is EfiUsbEndpointDirectio=
nDeviceTx:
> > +                                The Buffer that contains the data to b=
e transmitted.
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_NOT_READY         The physical device is busy or not rea=
dy to
> > +                                process this request.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +Transfer (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN UINT8                         EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> > +  IN OUT UINTN                     *BufferSize,
> > +  IN OUT VOID                      *Buffer
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT              *UsbFuncIoDevPtr;
> > +  USB_DEV_CORE                      *UsbDeviceCorePtr;
> > +  XDCI_CORE_HANDLE                  *XdciCorePtr;
> > +  EFI_STATUS                        Status;
> > +  USB_XFER_REQUEST                  XferReq;
> > +  UINT32                            EndPoint;
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:Transfer - Entry\n"));
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:EndpointIndex 0x%02x\n",
> EndpointIndex));
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "\n FU:Direction 0x%02x\n",
> Direction));
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  UsbDeviceCorePtr =3D UsbFuncIoDevPtr->DrvCore;
> > +  XdciCorePtr =3D UsbDeviceCorePtr->ControllerHandle;
> > +  EndPoint =3D UsbGetPhysicalEpNum (EndpointIndex, Direction ?
> UsbEpDirIn : UsbEpDirOut);
> > +
> > +  Status =3D SetFnIoReqInfo (
> > +             This,
> > +             EndpointIndex,
> > +             Direction,
> > +             BufferSize,
> > +             Buffer,
> > +             &XferReq
> > +             );
> > +
> > +  if (EFI_ERROR(Status)) {
> > +    DEBUG ((USB_FUIO_DEBUG_LOAD, "Set SetFnIoReqInfo - Error
> Stop!!!\n"));
> > +    while(1);
> > +    Status =3D EFI_DEVICE_ERROR;
> > +    goto FUN_EXIT;
> > +  }
> > +
> > +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].EpNum =3D EndPoint;
> > +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].Direction =3D Direction;
> > +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].XferAddress =3D
> (UINTN)Buffer;
> > +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].XferLength =3D
> (UINT32)(*BufferSize);
> > +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].LogEpNum =3D
> EndpointIndex;
> > +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].Complete =3D FALSE;
> > +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag =3D FALSE;
> > +
> > +  Status =3D EFI_DEVICE_ERROR;
> > +  switch (EndpointIndex) {
> > +    case 0: // Control endpoint
> > +      if (*BufferSize =3D=3D 0) {
> > +        if (Direction =3D=3D EfiUsbEndpointDirectionDeviceTx) {
> > +          Status =3D UsbDeviceEp0TxStatus(UsbDeviceCorePtr);
> > +        } else {
> > +          Status =3D UsbDeviceEp0RxStatus(UsbDeviceCorePtr);
> > +        }
> > +      } else if (Direction =3D=3D EfiUsbEndpointDirectionDeviceTx) {
> > +        Status =3D UsbXdciDeviceEpTxData(UsbDeviceCorePtr, &XferReq);
> > +      } else if (Direction =3D=3D EfiUsbEndpointDirectionDeviceRx) {
> > +        DEBUG ((USB_FUIO_DEBUG_LOAD, "\n Set Setup Package - ???
> Stop!!!\n"));
> > +      }
> > +      break;
> > +
> > +    default:
> > +      Status =3D EFI_SUCCESS;
> > +      if (Direction =3D=3D EfiUsbEndpointDirectionDeviceTx) {
> > +        DEBUG ((USB_FUIO_DEBUG_LOAD, "\n
> EfiUsbEndpointDirectionDeviceTx Size =3D %d\n",(*BufferSize) ));
> > +        XferReq.Zlp =3D TRUE;
> > +        if ((((*BufferSize) % 512) =3D=3D 0) && ((*BufferSize) !=3D 0)=
) {
> > +          UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag =3D TRUE;
> > +          DEBUG ((USB_FUIO_DEBUG_LOAD, "\n Set Zlp flag\n"));
> > +        }
> > +        Status =3D UsbXdciDeviceEpTxData (UsbDeviceCorePtr, &XferReq);
> > +      } else {
> > +        DEBUG ((USB_FUIO_DEBUG_LOAD, "\n
> EfiUsbEndpointDirectionDeviceRx Size =3D %d\n",(*BufferSize) ));
> > +        Status =3D UsbXdciDeviceEpRxData (UsbDeviceCorePtr, &XferReq);
> > +      }
> > +      break;
> > +  }
> > +
> > +  if (EFI_ERROR(Status)) {
> > +    goto FUN_EXIT;
> > +  }
> > +
> > +  if (Status !=3D EFI_SUCCESS) {
> > +    Status =3D EFI_DEVICE_ERROR;
> > +  }
> > +
> > +FUN_EXIT:
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "FU:Transfer - Exit %r\n", Status));
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  This function supplies power to the USB controller if needed, initia=
lize
> > +  hardware and internal data structures, and then return.
> > +  The port must not be activated by this function.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +StartXdciController (
> > +  IN EFI_USBFN_IO_PROTOCOL    *This
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT         *UsbFuncIoDevPtr;
> > +  USB_DEV_CONFIG_PARAMS        ConfigParams;
> > +  EFI_STATUS                   Status;
> > +
> > +  Status =3D EFI_SUCCESS;
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  if (UsbFuncIoDevPtr->StartUpController =3D=3D TRUE) {
> > +    goto EXIT_START_CONTROLLER;
> > +  }
> > +
> > +  ConfigParams.ControllerId =3D USB_ID_DWC_XDCI;
> > +  ConfigParams.BaseAddress =3D (UINT32)UsbFuncIoDevPtr-
> >XdciMmioBarAddr;
> > +  ConfigParams.Role =3D USB_ROLE_DEVICE;
> > +  ConfigParams.Speed =3D USB_SPEED_HIGH;
> > +
> > +  //
> > +  //*Vid =3D 0x8086
> > +  //*Pid =3D 0x0A65
> > +  //
> > +  UsbFuncIoDevPtr->VendorId =3D USBFU_VID;
> > +  UsbFuncIoDevPtr->DeviceId =3D USBFU_PID;
> > +  UsbFuncIoDevPtr->StartUpController =3D TRUE;
> > +
> > +  Status =3D UsbDeviceInit (&ConfigParams, (VOID **)&UsbFuncIoDevPtr-
> >DrvCore);
> > +  if (Status !=3D EFI_SUCCESS) {
> > +    Status =3D EFI_DEVICE_ERROR;
> > +    goto EXIT_START_CONTROLLER;
> > +  }
> > +
> > +  UsbFuncIoDevPtr->XdciDrvIfHandle =3D UsbFuncIoDevPtr->DrvCore-
> >ControllerHandle;
> > +
> > +EXIT_START_CONTROLLER:
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "StartXdciController - Exit :: %r\n",
> Status));
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  This function disables the hardware device by resetting the run/stop=
 bit
> > +  and power off the USB controller if needed.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +StopXdciController (
> > +  IN EFI_USBFN_IO_PROTOCOL    *This
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> > +  EFI_STATUS            DevStatus;
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "StopController - Entry\n"));
> > +
> > +  if (UsbFuncIoDevPtr->StartUpController =3D=3D FALSE) {
> > +    DEBUG ((USB_FUIO_DEBUG_LOAD, "The Controller not yet start up skip
> deinit\n"));
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  if (This =3D=3D NULL) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  DevStatus =3D UsbDeviceDeinit (UsbFuncIoDevPtr->DrvCore, TRUE);
> > +
> > +  UsbFuncIoDevPtr->DrvCore =3D NULL;
> > +  UsbFuncIoDevPtr->XdciDrvIfHandle =3D NULL;
> > +  UsbFuncIoDevPtr->StartUpController =3D FALSE;
> > +
> > +  if (DevStatus !=3D EFI_SUCCESS) {
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "StopController - Exit\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  This function sets the configuration policy for the specified non-co=
ntrol
> endpoint.
> > +  Refer to the description for calling restrictions
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  EndpointIndex     Indicates the non-control endpoint for
> > +                                which the policy needs to be set.
> > +  @param[in]  Direction         Direction of the endpoint.
> > +  @param[in]  PolicyType        Policy type the user is trying to set =
for
> > +                                the specified non-control endpoint.
> > +  @param[in]  BufferSize        The size of the Buffer in bytes.
> > +  @param[in]  Buffer            The new value for the policy parameter=
 that
> > +                                PolicyType specifies.
> > +
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_UNSUPPORTED       Changing this policy value is not
> supported.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +SetEndpointPolicy (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> > +  IN EFI_USBFN_POLICY_TYPE        PolicyType,
> > +  IN UINTN                        BufferSize,
> > +  IN VOID                         *Buffer
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> > +  EFI_STATUS            Status;
> > +  UINT32                EndPoint;
> > +  UINT8                 *FlagPtr;
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  FlagPtr =3D NULL;
> > +
> > +  switch (PolicyType) {
> > +    case EfiUsbPolicyUndefined:
> > +    case EfiUsbPolicyMaxTransactionSize:
> > +    case EfiUsbPolicyZeroLengthTerminationSupport:
> > +
> > +     Status =3D EFI_UNSUPPORTED;
> > +     break;
> > +
> > +    default:
> > +     FlagPtr =3D Buffer;
> > +     Status =3D EFI_SUCCESS;
> > +     break;
> > +  }
> > +
> > +  if (BufferSize < 1) {
> > +    Status =3D EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  if (EFI_ERROR(Status)) {
> > +    DEBUG ((USB_FUIO_DEBUG_LOAD, "SetEndpointPolicy - ERROR %r\n",
> Status));
> > +    return Status;
> > +  }
> > +
> > +  EndPoint =3D UsbGetPhysicalEpNum (EndpointIndex, Direction ?
> UsbEpDirIn : UsbEpDirOut);
> > +
> > +  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag =3D *FlagPtr;
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  This function retrieves the configuration policy for the specified n=
on-
> control
> > +  endpoint. There are no associated calling restrictions for this func=
tion.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  EndpointIndex     Indicates the non-control endpoint for
> > +                                which the policy needs to be set.
> > +  @param[in]  Direction         Direction of the endpoint.
> > +  @param[in]  PolicyType        Policy type the user is trying to set =
for
> > +                                the specified non-control endpoint.
> > +  @param[in]  BufferSize        The size of the Buffer in bytes.
> > +  @param[in]  Buffer            The new value for the policy parameter=
 that
> > +                                PolicyType specifies.
> > +
> > +
> > +  @retval EFI_SUCCESS           The function returned successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_DEVICE_ERROR      The physical device reported an error.
> > +  @retval EFI_UNSUPPORTED       Changing this policy value is not
> supported.
> > +  @retval EFI_BUFFER_TOO_SMALL  Supplied Buffer is not large enough to
> > +                                hold requested policy value.
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +GetEndpointPolicy (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> > +  IN EFI_USBFN_POLICY_TYPE        PolicyType,
> > +  IN OUT UINTN                    *BufferSize,
> > +  IN OUT VOID                     *Buffer
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT  *UsbFuncIoDevPtr;
> > +  EFI_STATUS            Status;
> > +  UINT32                EndPoint;
> > +  UINT32                MaxPacketSize;
> > +  BOOLEAN               SetFlag;
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +  MaxPacketSize =3D 0;
> > +  SetFlag =3D FALSE;
> > +
> > +  switch (PolicyType) {
> > +    case EfiUsbPolicyUndefined:
> > +
> > +     Status =3D EFI_UNSUPPORTED;
> > +     break;
> > +
> > +    case EfiUsbPolicyMaxTransactionSize:
> > +    case EfiUsbPolicyZeroLengthTerminationSupport:
> > +    default:
> > +     if (Buffer =3D=3D NULL) {
> > +       Status =3D EFI_INVALID_PARAMETER;
> > +     } else {
> > +       Status =3D EFI_SUCCESS;
> > +     }
> > +     break;
> > +  }
> > +
> > +  EndPoint =3D UsbGetPhysicalEpNum (EndpointIndex, Direction ?
> UsbEpDirIn : UsbEpDirOut);
> > +
> > +  if (EFI_ERROR(Status)) {
> > +    DEBUG ((USB_FUIO_DEBUG_LOAD, "GetEndpointPolicy - ERROR %r\n",
> Status));
> > +    return Status;
> > +  }
> > +
> > +  if (PolicyType =3D=3D EfiUsbPolicyMaxTransactionSize) {
> > +
> > +    if (*BufferSize < sizeof(UINT32)) {
> > +       Status =3D EFI_INVALID_PARAMETER;
> > +    } else {
> > +      MaxPacketSize =3D MAX_TRANSFER_PACKET;
> > +      CopyMem (Buffer, &MaxPacketSize, sizeof(UINT32));
> > +    }
> > +
> > +  } else if (PolicyType =3D=3D EfiUsbPolicyZeroLengthTerminationSuppor=
t) {
> > +    if (*BufferSize < sizeof(BOOLEAN)) {
> > +       Status =3D EFI_INVALID_PARAMETER;
> > +    } else {
> > +      SetFlag =3D TRUE;
> > +      CopyMem (Buffer, &SetFlag, sizeof(BOOLEAN));
> > +    }
> > +
> > +  } else if (PolicyType =3D=3D EfiUsbPolicyZeroLengthTermination) {
> > +    if (*BufferSize < sizeof(BOOLEAN)) {
> > +       Status =3D EFI_INVALID_PARAMETER;
> > +    } else {
> > +      SetFlag =3D  UsbFuncIoDevPtr->EndPointXferRec[EndPoint].ZlpFlag;
> > +      CopyMem (Buffer, &SetFlag, sizeof(BOOLEAN));
> > +    }
> > +  } else {
> > +    Status =3D EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +EFI_STATUS
> > +UsbFnInitDevice (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This
> > +  )
> > +{
> > +  EFI_STATUS                   Status;
> > +  USB_XDCI_DEV_CONTEXT         *UsbFuncIoDevPtr;
> > +
> > +  Status =3D EFI_SUCCESS;
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  PlatformSpecificInit ();
> > +
> > +  UsbFuncIoDevPtr->StartUpController =3D FALSE;
> > +  Status =3D StartXdciController (&UsbFuncIoDevPtr->UsbFunIoProtocol);
> > +  if (EFI_ERROR (Status)) {
> > +    Status =3D EFI_DEVICE_ERROR;
> > +    goto DEV_INIT_EXIT;
> > +  }
> > +
> > +  Status =3D UsbXdciDeviceConnect (UsbFuncIoDevPtr->DrvCore);
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbXdciDeviceConnect Status
> %x\n", Status));
> > +  if (Status !=3D EFI_SUCCESS) {
> > +    Status =3D EFI_DEVICE_ERROR;
> > +    goto DEV_INIT_EXIT;
> > +  }
> > +
> > +
> > +DEV_INIT_EXIT:
> > +
> > +  return Status;
> > +}
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +StartController (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This
> > +  )
> > +{
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +UsbFnDeInitDevice (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This
> > +  )
> > +{
> > +  EFI_STATUS                   Status;
> > +  USB_XDCI_DEV_CONTEXT         *UsbFuncIoDevPtr;
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  if (UsbFuncIoDevPtr->StartUpController =3D=3D FALSE) {
> > +    DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbFn:StopController:The
> Controller not yet start up force return EFI_SUCCESS\n"));
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  //
> > +  // disconnect
> > +  //
> > +  Status =3D UsbDeviceDisconnect (UsbFuncIoDevPtr->DrvCore);
> > +  DEBUG ((USB_FUIO_DEBUG_LOAD, "UsbDeviceDisconnect Status %x\n",
> Status));
> > +  if (Status !=3D EFI_SUCCESS) {
> > +    Status =3D EFI_DEVICE_ERROR;
> > +    goto DEV_DEINIT_EXIT;
> > +  }
> > +
> > +  //
> > +  // StopController
> > +  //
> > +  Status =3D StopXdciController (&UsbFuncIoDevPtr->UsbFunIoProtocol);
> > +  UsbFuncIoDevPtr->StartUpController =3D FALSE;
> > +
> > +DEV_DEINIT_EXIT:
> > +  return Status;
> > +}
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +StopController (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This
> > +  )
> > +{
> > +  return UsbFnDeInitDevice(This);
> > +}
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
> > new file mode 100644
> > index 0000000000..ad3d296db9
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbFuncIo.h
> > @@ -0,0 +1,234 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#ifndef __EFI_USB_FUNCTION_IO_INTERFACE_H__
> > +#define __EFI_USB_FUNCTION_IO_INTERFACE_H__
> > +
> > +#include <Uefi.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DevicePathLib.h>
> > +#include <Library/DriverLib.h>
> > +#include <Library/PcdLib.h>
> > +#include <Protocol/EfiUsbFnIo.h>
> > +#include <Library/PmicLib.h>
> > +#include <Library/UsbDeviceLib.h>
> > +#include <Library/PrintLib.h>
> > +#include "UsbIoNode.h"
> > +#include "XdciDWC.h"
> > +#include "UsbDeviceMode.h"
> > +
> > +//
> > +// Debug message setting
> > +//
> > +#define USB_FUIO_DEBUG_INFO              EFI_D_INFO
> > +#define USB_FUIO_DEBUG_LOAD              EFI_D_LOAD
> > +#define USB_FUIO_DEBUG_ERROR             EFI_D_ERROR
> > +#define USB_FUIO_DEBUG_EVENT_I           0 //DEBUG_INIT
> > +#define USB_FUIO_DEBUG_EVENT_D           EFI_D_ERROR
> > +#define USB_FUIO_DEBUG_EVENT_NOTREADY_D  EFI_D_ERROR
> > +#define USB_FUIO_DEBUG_EVENT_NOTREADY_I  0 //DEBUG_INIT
> > +
> > +#define MAX_TRANSFER_PACKET     (8 * 1024 * 1024)
> > +
> > +#define USBFU_VID     0x8086
> > +#define USBFU_PID     0x0A65
> > +
> > +#pragma pack(1)
> > +typedef struct {
> > +  UINT8                     ProgInterface;
> > +  UINT8                     SubClassCode;
> > +  UINT8                     BaseCode;
> > +} USB_CLASSC;
> > +
> > +//
> > +// Event Buffer Struct
> > +//
> > +typedef struct  {
> > +  UINT32 Event;
> > +  UINT32 DevTstLmp1;
> > +  UINT32 DevTstLmp2;
> > +  UINT32 Reserved;
> > +} USBD_EVENT_BUF;
> > +
> > +typedef struct  {
> > +  UINT32                        EpNum;
> > +  EFI_USBFN_ENDPOINT_DIRECTION  Direction;
> > +  UINTN                         XferAddress;
> > +  UINT32                        XferLength;
> > +  UINT8                         LogEpNum;
> > +  BOOLEAN                       Complete;
> > +  BOOLEAN                       ZlpFlag;
> > +} USBD_EP_XFER_REC;
> > +
> > +#pragma pack()
> > +
> > +EFI_STATUS
> > +UsbFnInitDevice (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This
> > +  );
> > +
> > +EFI_STATUS
> > +UsbFnDeInitDevice (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DetectPort (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  OUT EFI_USBFN_PORT_TYPE          *PortType
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +AllocateTransferBuffer (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN UINTN                         Size,
> > +  OUT VOID                         **Buffer
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +FreeTransferBuffer (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN VOID                          *Buffer
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +ConfigureEnableEndpoints (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN EFI_USB_DEVICE_INFO           *DeviceInfo
> > + );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +GetEndpointMaxPacketSize (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN EFI_USB_ENDPOINT_TYPE         EndpointType,
> > +  IN EFI_USB_BUS_SPEED             BusSpeed,
> > +  OUT UINT16                       *MaxPacketSize
> > + );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +GetMaxTransferSize (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  OUT UINTN                        *MaxTransferSize
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +GetDeviceInfo (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN EFI_USBFN_DEVICE_INFO_ID      Id,
> > +  IN OUT UINTN                     *BufferSize,
> > +  OUT VOID                         *Buffer OPTIONAL
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +GetVendorIdProductId (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  OUT UINT16                       *Vid,
> > +  OUT UINT16                       *Pid
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +AbortTransfer (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +GetEndpointStallState (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN UINT8                         EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> > +  IN OUT BOOLEAN                   *State
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +SetEndpointStallState (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN UINT8                         EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> > +  IN BOOLEAN                       State
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +EventHandler (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  OUT EFI_USBFN_MESSAGE            *Message,
> > +  IN OUT UINTN                     *PayloadSize,
> > +  OUT EFI_USBFN_MESSAGE_PAYLOAD    *Payload
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +Transfer (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN UINT8                         EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> > +  IN OUT UINTN                     *BufferSize,
> > +  IN OUT VOID                      *Buffer
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +StartController (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +StopController (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +SetEndpointPolicy (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN UINT8                         EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> > +  IN EFI_USBFN_POLICY_TYPE         PolicyType,
> > +  IN UINTN                         BufferSize,
> > +  IN VOID                          *Buffer
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +GetEndpointPolicy (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN UINT8                         EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> > +  IN EFI_USBFN_POLICY_TYPE         PolicyType,
> > +  IN OUT UINTN                     *BufferSize,
> > +  IN OUT VOID                      *Buffer
> > +  );
> > +
> > +VOID
> > +UsbFnSetEpInfo (
> > +  IN USB_EP_INFO                 *EpDest,
> > +  IN USB_DEVICE_ENDPOINT_INFO    *EpSrc
> > +  );
> > +
> > +extern EFI_USBFN_IO_PROTOCOL         mUsbFunIoProtocol;
> > +#endif
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
> > new file mode 100644
> > index 0000000000..8fc6e10046
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.c
> > @@ -0,0 +1,177 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#include "UsbDeviceDxe.h"
> > +
> > +
> > +/**
> > +  The SearchNode function search a memory address for record the drive=
r
> allocate
> > +  memory region and the node to the head link list.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  Buffer            The driver alocate memory address.
> > +  @param[out] Node              The match node record of the driver al=
oocate
> > +                                memory region.
> > +  @param[out] PNode             The pervious match node record of the
> driver
> > +                                aloocate memory region.
> > +
> > +  @retval EFI_SUCCESS           The operation completed successfully.
> > +  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
> > +**/
> > +EFI_STATUS
> > +SearchNode (
> > +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> > +  IN  VOID                     *Buffer,
> > +  OUT USB_MEM_NODE             **Node,
> > +  OUT USB_MEM_NODE             **PNode
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
> > +  USB_MEM_NODE         *NodeL;
> > +  USB_MEM_NODE         *PNodeL;
> > +  EFI_STATUS           Status;
> > +
> > +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "SearchNode - Entry\n"));
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL(This);
> > +  NodeL =3D UsbFuncIoDevPtr->FirstNodePtr;
> > +  PNodeL =3D NULL;
> > +  Status =3D EFI_NOT_FOUND;
> > +
> > +  while (Node !=3D NULL) {
> > +    if (NodeL->AllocatePtr =3D=3D Buffer) {
> > +      break;
> > +    }
> > +
> > +    PNodeL =3D NodeL;
> > +    NodeL =3D NodeL->NextPtr;
> > +  }
> > +
> > +  if (NodeL !=3D NULL && Node !=3D NULL) {
> > +    *Node =3D NodeL;
> > +    *PNode =3D PNodeL;
> > +    Status =3D EFI_SUCCESS;
> > +  }
> > +
> > +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "SearchNode - Exit %r\n",
> Status));
> > +  return Status;
> > +}
> > +
> > +/**
> > +  The InsertNewNodeToHead function remove a memory for record the
> driver allocate
> > +  memory region and the node to the head link list.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  Buffer            The driver alocate memory address.
> > +
> > +  @retval EFI_SUCCESS           The operation completed successfully.
> > +  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
> > +**/
> > +EFI_STATUS
> > +RemoveNode (
> > +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> > +  IN  VOID                     *Buffer
> > +  )
> > +{
> > +  USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
> > +  USB_MEM_NODE         *Node;
> > +  USB_MEM_NODE         *PNode;
> > +  EFI_STATUS           Status;
> > +
> > +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "RemoveNode - Entry\n"));
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL (This);
> > +
> > +  Status =3D SearchNode (This, Buffer, &Node, &PNode);
> > +
> > +  if (EFI_ERROR(Status) || PNode =3D=3D NULL) {
> > +    DEBUG ((USB_DEBUG_MEM_NODE_ERROR, "RemoveNode - Node Not
> Found\n"));
> > +    return EFI_NOT_FOUND;
> > +  }
> > +
> > +  if (Node !=3D UsbFuncIoDevPtr->FirstNodePtr) {
> > +    PNode->NextPtr =3D Node->NextPtr;
> > +  } else {
> > +    UsbFuncIoDevPtr->FirstNodePtr =3D Node->NextPtr;
> > +  }
> > +
> > +  FreePool (Node->AllocatePtr);
> > +  FreePool (Node);
> > +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "RemoveNode - Exit\n"));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  The InsertNewNodeToHead function allocates a memory for record the
> driver allocate
> > +  memory region and insert the node to the head link list.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[out] USB_MEM_NODE      return the new node address.
> > +
> > +  @retval EFI_SUCCESS           The operation completed successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_OUT_OF_RESOURCES  The requested transfer Buffer could
> not be allocated.
> > +
> > +**/
> > +EFI_STATUS
> > +InsertNewNodeToHead (
> > +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> > +  OUT USB_MEM_NODE             **Node
> > +  )
> > +{
> > +  USB_MEM_NODE         *NewNodePtr;
> > +  USB_MEM_NODE         *CurrentNodePtr;
> > +  USB_XDCI_DEV_CONTEXT *UsbFuncIoDevPtr;
> > +  EFI_STATUS           Status;
> > +
> > +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "CreateNewNode - Entry\n"));
> > +
> > +  if (This =3D=3D NULL) {
> > +    Status =3D EFI_INVALID_PARAMETER;
> > +    goto ErrorExit;
> > +  }
> > +
> > +  UsbFuncIoDevPtr =3D USBFUIO_CONTEXT_FROM_PROTOCOL(This);
> > +
> > +  //
> > +  // Create the new node
> > +  //
> > +  NewNodePtr =3D AllocateZeroPool (sizeof(USB_MEM_NODE));
> > +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "NewNodePtr - Addr =3D
> 0x%08x\n",(UINTN)NewNodePtr));
> > +
> > +  if (NewNodePtr =3D=3D NULL) {
> > +    Status =3D EFI_OUT_OF_RESOURCES;
> > +    goto ErrorExit;
> > +  }
> > +
> > +  //
> > +  // insert the new node
> > +  //
> > +  CurrentNodePtr =3D UsbFuncIoDevPtr->FirstNodePtr;
> > +  UsbFuncIoDevPtr->FirstNodePtr =3D NewNodePtr;
> > +
> > +  if (CurrentNodePtr !=3D NULL) {
> > +    NewNodePtr->NextPtr =3D CurrentNodePtr;
> > +  }
> > +
> > +  *Node =3D NewNodePtr;
> > +
> > +  DEBUG ((USB_DEBUG_MEM_NODE_INFO, "CreateNewNode - Exit\n"));
> > +  return EFI_SUCCESS;
> > +
> > +ErrorExit:
> > +
> > +  DEBUG ((USB_DEBUG_MEM_NODE_ERROR, "CreateNewNode - error
> %r\n",Status));
> > +  return Status;
> > +}
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
> > new file mode 100644
> > index 0000000000..ecedb2748b
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/UsbIoNode.h
> > @@ -0,0 +1,90 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#ifndef __EFI_USB_FUIO_MEM_NODE__
> > +#define __EFI_USB_FUIO_MEM_NODE__
> > +
> > +#include <Uefi.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/DevicePathLib.h>
> > +#include <Library/DriverLib.h>
> > +
> > +#define  USB_DEBUG_MEM_NODE_INFO  EFI_D_INIT
> > +#define  USB_DEBUG_MEM_NODE_ERROR EFI_D_ERROR
> > +
> > +
> > +typedef struct {
> > +  UINTN                         Size;
> > +  VOID                          *AllocatePtr;
> > +  VOID                          *NextPtr;
> > +} USB_MEM_NODE;
> > +
> > +/**
> > +  The SearchNode function search a memory address for record the drive=
r
> allocate
> > +  memory region and the node to the head link list.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  Buffer            The driver alocate memory address.
> > +  @param[out] Node              The match node record of the driver al=
oocate
> > +                                memory region.
> > +  @param[out] PNode             The pervious match node record of the
> driver
> > +                                aloocate memory region.
> > +
> > +  @retval EFI_SUCCESS           The operation completed successfully.
> > +  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
> > +**/
> > +EFI_STATUS
> > +SearchNode (
> > +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> > +  IN  VOID                     *Buffer,
> > +  OUT USB_MEM_NODE             **Node,
> > +  OUT USB_MEM_NODE             **PNode
> > +  );
> > +
> > +/**
> > +  The InsertNewNodeToHead function remove a memory for record the
> driver allocate
> > +  memory region and the node to the head link list.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[in]  Buffer            The driver alocate memory address.
> > +
> > +  @retval EFI_SUCCESS           The operation completed successfully.
> > +  @retval EFI_NOT_FOUND         The memory Buffer didn't find.
> > +**/
> > +EFI_STATUS
> > +RemoveNode (
> > +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> > +  IN  VOID                     *Buffer
> > +  );
> > +
> > +/**
> > +  The InsertNewNodeToHead function allocates a memory for record the
> driver allocate
> > +  memory region and insert the node to the head link list.
> > +
> > +  @param[in]  This              A pointer to the EFI_USBFN_IO_PROTOCOL
> instance.
> > +  @param[out] USB_MEM_NODE      return the new node address.
> > +
> > +  @retval EFI_SUCCESS           The operation completed successfully.
> > +  @retval EFI_INVALID_PARAMETER A parameter is invalid.
> > +  @retval EFI_OUT_OF_RESOURCES  The requested transfer Buffer could
> not be allocated.
> > +
> > +**/
> > +EFI_STATUS
> > +InsertNewNodeToHead (
> > +  IN  EFI_USBFN_IO_PROTOCOL    *This,
> > +  OUT USB_MEM_NODE             **Node
> > +  );
> > +
> > +  #endif
> > +
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
> > new file mode 100644
> > index 0000000000..6a53068681
> > --- /dev/null
> > +++
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciCommon.h
> > @@ -0,0 +1,156 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#ifndef _XDCI_COMMON_H_
> > +#define _XDCI_COMMON_H_
> > +
> > +#define USB_SETUP_DATA_PHASE_DIRECTION_MASK  (0x80)
> > +
> > +//
> > +// EP direction
> > +//
> > +typedef enum {
> > +  UsbEpDirOut =3D 0,
> > +  UsbEpDirIn  =3D 1
> > +} USB_EP_DIR;
> > +
> > +//
> > +// USB Speeds
> > +//
> > +typedef enum {
> > +  USB_SPEED_HIGH  =3D 0,
> > +  USB_SPEED_FULL,
> > +  USB_SPEED_LOW,
> > +  USB_SPEED_SUPER =3D 4
> > +} USB_SPEED;
> > +
> > +typedef enum {
> > +  USB_ID_DWC_XDCI =3D 0,
> > +  USB_CORE_ID_MAX
> > +} USB_CONTROLLER_ID;
> > +
> > +typedef enum {
> > +  USB_ROLE_HOST =3D 1,
> > +  USB_ROLE_DEVICE,
> > +  USB_ROLE_OTG
> > +} USB_ROLE;
> > +
> > +typedef enum {
> > +  USB_XFER_QUEUED    =3D 0,
> > +  USB_XFER_SUCCESSFUL,
> > +  USB_XFER_STALL
> > +} USB_XFER_STATUS;
> > +
> > +typedef enum {
> > +  USB_DEVICE_DISCONNECT_EVENT       =3D 0,
> > +  USB_DEVICE_RESET_EVENT,
> > +  USB_DEVICE_CONNECTION_DONE,
> > +  USB_DEVICE_STATE_CHANGE_EVENT,
> > +  USB_DEVICE_WAKEUP_EVENT,
> > +  USB_DEVICE_HIBERNATION_REQ_EVENT,
> > +  USB_DEVICE_SOF_EVENT              =3D 7,
> > +  USB_DEVICE_ERRATIC_ERR_EVENT      =3D 9,
> > +  USB_DEVICE_CMD_CMPLT_EVENT,
> > +  USB_DEVICE_BUFF_OVERFLOW_EVENT,
> > +  USB_DEVICE_TEST_LMP_RX_EVENT,
> > +  USB_DEVICE_SETUP_PKT_RECEIVED,
> > +  USB_DEVICE_XFER_NRDY,
> > +  USB_DEVICE_XFER_DONE
> > +} USB_DEVICE_EVENT_ID;
> > +
> > +typedef enum {
> > +  U0 =3D 0,
> > +  U1,
> > +  U2,
> > +  U3,
> > +  SS_DIS,
> > +  RX_DET,
> > +  SS_INACT,
> > +  POLL,
> > +  RECOV,
> > +  HRESET,
> > +  CMPLY,
> > +  LPBK,
> > +  RESUME_RESET =3D 15
> > +} USB_DEVICE_SS_LINK_STATE;
> > +
> > +typedef enum {
> > +  CTRL_SETUP_PHASE,
> > +  CTRL_DATA_PHASE,
> > +  CTRL_STATUS_PHASE
> > +} USB_CONTROL_XFER_PHASE;
> > +
> > +typedef enum  {
> > +  USB_EP_STATE_DISABLED =3D 0,
> > +  USB_EP_STATE_ENABLED,
> > +  USB_EP_STATE_STALLED,
> > +  USB_EP_STATE_SETUP,
> > +  USB_EP_STATE_IN_DATA,
> > +  USB_EP_STATE_OUT_DATA,
> > +  USB_EP_STATE_DATA,
> > +  USB_EP_STATE_STATUS
> > +} USB_EP_STATE;
> > +
> > +typedef struct  {
> > +  VOID                      *ParentHandle;
> > +  UINT32                    Hird;
> > +  UINT32                    EpNum;
> > +  USB_SPEED                 Speed;
> > +  USB_EP_STATE              EpState;
> > +  USB_EP_DIR                EpDir;
> > +  UINT8                     EpType;
> > +  USB_DEVICE_SS_LINK_STATE  LinkState;
> > +  UINT8                     *Buffer;
> > +  BOOLEAN                   SsEvent;
> > +} USB_DEVICE_CALLBACK_PARAM;
> > +
> > +//
> > +// USB endpoint
> > +//
> > +typedef struct {
> > +  UINT32       EpNum;
> > +  USB_EP_DIR   EpDir;
> > +  UINT8        EpType;
> > +  UINT32       MaxPktSize;
> > +  UINT32       MaxStreams;
> > +  UINT32       BurstSize;
> > +  UINT32       Interval;
> > +  UINT32       Mult;
> > +} USB_EP_INFO;
> > +
> > +//
> > +// USB transfer request
> > +//
> > +typedef struct _USB_XFER_REQUEST USB_XFER_REQUEST;
> > +
> > +typedef
> > +VOID
> > +(EFIAPI *USB_XFER_DONE_CALLBACK) (
> > +  IN VOID                    *XdciHndl,
> > +  IN USB_XFER_REQUEST        *XferReq
> > +  );
> > +
> > +struct _USB_XFER_REQUEST {
> > +  VOID                      *XferBuffer;     // Buffer address. bus-wi=
dth aligned
> > +  UINT32                    XferLen;         // Requested transfer len=
gth
> > +  UINT32                    ActualXferLen;  // Actual transfer length =
at completion
> callback stage
> > +  UINT32                    StreamId;        // Stream ID. Only releva=
nt for bulk
> streaming
> > +  UINT32                    FrameNum;        // Only relevant for peri=
odic transfer
> > +  USB_XFER_STATUS           XferStatus;      // Transfer status
> > +  USB_EP_INFO               EpInfo;          // EP info
> > +  USB_XFER_DONE_CALLBACK    XferDone;        // Transfer completion
> callback
> > +  BOOLEAN                   Zlp;              // Do zero-length transf=
er
> > +};
> > +
> > +#endif
> > +
> > diff --git a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
> > new file mode 100644
> > index 0000000000..3569ba6975
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.c
> > @@ -0,0 +1,4030 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#include "UsbDeviceMode.h"
> > +#include "XdciInterface.h"
> > +#include "XdciDWC.h"
> > +
> > +
> > +UINT32
> > +UsbRegRead (
> > +  IN UINT32    Base,
> > +  IN UINT32    Offset
> > +  )
> > +{
> > +  volatile UINT32 *addr =3D (volatile UINT32 *)((UINTN)(Base) +
> (UINTN)(Offset));
> > +  return *addr;
> > +}
> > +
> > +VOID
> > +UsbRegWrite (
> > +  IN UINT32    Base,
> > +  IN UINT32    Offset,
> > +  IN UINT32    val
> > +  )
> > +{
> > +  volatile UINT32 *addr =3D (volatile UINT32 *)((UINTN)(Base) +
> (UINTN)(Offset));
> > +  *addr =3D val;
> > +}
> > +
> > +
> > +/**
> > +  Internal utility function:
> > +  This function is used to obtain physical endpoint number
> > +  xDCI needs physical endpoint number for EP registers
> > +  We also use it to index into our EP array
> > +  Note: Certain data structures/commands use logical EP numbers
> > +  as opposed to physical endpoint numbers so one should be
> > +  careful when interpreting EP numbers
> > +  @EpNum: Logical endpoint number
> > +  @epDir: Direction for the endpoint
> > +
> > +**/
> > +STATIC
> > +UINT32
> > +DwcXdciGetPhysicalEpNum (
> > +  IN UINT32        EndpointNum,
> > +  IN USB_EP_DIR    EndpointDir
> > +  )
> > +{
> > +  return EndpointDir? ((EndpointNum << 1) | EndpointDir) : (EndpointNu=
m
> << 1);
> > +}
> > +
> > +
> > +/**
> > +  Internal utility function:
> > +  This function is used to obtain the MPS for control transfers
> > +  Based on the Speed. If this is called before bus reset completes
> > +  then it returns MPS Based on desired Speed. If it is after bus
> > +  reset then MPS returned is Based on actual negotiated Speed
> > +  @CoreHandle: xDCI controller handle address
> > +  @mps: address of 32-bit variable to return the MPS
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciCoreGetCtrlMps (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              *mps
> > +  )
> > +{
> > +  if (CoreHandle =3D=3D NULL) {
> > +      DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreGetCtrlMps: INVALID
> handle\n"));
> > +      return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (mps =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreGetCtrlMps: INVALID
> parameter\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  switch (CoreHandle->ActualSpeed) {
> > +    case USB_SPEED_HIGH:
> > +      *mps =3D DWC_XDCI_HS_CTRL_EP_MPS;
> > +      break;
> > +    case USB_SPEED_FULL:
> > +      *mps =3D DWC_XDCI_FS_CTRL_EP_MPS;
> > +      break;
> > +    case USB_SPEED_LOW:
> > +      *mps =3D DWC_XDCI_LS_CTRL_EP_MPS;
> > +      break;
> > +    case USB_SPEED_SUPER:
> > +      *mps =3D DWC_XDCI_SS_CTRL_EP_MPS;
> > +      break;
> > +    default:
> > +      *mps =3D 0;
> > +      DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreGetCtrlMps: UNKNOWN
> Speed\n"));
> > +      break;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal utility function:
> > +  This function is used to initialize the parameters required
> > +  for executing endpoint command
> > +  @CoreHandle: xDCI controller handle address
> > +  @EpInfo: EP info address
> > +  @ConfigAction: Configuration action specific to EP command
> > +  @EpCmd: xDCI EP command for which parameters are initialized
> > +  @EpCmdParams: address of struct to return EP params
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciCoreInitEpCmdParams (
> > +  IN XDCI_CORE_HANDLE                *CoreHandle,
> > +  IN USB_EP_INFO                     *EpInfo,
> > +  IN UINT32                          ConfigAction,
> > +  IN DWC_XDCI_ENDPOINT_CMD           EpCmd,
> > +  IN DWC_XDCI_ENDPOINT_CMD_PARAMS    *EpCmdParams
> > +  )
> > +{
> > +  EFI_STATUS  status =3D EFI_SUCCESS;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreInitEpCmdParams:
> INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Reset params
> > +  //
> > +  EpCmdParams->Param0 =3D EpCmdParams->Param1 =3D EpCmdParams-
> >Param2 =3D 0;
> > +
> > +  switch (EpCmd) {
> > +    case EPCMD_SET_EP_CONFIG:
> > +      //
> > +      // Issue DEPCFG command for EP
> > +      // Issue a DEPCFG (Command 1) command for endpoint
> > +      //
> > +      if (EpInfo->MaxStreams) {
> > +        EpCmdParams->Param1 =3D
> DWC_XDCI_PARAM1_SET_EP_CFG_STRM_CAP_MASK;
> > +      }
> > +
> > +      if (EpInfo->Interval) {
> > +        EpCmdParams->Param1 |=3D ((EpInfo->Interval-1) <<
> DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_BIT_POS);
> > +      }
> > +
> > +      //
> > +      // Set EP num
> > +      //
> > +      EpCmdParams->Param1 |=3D (EpInfo->EpNum <<
> DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_BIT_POS);
> > +      //
> > +      // Set EP direction
> > +      //
> > +      EpCmdParams->Param1 |=3D (EpInfo->EpDir <<
> DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_BIT_POS);
> > +      //
> > +      // Set EP-specific Event enable for not ready and
> > +      // complete events
> > +      //
> > +      EpCmdParams->Param1 &=3D
> ~DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_MASK;
> > +      //
> > +      // Setup the events we want enabled for this EP
> > +      //
> > +      EpCmdParams->Param1 |=3D
> (DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_NRDY_MASK |
> > +
> DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_IN_PRG_MASK |
> > +
> DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_CMPLT_MASK);
> > +
> > +      //
> > +      // We only have one interrupt line for this core.
> > +      // Set interrupt number to 0
> > +      //
> > +      EpCmdParams->Param1 &=3D
> ~DWC_XDCI_PARAM1_SET_EP_CFG_INTR_NUM_MASK;
> > +
> > +      //
> > +      // Set FIFOnum =3D 0 for control EP0
> > +      //
> > +      EpCmdParams->Param0 &=3D
> ~DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_MASK;
> > +
> > +      //
> > +      // Program FIFOnum for non-EP0 EPs
> > +      //
> > +      if (EpInfo->EpNum && EpInfo->EpDir) {
> > +        EpCmdParams->Param0 |=3D (EpInfo->EpNum <<
> DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_BIT_POS);
> > +      }
> > +
> > +      //
> > +      // Program max packet size
> > +      //
> > +      EpCmdParams->Param0 &=3D
> ~DWC_XDCI_PARAM0_SET_EP_CFG_MPS_MASK;
> > +      EpCmdParams->Param0 |=3D (EpInfo->MaxPktSize <<
> DWC_XDCI_PARAM0_SET_EP_CFG_MPS_BIT_POS);
> > +
> > +      //
> > +      // Set Burst size. 0 means burst size of 1
> > +      //
> > +      EpCmdParams->Param0 &=3D
> ~DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_MASK;
> > +      EpCmdParams->Param0 |=3D (EpInfo->BurstSize <<
> DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_BIT_POS);
> > +
> > +      //
> > +      // Set EP type
> > +      //
> > +      EpCmdParams->Param0 &=3D
> ~DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_MASK;
> > +      EpCmdParams->Param0 |=3D (EpInfo->EpType <<
> DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_BIT_POS);
> > +
> > +      //
> > +      // Set config action
> > +      //
> > +      EpCmdParams->Param0 &=3D
> ~DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MASK;
> > +      EpCmdParams->Param0 |=3D (ConfigAction <<
> DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_BIT_POS);
> > +      break;
> > +
> > +    case EPCMD_SET_EP_XFER_RES_CONFIG:
> > +      // Set Param0 to 1. Same for all EPs when resource
> > +      // configuration is done
> > +      //
> > +      EpCmdParams->Param0 =3D 1;
> > +      break;
> > +
> > +    case EPCMD_END_XFER:
> > +      //
> > +      // Nothing to set. Already reset params for all cmds
> > +      //
> > +      break;
> > +
> > +    case EPCMD_START_NEW_CONFIG:
> > +      //
> > +      // Nothing to set. Already reset params for all cmds
> > +      //
> > +      break;
> > +
> > +    default:
> > +      status =3D EFI_INVALID_PARAMETER;
> > +      DEBUG ((DEBUG_INFO, "\nDwcXdciCoreInitEpCmdParams: INVALID
> Parameter"));
> > +      break;
> > +  }
> > +
> > +  return status;
> > +}
> > +
> > +
> > +/**
> > +  Internal utility function:
> > +  This function is used to issue the xDCI endpoint command
> > +  @CoreHandle: xDCI controller handle address
> > +  @EpNum: Physical EP num
> > +  @EpCmd: xDCI EP command
> > +  @EpCmdParams: EP command parameters address
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciCoreIssueEpCmd (
> > +  IN XDCI_CORE_HANDLE                *CoreHandle,
> > +  IN UINT32                          EpNum,
> > +  IN UINT32                          EpCmd,
> > +  IN DWC_XDCI_ENDPOINT_CMD_PARAMS    *EpCmdParams
> > +  )
> > +{
> > +  UINT32 BaseAddr;
> > +  UINT32 MaxDelayIter =3D 5000;//DWC_XDCI_MAX_DELAY_ITERATIONS;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreIssueEpCmd: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr =3D CoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Set EP command parameter values
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EPCMD_PARAM2_REG(EpNum),
> > +    EpCmdParams->Param2
> > +    );
> > +
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EPCMD_PARAM1_REG(EpNum),
> > +    EpCmdParams->Param1
> > +    );
> > +
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EPCMD_PARAM0_REG(EpNum),
> > +    EpCmdParams->Param0
> > +    );
> > +
> > +  //
> > +  // Set the command code and activate it
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EPCMD_REG(EpNum),
> > +    EpCmd | DWC_XDCI_EPCMD_CMD_ACTIVE_MASK
> > +    );
> > +
> > +  //
> > +  // Wait until command completes
> > +  //
> > +  do {
> > +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_EPCMD_REG(EpNum)) &
> DWC_XDCI_EPCMD_CMD_ACTIVE_MASK))
> > +      break;
> > +    else
> > +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> > +  } while (--MaxDelayIter);
> > +
> > +  if (!MaxDelayIter) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreIssueEpCmd. ERROR: Failed to
> issue Command\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal utility function:
> > +  This function is used to flush all FIFOs
> > +  @CoreHandle: xDCI controller handle address
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciCoreFlushAllFifos (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle
> > +  )
> > +{
> > +  UINT32 BaseAddr;
> > +  UINT32 MaxDelayIter =3D DWC_XDCI_MAX_DELAY_ITERATIONS;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreFlushAllFifos: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr =3D CoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Write the command to flush all FIFOs
> > +  //
> > +  UsbRegWrite(
> > +    BaseAddr,
> > +    DWC_XDCI_DGCMD_REG,
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) |
> DWC_XDCI_DGCMD_CMD_ALL_FIFO_FLUSH |
> DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
> > +    );
> > +
> > +  //
> > +  // Wait until command completes
> > +  //
> > +  do {
> > +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) &
> DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
> > +      break;
> > +    else
> > +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> > +  } while (--MaxDelayIter);
> > +
> > +  if (!MaxDelayIter) {
> > +    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal utility function:
> > +  This function is used to flush Tx FIFO specific to an endpoint
> > +  @CoreHandle: xDCI controller handle address
> > +  @EpNum: Physical EP num
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciCoreFlushEpTxFifo (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              EpNum
> > +  )
> > +{
> > +  UINT32 BaseAddr;
> > +  UINT32 MaxDelayIter =3D DWC_XDCI_MAX_DELAY_ITERATIONS;
> > +  UINT32 fifoNum;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreFlushEpTxFifo: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr =3D CoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Translate to FIFOnum
> > +  // NOTE: Assuming this is a Tx EP
> > +  //
> > +  fifoNum =3D (EpNum >> 1);
> > +
> > +  //
> > +  // TODO: Currently we are only using TxFIFO 0. Later map these
> > +  // Write the FIFO num/dir param for the generic command.
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DGCMD_PARAM_REG,
> > +    ((UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_PARAM_REG) &
> ~DWC_XDCI_DGCMD_PARAM_TX_FIFO_NUM_MASK) |
> DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK)
> > +    );
> > +
> > +  //
> > +  // Write the command to flush all FIFOs
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DGCMD_REG,
> > +    (UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) |
> DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH |
> DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
> > +    );
> > +
> > +
> > +  //
> > +  // Wait until command completes
> > +  //
> > +  do {
> > +    if (!(UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) &
> DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
> > +      break;
> > +    else
> > +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> > +  } while (--MaxDelayIter);
> > +
> > +  if (!MaxDelayIter) {
> > +    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciCorePrepareOneTrb (
> > +  IN DWC_XDCI_TRB            *Trb,
> > +  IN DWC_XDCI_TRB_CONTROL    TrbCtrl,
> > +  IN UINT32                  LastBit,
> > +  IN UINT32                  ChainBit,
> > +  IN UINT8                   *BufferPtr,
> > +  IN UINT32                  size
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "Trb is 0x%x, BufferPtr is 0x%x, size is 0x%x\n"=
,
> Trb, BufferPtr, size));
> > +
> > +  Trb->BuffPtrLow =3D (UINT32)(UINTN)BufferPtr;
> > +  Trb->BuffPtrHigh =3D 0;
> > +  Trb->LenXferParams =3D size;
> > +  Trb->TrbCtrl =3D TrbCtrl << DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
> > +
> > +  if (ChainBit)
> > +    Trb->TrbCtrl |=3D ChainBit <<
> DWC_XDCI_TRB_CTRL_CHAIN_BUFF_BIT_POS;
> > +
> > +  if (LastBit)
> > +    Trb->TrbCtrl |=3D LastBit << DWC_XDCI_TRB_CTRL_LST_TRB_BIT_POS;
> > +
> > +  Trb->TrbCtrl |=3D DWC_XDCI_TRB_CTRL_IOSP_MISOCH_MASK|
> DWC_XDCI_TRB_CTRL_HWO_MASK;
> > +
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciCorePrepareOneTrb) Trb->BuffPtrLow
> =3D 0x%x, Trb->LenXferParams is 0x%x, Trb->TrbCtrl is 0x%x\n",
> > +                                                       Trb->BuffPtrLow=
, Trb->LenXferParams, Trb-
> >TrbCtrl));
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal utility function:
> > +  This function is used to initialize transfer request block
> > +  @CoreHandle: xDCI controller handle address
> > +  @Trb: Address of TRB to initialize
> > +  @TrbCtrl: TRB control value
> > +  @buffPtr: Transfer Buffer address
> > +  @size: Size of the transfer
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciCoreInitTrb (
> > +  IN XDCI_CORE_HANDLE        *CoreHandle,
> > +  IN DWC_XDCI_TRB            *Trb,
> > +  IN DWC_XDCI_TRB_CONTROL    TrbCtrl,
> > +  IN UINT8                   *BufferPtr,
> > +  IN UINT32                  size
> > +  )
> > +{
> > +#define ONE_TRB_SIZE      (DWC_XDCI_TRB_BUFF_SIZE_MASK &
> 0x00F00000)
> > +  UINT8                   *TrbBuffer;
> > +  UINT32                  TrbCtrlLast;
> > +  UINT32                  TrbCtrlChain;
> > +  UINT32                  TrbIndex;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreInitTrb: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (Trb =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreInitTrb: INVALID
> handle\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +   //
> > +   // Init TRB fields
> > +   // NOTE: Assuming we are only using 32-bit addresses
> > +   // TODO: update for 64-bit addresses
> > +   //
> > +  if (size <=3D DWC_XDCI_TRB_BUFF_SIZE_MASK) {
> > +    //
> > +    // Can transfer in one TRB
> > +    //
> > +    TrbCtrlChain =3D 0;
> > +    TrbCtrlLast =3D 1;
> > +    DwcXdciCorePrepareOneTrb (Trb, TrbCtrl, TrbCtrlLast, TrbCtrlChain,
> BufferPtr, size);
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  //
> > +  // Can't transfer in one TRB.
> > +  // Seperate it in every ONE_TRB_SIZE of TRB
> > +  //
> > +  TrbBuffer =3D BufferPtr;
> > +  TrbIndex =3D 0;
> > +  while (size > ONE_TRB_SIZE) {
> > +    TrbCtrlChain =3D 1;
> > +    TrbCtrlLast =3D 0;
> > +    DwcXdciCorePrepareOneTrb (Trb, TrbCtrl, TrbCtrlLast, TrbCtrlChain,
> TrbBuffer, ONE_TRB_SIZE);
> > +    TrbBuffer +=3D ONE_TRB_SIZE;
> > +    size -=3D ONE_TRB_SIZE;
> > +    Trb++;
> > +    TrbIndex++;
> > +    if (TrbIndex >=3D DWC_XDCI_TRB_NUM)
> > +      return EFI_OUT_OF_RESOURCES;
> > +  }
> > +  TrbCtrlChain =3D 0;
> > +  TrbCtrlLast =3D 1;
> > +  DwcXdciCorePrepareOneTrb (Trb, TrbCtrl, TrbCtrlLast, TrbCtrlChain,
> TrbBuffer, size);
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to start a SETUP phase on control endpoint
> > +  @CoreHandle: xDCI controller handle address
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciCoreStartEp0SetupXfer (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle
> > +  )
> > +{
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> > +  EFI_STATUS                      status =3D EFI_DEVICE_ERROR;
> > +  DWC_XDCI_TRB                    *Trb;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreStartEp0SetupXfer:
> INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (CoreHandle->EpHandles[0].State =3D=3D USB_EP_STATE_SETUP) {
> > +    DEBUG ((DEBUG_INFO, "EP0 was already in SETUP phase\n"));
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  CoreHandle->EpHandles[0].State =3D USB_EP_STATE_SETUP;
> > +  Trb =3D CoreHandle->Trbs;
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreStartEp0SetupXfer)\n"));
> > +
> > +  status =3D DwcXdciCoreInitTrb (
> > +             CoreHandle,
> > +             Trb,
> > +             TRBCTL_SETUP,
> > +             CoreHandle->AlignedSetupBuffer,
> > +             8
> > +             );
> > +
> > +  if (status)
> > +    return status;
> > +
> > +  //
> > +  // Issue a DEPSTRTXFER for EP0
> > +  // Reset params
> > +  //
> > +  EpCmdParams.Param0 =3D EpCmdParams.Param1 =3D
> EpCmdParams.Param2 =3D 0;
> > +
> > +  //
> > +  // Init the lower re-bits for TRB address
> > +  //
> > +  EpCmdParams.Param1 =3D (UINT32)(UINTN)Trb;
> > +
> > +  //
> > +  // Issue the command to start transfer on physical
> > +  // endpoint 0
> > +  //
> > +  status =3D DwcXdciCoreIssueEpCmd (
> > +             CoreHandle,
> > +             0,
> > +             EPCMD_START_XFER,
> > +             &EpCmdParams
> > +             );
> > +
> > +  //
> > +  // Save new resource index for this transfer
> > +  //
> > +  CoreHandle->EpHandles[0].CurrentXferRscIdx =3D ((UsbRegRead (
> > +                                                     CoreHandle->BaseA=
ddress,
> > +                                                     DWC_XDCI_EPCMD_RE=
G(0)) &
> DWC_XDCI_EPCMD_RES_IDX_MASK) >>
> DWC_XDCI_EPCMD_RES_IDX_BIT_POS
> > +                                                     );
> > +
> > +  return status;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process the state change event
> > +  @CoreHandle: xDCI controller handle address
> > +  @event: device event dword
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessDeviceStateChangeEvent (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              Event
> > +  )
> > +{
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR:
> DwcXdciProcessDeviceStateChangeEvent: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  CoreHandle->HirdVal =3D (Event &
> DWC_XDCI_EVENT_BUFF_DEV_HIRD_MASK) >>
> DWC_XDCI_EVENT_BUFF_DEV_HIRD_BIT_POS;
> > +
> > +  CoreHandle->LinkState =3D ((Event &
> DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_MASK) >>
> DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_BIT_POS);
> > +
> > +  if (CoreHandle->EventCallbacks.DevLinkStateCallback) {
> > +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle =3D
> CoreHandle->ParentHandle;
> > +    CoreHandle->EventCallbacks.CbEventParams.LinkState =3D CoreHandle-
> >LinkState;
> > +    CoreHandle->EventCallbacks.CbEventParams.Hird =3D CoreHandle-
> >HirdVal;
> > +    CoreHandle->EventCallbacks.CbEventParams.SsEvent =3D (Event &
> DWC_XDCI_EVENT_BUFF_DEV_SS_EVENT_MASK) ? 1 : 0;
> > +    CoreHandle->EventCallbacks.DevLinkStateCallback (&CoreHandle-
> >EventCallbacks.CbEventParams);
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to issue a command to end transfer
> > +  @CoreHandle: xDCI controller handle address
> > +  @EpNum: Physical EP num for which transfer is to be ended
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciEndXfer (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              EpNum
> > +  )
> > +{
> > +  EFI_STATUS                      status;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> > +  UINT32                          cmdParams;
> > +  DWC_XDCI_TRB                    *TrbPtr;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciEndXfer: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  CoreHandle->EpHandles[EpNum].CheckFlag =3D FALSE;
> > +
> > +  //
> > +  // Issue a DEPENDXFER for EP
> > +  // Reset params
> > +  //
> > +  EpCmdParams.Param0 =3D EpCmdParams.Param1 =3D
> EpCmdParams.Param2 =3D 0;
> > +
> > +  cmdParams =3D ((CoreHandle->EpHandles[EpNum].CurrentXferRscIdx <<
> DWC_XDCI_EPCMD_RES_IDX_BIT_POS) |
> DWC_XDCI_EPCMD_FORCE_RM_MASK);
> > +
> > +  if (CoreHandle->EpHandles[EpNum].CurrentXferRscIdx =3D=3D 0) {
> > +    return EFI_SUCCESS;
> > +  }
> > +  //
> > +  // Issue the command
> > +  //
> > +  status =3D DwcXdciCoreIssueEpCmd(
> > +             CoreHandle,
> > +             EpNum,
> > +             cmdParams | DWC_XDCI_EPCMD_END_XFER,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (!status) {
> > +    CoreHandle->EpHandles[EpNum].CurrentXferRscIdx =3D 0;
> > +    TrbPtr =3D CoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM);
> > +    ZeroMem (TrbPtr, DWC_XDCI_TRB_NUM * sizeof (DWC_XDCI_TRB));
> > +  }
> > +
> > +  return status;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process bus reset detection event
> > +  @CoreHandle: xDCI controller handle address
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessDeviceResetDet (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle
> > +  )
> > +{
> > +  EFI_STATUS  status =3D EFI_SUCCESS;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Flush all FIFOs
> > +  //
> > +  status =3D DwcXdciCoreFlushAllFifos(CoreHandle);
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceResetDet: Failed to flush
> FIFOs\n"));
> > +  }
> > +
> > +  //
> > +  // Start SETUP phase on EP0
> > +  //
> > +  status =3D DwcXdciCoreStartEp0SetupXfer(CoreHandle);
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceResetDet: Failed to start
> SETUP phase for EP0\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Notify upper layer if a callback is registerd for
> > +  //  this event
> > +  //
> > +  if (CoreHandle->EventCallbacks.DevBusResetCallback) {
> > +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle =3D
> CoreHandle->ParentHandle;
> > +    status =3D CoreHandle->EventCallbacks.DevBusResetCallback
> (&CoreHandle->EventCallbacks.CbEventParams);
> > +  }
> > +
> > +  return status;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process connection done (means reset
> > +  complete) event
> > +  @CoreHandle: xDCI controller handle address
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessDeviceResetDone (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle
> > +  )
> > +{
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> > +  UINT32                          BaseAddr;
> > +  EFI_STATUS                      status =3D EFI_SUCCESS;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessDeviceResetDone:
> INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr =3D CoreHandle->BaseAddress;
> > +  CoreHandle->ActualSpeed =3D (UsbRegRead (BaseAddr,
> DWC_XDCI_DSTS_REG) & DWC_XDCI_DSTS_CONN_SPEED_MASK);
> > +  DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceResetDone CoreHandle-
> >ActualSpeed is %x\n", CoreHandle->ActualSpeed));
> > +
> > +  //
> > +  // Program MPS Based on the negotiated Speed
> > +  //
> > +  DwcXdciCoreGetCtrlMps (CoreHandle, &CoreHandle-
> >EpHandles[0].EpInfo.MaxPktSize);
> > +  DwcXdciCoreGetCtrlMps (CoreHandle, &CoreHandle-
> >EpHandles[1].EpInfo.MaxPktSize);
> > +
> > +  //
> > +  // Init DEPCFG cmd params for EP0
> > +  //
> > +  status =3D DwcXdciCoreInitEpCmdParams (
> > +             CoreHandle,
> > +             &CoreHandle->EpHandles[0].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MDFY_STATE,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status =3D DwcXdciCoreIssueEpCmd (
> > +             CoreHandle,
> > +             0,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Init DEPCFG cmd params for EP1
> > +  //
> > +  status =3D DwcXdciCoreInitEpCmdParams (
> > +             CoreHandle,
> > +             &CoreHandle->EpHandles[1].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MDFY_STATE,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status =3D DwcXdciCoreIssueEpCmd (
> > +             CoreHandle,
> > +             1,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  //
> > +  // Put the other PHY into suspend
> > +  //
> > +  if (CoreHandle->ActualSpeed =3D=3D USB_SPEED_SUPER) {
> > +    //
> > +    // Put HS PHY to suspend
> > +    //
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_GUSB2PHYCFG_REG (0),
> > +      (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) |
> DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
> > +      );
> > +
> > +    //
> > +    // Clear SS PHY's suspend mask
> > +    //
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_GUSB3PIPECTL_REG (0),
> > +      (UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) &
> ~DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
> > +      );
> > +
> > +  } else {
> > +    //
> > +    // Put SS PHY to suspend
> > +    //
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_GUSB3PIPECTL_REG(0),
> > +      (UsbRegRead(BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) |
> DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
> > +      );
> > +
> > +    //
> > +    // Clear HS PHY's suspend mask
> > +    //
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_GUSB2PHYCFG_REG(0),
> > +      (UsbRegRead(BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) &
> ~DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
> > +      );
> > +  }
> > +
> > +  //
> > +  // Notify upper layer if callback is registered
> > +  //
> > +  if (CoreHandle->EventCallbacks.DevResetDoneCallback) {
> > +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle =3D
> CoreHandle->ParentHandle;
> > +    CoreHandle->EventCallbacks.CbEventParams.Speed =3D CoreHandle-
> >ActualSpeed;
> > +    CoreHandle->EventCallbacks.DevResetDoneCallback (&CoreHandle-
> >EventCallbacks.CbEventParams);
> > +  }
> > +
> > +  return status;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process device event
> > +  @CoreHandle: xDCI controller handle address
> > +  @IntLineEventBuffer: event Buffer pointing to device event
> > +  @ProcessedEventSize: address of variable to save the size of
> > +  the event that was Processed
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessDeviceEvent (
> > +  IN XDCI_CORE_HANDLE         *CoreHandle,
> > +  IN DWC_XDCI_EVENT_BUFFER    *IntLineEventBuffer,
> > +  IN UINT32                   *ProcessedEventSize
> > +  )
> > +{
> > +  UINT32 event;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessDeviceEvent: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Extract device event
> > +  //
> > +  event =3D (IntLineEventBuffer->Event &
> DWC_XDCI_EVENT_BUFF_DEV_EVT_MASK);
> > +  event >>=3D DWC_XDCI_EVENT_BUFF_DEV_EVT_BIT_POS;
> > +
> > +  //
> > +  // Assume default event size. Change it in switch case if
> > +  //  different
> > +  //
> > +  *ProcessedEventSize =3D
> DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
> > +
> > +  switch (event) {
> > +    case DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT\n"));
> > +      DwcXdciProcessDeviceResetDet (CoreHandle);
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT\n"));
> > +      DwcXdciProcessDeviceResetDone (CoreHandle);
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT\n"));
> > +      DwcXdciProcessDeviceStateChangeEvent (CoreHandle,
> IntLineEventBuffer->Event);
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT:
> > +      DEBUG ((DEBUG_INFO, "Device
> DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT\n"));
> > +      *ProcessedEventSize =3D
> DWC_XDCI_DEV_EVENT_TST_LMP_SIZE_IN_BYTES;
> > +      break;
> > +
> > +    default:
> > +      DEBUG ((DEBUG_INFO, "DwcXdciProcessDeviceEvent: UNHANDLED
> device event: %x\n", event));
> > +      break;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process EP not ready for
> > +  non-control endpoints
> > +  @CoreHandle: xDCI controller handle address
> > +  @EpNum: Physical endpoint number
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessEpXferNotReady (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              EpNum
> > +  )
> > +{
> > +  //
> > +  // TODO: Not doing on-demand transfers
> > +  // Revisit if required for later use
> > +  //
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process EP not ready for
> > +  control endpoints
> > +  @CoreHandle: xDCI controller handle address
> > +  @EpNum: Physical endpoint number
> > +  @dataStage: EP not ready when data stage token was received
> > +  @statusStage: EP not ready when status stage token was received
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessEp0XferNotReady (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              EpNum,
> > +  IN UINT32              epEventStatus
> > +  )
> > +{
> > +  USB_EP_STATE        epState =3D USB_EP_STATE_SETUP;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEp0XferNotReady:
> INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +  //
> > +  // Is it data stage or status stage
> > +  //
> > +  if (epEventStatus &
> DWC_XDCI_EVENT_BUFF_EP_CTRL_DATA_REQ_MASK) {
> > +    epState =3D USB_EP_STATE_DATA;
> > +  } else if (epEventStatus &
> DWC_XDCI_EVENT_BUFF_EP_CTRL_STATUS_REQ_MASK) {
> > +    epState =3D USB_EP_STATE_STATUS;
> > +  }
> > +
> > +  if ((EpNum =3D=3D 0) && (epState =3D=3D USB_EP_STATE_STATUS)) {
> > +    if (epEventStatus & DWC_XDCI_EVENT_BUFF_EP_XFER_ACTIVE_MASK) {
> > +      DEBUG ((DEBUG_INFO, "XFER_ACTIVE\n"));
> > +    } else {
> > +      DEBUG ((DEBUG_INFO, "XFER_NOT_ACTIVE\n"));
> > +    }
> > +    DwcXdciEp0ReceiveStatusPkt (CoreHandle);
> > +  }
> > +
> > +  //
> > +  // Notify upper layer if a callback is registered for
> > +  // this event
> > +  //
> > +  if (CoreHandle->EventCallbacks.DevXferNrdyCallback) {
> > +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle =3D
> CoreHandle->ParentHandle;
> > +    CoreHandle->EventCallbacks.CbEventParams.EpState =3D epState;
> > +    CoreHandle->EventCallbacks.DevXferNrdyCallback (&CoreHandle-
> >EventCallbacks.CbEventParams);
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process transfer phone done for EP0
> > +  @CoreHandle: xDCI controller handle address
> > +  @EpNum: Physical endpoint number (0 for OUT and 1 for IN)
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessEp0XferPhaseDone (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              EpNum
> > +  )
> > +{
> > +  DWC_XDCI_ENDPOINT    *epHandle;
> > +  DWC_XDCI_TRB         *Trb;
> > +  EFI_STATUS           status =3D EFI_SUCCESS;
> > +  UINT32               TrbSts;
> > +  UINT32               TrbCtrl;
> > +  UINT32               TrbBufsize;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEp0XferPhaseDone:
> INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  epHandle =3D &CoreHandle->EpHandles[EpNum];
> > +  Trb =3D CoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM);
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciProcessEp0XferPhaseDone)EpNum is
> %d\n", EpNum));
> > +
> > +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone. HW owns
> TRB: %x!!!\n", (UINT32)(UINTN)Trb));
> > +  }
> > +
> > +  epHandle->CurrentXferRscIdx =3D 0;
> > +  epHandle->State =3D USB_EP_STATE_ENABLED;
> > +  TrbCtrl =3D (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_TYPE_MASK) >>
> DWC_XDCI_TRB_CTRL_TYPE_BIT_POS;
> > +  TrbSts =3D (Trb->LenXferParams & DWC_XDCI_TRB_STATUS_MASK) >>
> DWC_XDCI_TRB_STATUS_BIT_POS;
> > +  TrbBufsize =3D Trb->LenXferParams & DWC_XDCI_TRB_BUFF_SIZE_MASK;
> > +
> > +  switch (TrbCtrl) {
> > +    case DWC_XDCI_TRB_CTRL_TYPE_SETUP:
> > +      DEBUG ((DEBUG_INFO, "SETUP\n"));
> > +      if (CoreHandle->EventCallbacks.DevSetupPktReceivedCallback) {
> > +        CoreHandle->EventCallbacks.CbEventParams.ParentHandle =3D
> CoreHandle->ParentHandle;
> > +        CoreHandle->EventCallbacks.CbEventParams.Buffer =3D CoreHandle=
-
> >AlignedSetupBuffer;
> > +        status =3D CoreHandle->EventCallbacks.DevSetupPktReceivedCallb=
ack
> (&CoreHandle->EventCallbacks.CbEventParams);
> > +      }
> > +
> > +      if (!(CoreHandle->AlignedSetupBuffer[0] &
> USB_SETUP_DATA_PHASE_DIRECTION_MASK)) {
> > +        //
> > +        // Keep a Buffer ready for setup phase
> > +        //
> > +        DwcXdciCoreStartEp0SetupXfer (CoreHandle);
> > +      }
> > +
> > +      break;
> > +
> > +    case DWC_XDCI_TRB_CTRL_TYPE_STATUS2:
> > +      DEBUG ((DEBUG_INFO, "STATUS2\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_TRB_CTRL_TYPE_STATUS3:
> > +      DEBUG ((DEBUG_INFO, "STATUS3\n"));
> > +      //
> > +      // Notify upper layer of control transfer completion
> > +      // if a callback function was registerd
> > +      //
> > +      if (CoreHandle->EventCallbacks.DevXferDoneCallback) {
> > +        CoreHandle->EventCallbacks.CbEventParams.ParentHandle =3D
> CoreHandle->ParentHandle;
> > +        CoreHandle->EventCallbacks.CbEventParams.EpNum =3D (EpNum >> 1=
);
> > +        CoreHandle->EventCallbacks.CbEventParams.EpDir =3D (EpNum & 1)=
;
> > +        CoreHandle->EventCallbacks.CbEventParams.Buffer =3D (UINT8
> *)(UINTN)(Trb->BuffPtrLow);
> > +        CoreHandle->EventCallbacks.DevXferDoneCallback (&CoreHandle-
> >EventCallbacks.CbEventParams);
> > +      }
> > +
> > +      //
> > +      // Status phase done. Queue next SETUP packet
> > +      //
> > +      status =3D DwcXdciCoreStartEp0SetupXfer(CoreHandle);
> > +
> > +      if (status) {
> > +        DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone: FAILED
> to queue SETUP\n"));
> > +      }
> > +      break;
> > +
> > +    case DWC_XDCI_TRB_CTRL_TYPE_DATA:
> > +      DEBUG ((DEBUG_INFO, "DATA\n"));
> > +      if (TrbSts =3D=3D DWC_XDCI_TRB_STATUS_SETUP_PENDING || TrbBufsiz=
e
> !=3D 0) {
> > +        DEBUG ((DEBUG_INFO, "ERROR: Control transfert aborted by host:
> Setup pending\n"));
> > +        DwcXdciCoreStartEp0SetupXfer (CoreHandle);
> > +      }
> > +
> > +      if (CoreHandle->EventCallbacks.DevXferDoneCallback) {
> > +        CoreHandle->EventCallbacks.CbEventParams.ParentHandle =3D
> CoreHandle->ParentHandle;
> > +        CoreHandle->EventCallbacks.CbEventParams.EpNum =3D (EpNum >> 1=
);
> > +        CoreHandle->EventCallbacks.CbEventParams.EpDir =3D (EpNum & 1)=
;
> > +        CoreHandle->EventCallbacks.CbEventParams.Buffer =3D (UINT8
> *)(UINTN)(Trb->BuffPtrLow);
> > +        CoreHandle->EventCallbacks.DevXferDoneCallback (&CoreHandle-
> >EventCallbacks.CbEventParams);
> > +      }
> > +      break;
> > +
> > +    default:
> > +      DEBUG ((DEBUG_INFO, "DwcXdciProcessEp0XferPhaseDone:
> UNHANDLED STATE in TRB\n"));
> > +      break;
> > +  }
> > +
> > +  return status;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process transfer done for
> > +  non-control endpoints
> > +  @CoreHandle: xDCI controller handle address
> > +  @EpNum: Physical endpoint number
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessEpXferDone (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              EpNum
> > +  )
> > +{
> > +  DWC_XDCI_ENDPOINT    *epHandle;
> > +  DWC_XDCI_TRB         *Trb;
> > +  USB_XFER_REQUEST     *XferReq;
> > +  UINT32               remainingLen;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpXferDone: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  epHandle =3D &CoreHandle->EpHandles[EpNum];
> > +  epHandle->CurrentXferRscIdx =3D 0;
> > +  Trb =3D epHandle->Trb;
> > +  XferReq =3D &epHandle->XferHandle;
> > +
> > +  //
> > +  // if transfer done, set CheckFlag to FALSE for allow next transfer
> request.
> > +  //
> > +  epHandle->CheckFlag =3D FALSE;
> > +
> > +  if ((Trb =3D=3D NULL) || (XferReq =3D=3D NULL)) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpXferDone: INVALID
> parameter\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  //
> > +  // Compute the actual transfer length
> > +  //
> > +  XferReq->ActualXferLen =3D XferReq->XferLen;
> > +  remainingLen =3D (Trb->LenXferParams &
> DWC_XDCI_TRB_BUFF_SIZE_MASK);
> > +
> > +  if (remainingLen > XferReq->XferLen) {
> > +    //
> > +    // Buffer overrun? This should never happen
> > +    //
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpXferDone: Possible
> Buffer overrun\n"));
> > +  } else {
> > +    XferReq->ActualXferLen -=3D remainingLen;
> > +  }
> > +
> > +  //
> > +  // Notify upper layer of request-specific transfer completion
> > +  // if there is a callback specifically for this request
> > +  //
> > +  if (XferReq->XferDone) {
> > +    XferReq->XferDone(CoreHandle->ParentHandle, XferReq);
> > +  }
> > +
> > +  //
> > +  // Notify upper layer if a callback was registered
> > +  //
> > +  if (CoreHandle->EventCallbacks.DevXferDoneCallback) {
> > +    CoreHandle->EventCallbacks.CbEventParams.ParentHandle =3D
> CoreHandle->ParentHandle;
> > +    CoreHandle->EventCallbacks.CbEventParams.EpNum =3D (EpNum >> 1);
> > +    CoreHandle->EventCallbacks.CbEventParams.EpDir =3D (EpNum & 1);
> > +    CoreHandle->EventCallbacks.CbEventParams.EpType =3D epHandle-
> >EpInfo.EpType;
> > +    CoreHandle->EventCallbacks.CbEventParams.Buffer =3D (UINT8
> *)(UINTN)(epHandle->Trb->BuffPtrLow);
> > +    CoreHandle->EventCallbacks.DevXferDoneCallback (&CoreHandle-
> >EventCallbacks.CbEventParams);
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process endpoint events
> > +  @CoreHandle: xDCI controller handle address
> > +  @IntLineEventBuffer:  address of Buffer containing event
> > +  to process
> > +  @ProcessedEventSize: address to save the size of event
> > +  Processed
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessEpEvent (
> > +  IN XDCI_CORE_HANDLE         *CoreHandle,
> > +  IN DWC_XDCI_EVENT_BUFFER    *IntLineEventBuffer,
> > +  IN UINT32                   *ProcessedEventSize
> > +  )
> > +{
> > +  UINT32          EpNum;
> > +  UINT32          epEvent;
> > +  UINT32          epEventStatus;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessEpEvent: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  epEvent =3D IntLineEventBuffer->Event;
> > +
> > +  *ProcessedEventSize =3D
> DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES;
> > +
> > +  //
> > +  // Get EP num
> > +  //
> > +  EpNum =3D ((epEvent & DWC_XDCI_EVENT_BUFF_EP_NUM_MASK) >>
> DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS);
> > +  epEventStatus =3D (epEvent &
> DWC_XDCI_EVENT_BUFF_EP_EVENT_STATUS_MASK);
> > +
> > +  //
> > +  // Interpret event and handle transfer completion here
> > +  //
> > +  epEvent =3D ((epEvent & DWC_XDCI_EVENT_BUFF_EP_EVENT_MASK) >>
> DWC_XDCI_EVENT_BUFF_EP_EVENT_BIT_POS);
> > +
> > +  switch (epEvent) {
> > +    case DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT:
> > +      DEBUG ((DEBUG_INFO, "XFER_CMPLT ep %d\n", EpNum));
> > +      if (EpNum > 1) {
> > +        DwcXdciProcessEpXferDone (CoreHandle, EpNum);
> > +      } else {
> > +        DwcXdciProcessEp0XferPhaseDone (CoreHandle, EpNum);
> > +      }
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS:
> > +      DEBUG ((DEBUG_INFO, "IN_PROGRESS\n"));
> > +      break;
> > +
> > +    case DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY:
> > +      DEBUG ((DEBUG_INFO, "NOT_READY ep %d\n", EpNum));
> > +      if (EpNum > 1) {
> > +        //
> > +        // Endpoint transfer is not ready
> > +        //
> > +        DwcXdciProcessEpXferNotReady (CoreHandle, EpNum);
> > +      } else {
> > +        DwcXdciProcessEp0XferNotReady (CoreHandle, EpNum,
> epEventStatus);
> > +      }
> > +      break;
> > +
> > +    default:
> > +      DEBUG ((DEBUG_INFO, "DwcXdciProcessEpEvent: UNKNOWN EP
> event\n"));
> > +      break;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Internal function:
> > +  This function is used to process events on single interrupt line
> > +  @CoreHandle: xDCI controller handle address
> > +  @eventCount:  event bytes to process
> > +  @ProcessedEventCount: address to save the size
> > +  (in bytes) of event Processed
> > +  Processed
> > +
> > +**/
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciProcessInterruptLineEvents (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              eventCount,
> > +  IN UINT32              *ProcessedEventCount
> > +  )
> > +{
> > +  UINT32    ProcessedEventSize =3D 0;
> > +  UINT32    currentEventAddr;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessInterruptLineEvents:
> INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (CoreHandle->CurrentEventBuffer =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciProcessInterruptLineEvents:
> INVALID event Buffer\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  currentEventAddr =3D (UINT32)(UINTN)(CoreHandle->CurrentEventBuffer)=
;
> > +
> > +  //
> > +  // Process eventCount/eventSize number of events
> > +  // in this run
> > +  //
> > +  while (eventCount) {
> > +    if (CoreHandle->CurrentEventBuffer->Event &
> DWC_XDCI_EVENT_DEV_MASK) {
> > +      DwcXdciProcessDeviceEvent (
> > +        CoreHandle,
> > +        CoreHandle->CurrentEventBuffer,
> > +        &ProcessedEventSize
> > +        );
> > +    } else {
> > +      DwcXdciProcessEpEvent (
> > +        CoreHandle,
> > +        CoreHandle->CurrentEventBuffer,
> > +        &ProcessedEventSize);
> > +    }
> > +
> > +    eventCount -=3D ProcessedEventSize;
> > +    *ProcessedEventCount +=3D ProcessedEventSize;
> > +    if ((currentEventAddr + ProcessedEventSize) >=3D
> > +        ((UINT32)(UINTN)(CoreHandle->AlignedEventBuffers) +
> (sizeof(DWC_XDCI_EVENT_BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER))
> > +       ) {
> > +      currentEventAddr =3D (UINT32)(UINTN)(CoreHandle-
> >AlignedEventBuffers);
> > +      DEBUG ((DEBUG_INFO, "DwcXdciProcessInterruptLineEvents: Event
> Buffer bound reached\n"));
> > +    } else {
> > +      currentEventAddr +=3D ProcessedEventSize;
> > +    }
> > +
> > +    CoreHandle->CurrentEventBuffer =3D (DWC_XDCI_EVENT_BUFFER
> *)(UINTN)currentEventAddr;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +//
> > +// DWC XDCI APIs
> > +//
> > +
> > +/**
> > +  Interface:
> > +
> > +  This function is used to initialize the xDCI core
> > +  @configParams: Parameters from app to configure the core
> > +  @deviceCorePtr:  HW-independent APIs handle for device core
> > +  @CoreHandle: xDCI controller handle retured
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreInit (
> > +  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
> > +  IN VOID                     *deviceCorePtr,
> > +  IN VOID                     **CoreHandle
> > +  )
> > +{
> > +  EFI_STATUS                      status =3D EFI_DEVICE_ERROR;
> > +  UINT32                          BaseAddr;
> > +  XDCI_CORE_HANDLE                *LocalCoreHandle;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> > +  UINT32                          MaxDelayIter =3D
> DWC_XDCI_MAX_DELAY_ITERATIONS;
> > +  UINT8                           i;
> > +
> > +  LocalCoreHandle =3D (XDCI_CORE_HANDLE *)AllocateZeroPool
> (sizeof(XDCI_CORE_HANDLE));
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  if (LocalCoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to allocate handle fo=
r
> xDCI\n"));
> > +    return EFI_OUT_OF_RESOURCES;
> > +  }
> > +
> > +  ZeroMem (LocalCoreHandle, sizeof(XDCI_CORE_HANDLE));
> > +
> > +  LocalCoreHandle->ParentHandle =3D deviceCorePtr;
> > +
> > +  *CoreHandle =3D (VOID *)LocalCoreHandle;
> > +
> > +  LocalCoreHandle->Id =3D ConfigParams->ControllerId;
> > +  LocalCoreHandle->BaseAddress =3D BaseAddr =3D ConfigParams-
> >BaseAddress;
> > +  LocalCoreHandle->Flags =3D ConfigParams->Flags;
> > +  LocalCoreHandle->DesiredSpeed =3D LocalCoreHandle->ActualSpeed =3D
> ConfigParams->Speed;
> > +  LocalCoreHandle->Role =3D ConfigParams->Role;
> > +
> > +  DEBUG ((DEBUG_INFO, "Resetting the USB core\n"));
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCTL_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) |
> DWC_XDCI_DCTL_CSFTRST_MASK
> > +    );
> > +  //
> > +  // Wait until core soft reset completes
> > +  //
> > +  do {
> > +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) &
> DWC_XDCI_DCTL_CSFTRST_MASK)) {
> > +      break;
> > +    } else {
> > +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> > +    }
> > +  } while (--MaxDelayIter);
> > +
> > +  if (!MaxDelayIter) {
> > +    DEBUG ((DEBUG_INFO, "Failed to reset device controller\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "USB core has been reset\n"));
> > +
> > +  //
> > +  // All FIFOs are flushed at this point
> > +  //
> > +  //
> > +  // Ensure we have EP0 Rx/Tx handles initialized
> > +  //
> > +  LocalCoreHandle->EpHandles[0].EpInfo.EpNum =3D 0;
> > +  LocalCoreHandle->EpHandles[0].EpInfo.EpDir =3D UsbEpDirOut;
> > +  LocalCoreHandle->EpHandles[0].EpInfo.EpType =3D
> USB_ENDPOINT_CONTROL;
> > +  LocalCoreHandle->EpHandles[0].EpInfo.MaxPktSize =3D
> DWC_XDCI_SS_CTRL_EP_MPS;
> > +  //
> > +  // 0 means burst size of 1
> > +  //
> > +  LocalCoreHandle->EpHandles[0].EpInfo.BurstSize =3D 0;
> > +
> > +  LocalCoreHandle->EpHandles[1].EpInfo.EpNum =3D 0;
> > +  LocalCoreHandle->EpHandles[1].EpInfo.EpDir =3D UsbEpDirIn;
> > +  LocalCoreHandle->EpHandles[1].EpInfo.EpType =3D
> USB_ENDPOINT_CONTROL;
> > +  LocalCoreHandle->EpHandles[1].EpInfo.MaxPktSize =3D
> DWC_XDCI_SS_CTRL_EP_MPS;
> > +  //
> > +  // 0 means burst size of 1
> > +  //
> > +  LocalCoreHandle->EpHandles[1].EpInfo.BurstSize =3D 0;
> > +
> > +  LocalCoreHandle->DevState =3D UsbDevStateDefault;
> > +
> > +  //
> > +  // Clear KeepConnect bit so we can allow disconnect and
> > +  // re-connect. Stay in RX_DETECT state
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCTL_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) &
> > +    (~DWC_XDCI_DCTL_KEEP_CONNECT_MASK) &
> > +    ((~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK) |
> (DWC_XDCI_DCTL_STATE_CHANGE_REQ_RX_DETECT <<
> DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS))
> > +    );
> > +
> > +  DEBUG ((DEBUG_INFO, "Device controller Synopsys ID: %x\n",
> UsbRegRead (BaseAddr, DWC_XDCI_GSNPSID_REG)));
> > +  DEBUG ((DEBUG_INFO, "Default value of xDCI GSBUSCFG0 and
> GSBUSCFG1: %x, %x\n",
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG0_REG),
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG1_REG)));
> > +
> > +  DEBUG ((DEBUG_INFO, "Default value of xDCI GTXTHRCFG and
> GRXTHRCFG: %x, %x\n",
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GTXTHRCFG_REG),
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GRXTHRCFG_REG)));
> > +
> > +  //
> > +  // Clear ULPI auto-resume bit
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_GUSB2PHYCFG_REG (0),
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)) &
> ~DWC_XDCI_GUSB2PHYCFG_ULPI_AUTO_RESUME_MASK)
> > +    );
> > +
> > +  DEBUG ((DEBUG_INFO, "Default value of xDCI GUSB2PHYCFG and
> GUSB3PIPECTL: %x, %x\n",
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)),
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG (0))));
> > +  //
> > +  // Only one RxFIFO
> > +  //
> > +  DEBUG ((DEBUG_INFO, "Default value of DWC_XDCI_GRXFIFOSIZ: %x\n",
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GRXFIFOSIZ_REG (0))));
> > +
> > +  for (i =3D 0; i < DWC_XDCI_MAX_ENDPOINTS; i++) {
> > +    DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_GTXFIFOSIZ
> %d: %x\n",
> > +            i, UsbRegRead (BaseAddr, DWC_XDCI_GTXFIFOSIZ_REG (i))));
> > +  }
> > +
> > +  //
> > +  // TODO: Need to check if TxFIFO should start where RxFIFO ends
> > +  // or default is correct i.e. TxFIFO starts at 0 just like RxFIFO
> > +  //
> > +
> > +  //
> > +  // Allocate and Initialize Event Buffers
> > +  //
> > +  LocalCoreHandle->MaxDevIntLines =3D ((UsbRegRead (BaseAddr,
> DWC_XDCI_GHWPARAMS1_REG) &
> > +                                           DWC_XDCI_GHWPARAMS1_NUM_INT=
_MASK) >>
> > +                                           DWC_XDCI_GHWPARAMS1_NUM_INT=
_BIT_POS);
> > +
> > +  DEBUG ((DEBUG_INFO, "Max dev int lines: %d\n", LocalCoreHandle-
> >MaxDevIntLines));
> > +  //
> > +  // One event Buffer per interrupt line.
> > +  //  Need to align it to size of event Buffer
> > +  //  Buffer needs to be big enough. Otherwise the core
> > +  //  won't operate
> > +  //
> > +  LocalCoreHandle->AlignedEventBuffers =3D (DWC_XDCI_EVENT_BUFFER *)
> > +                                             ((UINT32)(UINTN)(LocalCor=
eHandle-
> >EventBuffers) +
> > +                                             ((sizeof (DWC_XDCI_EVENT_=
BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER) -
> > +                                             (((UINT32)(UINTN)(LocalCo=
reHandle-
> >EventBuffers)) %
> > +                                             (sizeof (DWC_XDCI_EVENT_B=
UFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER))));
> > +
> > +  for (i =3D 0; i < LocalCoreHandle->MaxDevIntLines; i++) {
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_GEVNTADR_REG (i),
> > +      (UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers + i *
> sizeof(DWC_XDCI_EVENT_BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER)
> > +      );
> > +
> > +    //
> > +    // Clear High 32bit address register, GEVNTADR register is 64-bit =
register
> > +    // default is 0xffffffffffffffff
> > +    //
> > +    UsbRegWrite (BaseAddr, DWC_XDCI_GEVNTADR_REG (i) + 4,
> 0x00000000);
> > +
> > +    LocalCoreHandle->CurrentEventBuffer =3D LocalCoreHandle-
> >AlignedEventBuffers;
> > +    //
> > +    // Write size and clear the mask
> > +    //
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_EVNTSIZ_REG (i),
> > +      sizeof (DWC_XDCI_EVENT_BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER
> > +      );
> > +
> > +    //
> > +    // Write 0 to the event count register as the last step
> > +    //
> > +    //  for event configuration
> > +    //
> > +    UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i), 0);
> > +
> > +    DEBUG ((DEBUG_INFO, "Value of xDCI Event Buffer %d: %x, Size: %x,
> Count: %x\n",
> > +                        i,
> > +                        UsbRegRead (BaseAddr, DWC_XDCI_GEVNTADR_REG (i=
)),
> > +                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTSIZ_REG (i)=
),
> > +                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (=
i))));
> > +  }
> > +
> > +    //
> > +    // Program Global Control Register to disable scaledown,
> > +    // disable clock gating
> > +    //
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_GCTL_REG,
> > +      ((UsbRegRead(BaseAddr, DWC_XDCI_GCTL_REG) &
> > +                    ~(DWC_XDCI_GCTL_SCALE_DOWN_MODE_MASK +
> DWC_XDCI_GCTL_RAMCLKSEL_MASK +
> DWC_XDCI_GCTL_DISABLE_SCRAMB_MASK)) |
> > +                    DWC_XDCI_GCTL_DISABLE_CLK_GATING_MASK |
> > +                    (DWC_XDCI_GCTL_PRT_CAP_DEVICE <<
> DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)));
> > +
> > +    DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_GCTL_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG)));
> > +
> > +  //
> > +  // TODO: Program desired Speed and set LPM capable
> > +  // We will do this when SuperSpeed works. For now,
> > +  // force into High-Speed mode to aVOID anyone trying this
> > +  // on Super Speed port
> > +  //
> > +#ifdef SUPPORT_SUPER_SPEED
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCFG_REG,
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) &
> ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | LocalCoreHandle-
> >DesiredSpeed
> > +    );
> > +#else
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCFG_REG,
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) &
> ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) |
> DWC_XDCI_DCFG_DESIRED_HS_SPEED
> > +    );
> > +#endif
> > +
> > +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DCFG_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG)));
> > +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DSTS_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG)));
> > +
> > +  //
> > +  // Enable Device Interrupt Events
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DEVTEN_REG,
> > +    DWC_XDCI_DEVTEN_DEVICE_INTS
> > +    );
> > +  //
> > +  // Program the desired role
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_GCTL_REG,
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG) &
> ~DWC_XDCI_GCTL_PRT_CAP_DIR_MASK) | (LocalCoreHandle->Role <<
> DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)
> > +    );
> > +  //
> > +  // Clear USB2 suspend for start new config command
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_GUSB2PHYCFG_REG (0),
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) &
> ~DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
> > +    );
> > +
> > +  //
> > +  // Clear USB3 suspend for start new config command
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_GUSB3PIPECTL_REG (0),
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) &
> ~DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
> > +    );
> > +
> > +  //
> > +  // Issue DEPSTARTCFG command for EP0
> > +  //
> > +  status =3D DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[0].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> > +             EPCMD_START_NEW_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> START_NEW_CONFIG EP command on xDCI\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status =3D DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             0,
> > +             EPCMD_START_NEW_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> START_NEW_CONFIG EP command on xDCI\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue DEPCFG command for EP0
> > +  //
> > +  status =3D DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[0].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> SET_EP_CONFIG command on xDCI for EP0\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status =3D DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             0,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams);
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> SET_EP_CONFIG command on xDCI for EP0\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue DEPCFG command for EP1
> > +  //
> > +  status =3D DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[1].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> SET_EP_CONFIG command on xDCI for EP1\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status =3D DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             1,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> SET_EP_CONFIG command on xDCI for EP1\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue DEPXFERCFG command for EP0
> > +  //
> > +  status =3D DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[0].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status =3D DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             0,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue DEPXFERCFG command for EP1
> > +  //
> > +  status =3D DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[1].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status =3D DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             1,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Prepare a Buffer for SETUP packet
> > +  //
> > +  LocalCoreHandle->Trbs =3D (DWC_XDCI_TRB *)((UINTN)
> > +                            LocalCoreHandle->UnalignedTrbs +
> > +                            (UINTN)(DWC_XDCI_TRB_BYTE_ALIGNMENT -
> > +                            ((UINT32)(UINTN)LocalCoreHandle->Unaligned=
Trbs %
> > +                            DWC_XDCI_TRB_BYTE_ALIGNMENT)));
> > +
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@
> unalignedTrbs address is 0x%x\n", LocalCoreHandle->UnalignedTrbs));
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ TRB
> address is 0x%x\n", LocalCoreHandle->Trbs));
> > +  //
> > +  // Allocate Setup Buffer that is 8-byte aligned
> > +  //
> > +  LocalCoreHandle->AlignedSetupBuffer =3D LocalCoreHandle-
> >DefaultSetupBuffer +
> > +                                            (DWC_XDCI_SETUP_BUFF_SIZE =
-
> > +                                            ((UINT32)(UINTN)(LocalCore=
Handle-
> >DefaultSetupBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
> > +
> > +  //
> > +  // Aligned Buffer for status phase
> > +  //
> > +  LocalCoreHandle->AlignedMiscBuffer =3D LocalCoreHandle->MiscBuffer +
> > +                                           (DWC_XDCI_SETUP_BUFF_SIZE -
> > +                                           ((UINT32)(UINTN)(LocalCoreH=
andle-
> >AlignedMiscBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
> > +
> > +
> > +  //
> > +  // Enable Physical Endpoints 0
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EP_DALEPENA_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 0)
> > +    );
> > +  //
> > +  // Enable Physical Endpoints 1
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EP_DALEPENA_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 1)
> > +    );
> > +
> > +  DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_DEVTEN_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DEVTEN_REG)));
> > +  return status;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to de-initialize the xDCI core
> > +  @CoreHandle: xDCI controller handle
> > +  @flags: Special flags for de-initializing the core in
> > +  particular way
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreDeinit (
> > +  IN VOID      *CoreHandle,
> > +  IN UINT32    flags
> > +  )
> > +{
> > +  FreePool (CoreHandle);
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to register event callback function
> > +  @CoreHandle: xDCI controller handle
> > +  @event: Event for which callback is to be registered
> > +  @callbackFn: Callback function to invoke after event occurs
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreRegisterCallback (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_DEVICE_EVENT_ID       Event,
> > +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE  *LocalCoreHandle =3D (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +
> > +  if (LocalCoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreRegisterCallback: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "DwcXdciCoreRegisterCallback: event is %d\n",
> Event));
> > +  switch (Event) {
> > +    case USB_DEVICE_DISCONNECT_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevDisconnectCallback =3D
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_RESET_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevBusResetCallback =3D
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_CONNECTION_DONE:
> > +      LocalCoreHandle->EventCallbacks.DevResetDoneCallback =3D
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_STATE_CHANGE_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevLinkStateCallback =3D
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_WAKEUP_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevWakeupCallback =3D CallbackFu=
nc;
> > +      break;
> > +
> > +    case USB_DEVICE_HIBERNATION_REQ_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevHibernationCallback =3D
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_SOF_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevSofCallback =3D CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_ERRATIC_ERR_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevErraticErrCallback =3D
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_CMD_CMPLT_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevCmdCmpltCallback =3D
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_BUFF_OVERFLOW_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevBuffOvflwCallback =3D
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_TEST_LMP_RX_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevTestLmpRxCallback =3D
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_SETUP_PKT_RECEIVED:
> > +      LocalCoreHandle->EventCallbacks.DevSetupPktReceivedCallback =3D
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_XFER_NRDY:
> > +      LocalCoreHandle->EventCallbacks.DevXferNrdyCallback =3D
> CallbackFunc;
> > +      break;
> > +
> > +    case USB_DEVICE_XFER_DONE:
> > +      LocalCoreHandle->EventCallbacks.DevXferDoneCallback =3D
> CallbackFunc;
> > +      break;
> > +
> > +    default:
> > +      break;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to unregister event callback function
> > +  @CoreHandle: xDCI controller handle
> > +  @event: Event for which callback function is to be unregistered
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreUnregisterCallback (
> > +  IN VOID                   *CoreHandle,
> > +  IN USB_DEVICE_EVENT_ID    event
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE  *LocalCoreHandle =3D (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +
> > +  if (LocalCoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreUnregisterCallback: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  switch (event) {
> > +    case USB_DEVICE_DISCONNECT_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevDisconnectCallback =3D NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_RESET_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevBusResetCallback =3D NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_CONNECTION_DONE:
> > +      LocalCoreHandle->EventCallbacks.DevResetDoneCallback =3D NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_STATE_CHANGE_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevLinkStateCallback =3D NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_WAKEUP_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevWakeupCallback =3D NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_HIBERNATION_REQ_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevHibernationCallback =3D NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_SOF_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevSofCallback =3D NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_ERRATIC_ERR_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevErraticErrCallback =3D NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_CMD_CMPLT_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevCmdCmpltCallback =3D NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_BUFF_OVERFLOW_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevBuffOvflwCallback =3D NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_TEST_LMP_RX_EVENT:
> > +      LocalCoreHandle->EventCallbacks.DevTestLmpRxCallback =3D NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_SETUP_PKT_RECEIVED:
> > +      LocalCoreHandle->EventCallbacks.DevSetupPktReceivedCallback =3D
> NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_XFER_NRDY:
> > +      LocalCoreHandle->EventCallbacks.DevXferNrdyCallback =3D NULL;
> > +      break;
> > +
> > +    case USB_DEVICE_XFER_DONE:
> > +      LocalCoreHandle->EventCallbacks.DevXferDoneCallback =3D NULL;
> > +      break;
> > +
> > +    default:
> > +      break;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used as an interrupt service routine
> > +  @CoreHandle: xDCI controller handle
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreIsrRoutine (
> > +  IN VOID     *CoreHandle
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE    *LocalCoreHandle =3D (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  UINT32              BaseAddr;
> > +  UINT32              eventCount;
> > +  UINT32              ProcessedEventCount;
> > +  UINT32              i;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreIsrRoutine: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (LocalCoreHandle->InterrupProcessing =3D=3D TRUE) {
> > +    DEBUG ((DEBUG_INFO, "interrupProcessing.........\n"));
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  BaseAddr =3D LocalCoreHandle->BaseAddress;
> > +  //
> > +  // Event Buffer corresponding to each interrupt line needs
> > +  // to be Processed
> > +  //
> > +  LocalCoreHandle->InterrupProcessing =3D TRUE;
> > +  for (i =3D 0; i < LocalCoreHandle->MaxDevIntLines; i++) {
> > +    //
> > +    // Get the number of events HW has written for this
> > +    //  interrupt line
> > +    //
> > +    eventCount =3D UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG
> (i));
> > +    eventCount &=3D DWC_XDCI_EVNTCOUNT_MASK;
> > +    ProcessedEventCount =3D 0;
> > +
> > +    //
> > +    // Process interrupt line Buffer only if count is non-zero
> > +    //
> > +    if (eventCount) {
> > +      //
> > +      // Process events in this Buffer
> > +      //
> > +      DwcXdciProcessInterruptLineEvents (LocalCoreHandle, eventCount,
> &ProcessedEventCount);
> > +      //
> > +      // Write back the Processed number of events so HW decrements it
> from current
> > +      // event count
> > +      //
> > +      UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i),
> ProcessedEventCount);
> > +    }
> > +  }
> > +  LocalCoreHandle->InterrupProcessing =3D FALSE;
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used as an interrupt service routine and it process=
es only
> one event at a time.
> > +  @CoreHandle: xDCI controller handle
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreIsrRoutineTimerBased (
> > +  IN VOID     *CoreHandle
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE    *LocalCoreHandle =3D (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  UINT32              BaseAddr;
> > +  UINT32              eventCount;
> > +  UINT32              ProcessedEventCount;
> > +  UINT32              currentEventAddr;
> > +  UINT32              ProcessedEventSize =3D 0;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreIsrRoutineTimerBased: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (LocalCoreHandle->CurrentEventBuffer =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreIsrRoutineTimerBased:
> INVALID event Buffer\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  BaseAddr =3D LocalCoreHandle->BaseAddress;
> > +
> > +  eventCount =3D UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0))
> & DWC_XDCI_EVNTCOUNT_MASK;
> > +
> > +  if (LocalCoreHandle->InterrupProcessing =3D=3D TRUE) {
> > +    DEBUG ((DEBUG_INFO, "interrupProcessing.........\n"));
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  LocalCoreHandle->InterrupProcessing =3D TRUE;
> > +
> > +  ProcessedEventCount =3D 0;
> > +  currentEventAddr =3D (UINT32)(UINTN)(LocalCoreHandle-
> >CurrentEventBuffer);
> > +
> > +  if (LocalCoreHandle->CurrentEventBuffer->Event &
> DWC_XDCI_EVENT_DEV_MASK) {
> > +    DwcXdciProcessDeviceEvent (
> > +      LocalCoreHandle,
> > +      LocalCoreHandle->CurrentEventBuffer,
> > +      &ProcessedEventSize
> > +      );
> > +  } else {
> > +    DwcXdciProcessEpEvent (
> > +      LocalCoreHandle,
> > +      LocalCoreHandle->CurrentEventBuffer,
> > +      &ProcessedEventSize);
> > +  }
> > +
> > +  eventCount -=3D ProcessedEventSize;
> > +  ProcessedEventCount +=3D ProcessedEventSize;
> > +  if ((currentEventAddr + ProcessedEventSize) >=3D
> > +      ((UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers) +
> (sizeof(DWC_XDCI_EVENT_BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER))
> > +     ) {
> > +    currentEventAddr =3D (UINT32)(UINTN)(LocalCoreHandle-
> >AlignedEventBuffers);
> > +    DEBUG ((DEBUG_INFO, "DwcXdciProcessInterruptLineEvents: Event
> Buffer bound reached\n"));
> > +  } else {
> > +    currentEventAddr +=3D ProcessedEventSize;
> > +  }
> > +
> > +  LocalCoreHandle->CurrentEventBuffer =3D (DWC_XDCI_EVENT_BUFFER
> *)(UINTN)currentEventAddr;
> > +  UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (0),
> ProcessedEventCount);
> > +  LocalCoreHandle->InterrupProcessing =3D FALSE;
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to enable xDCI to connect to the host
> > +  @CoreHandle: xDCI controller handle
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreConnect (
> > +  IN VOID     *CoreHandle
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE    *LocalCoreHandle =3D (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  UINT32              MaxDelayIter =3D DWC_XDCI_MAX_DELAY_ITERATIONS;
> > +  UINT32              BaseAddr;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreConnect: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr =3D LocalCoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Clear KeepConnect bit so we can allow disconnect and re-connect
> > +  // Also issue No action on state change to aVOID any link change
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCTL_REG,
> > +    (UsbRegRead(BaseAddr, DWC_XDCI_DCTL_REG) &
> ~DWC_XDCI_DCTL_KEEP_CONNECT_MASK) &
> ~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK
> > +    );
> > +
> > +  //
> > +  // Set Run bit to connect to the host
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCTL_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) |
> DWC_XDCI_DCTL_RUN_STOP_MASK
> > +    );
> > +
> > +  //
> > +  // Wait until core starts running
> > +  //
> > +  do {
> > +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG) &
> DWC_XDCI_DSTS_DEV_CTRL_HALTED_MASK)) {
> > +      break;
> > +    } else {
> > +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> > +    }
> > +  } while (--MaxDelayIter);
> > +
> > +  if (!MaxDelayIter) {
> > +    DEBUG ((DEBUG_INFO, "Failed to run the device controller\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to disconnect xDCI from the host
> > +  @CoreHandle: xDCI controller handle
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreDisconnect (
> > +  IN VOID    *CoreHandle
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE  *LocalCoreHandle =3D (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  UINT32            MaxDelayIter =3D DWC_XDCI_MAX_DELAY_ITERATIONS;
> > +  UINT32            BaseAddr;
> > +  UINT32            eventCount;
> > +  UINT32            dsts;
> > +  UINT32            i;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr =3D LocalCoreHandle->BaseAddress;
> > +
> > +  eventCount =3D UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG
> (0));
> > +  eventCount &=3D DWC_XDCI_EVNTCOUNT_MASK;
> > +
> > +  DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: eventCount=3D%d\n",
> eventCount));
> > +  while (eventCount) {
> > +    DwcXdciCoreIsrRoutine(LocalCoreHandle);
> > +    eventCount =3D UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG
> (0));
> > +    eventCount &=3D DWC_XDCI_EVNTCOUNT_MASK;
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: eventCount=3D%d\n",
> eventCount));
> > +  }
> > +
> > +  //
> > +  // Issue DEPENDXFER for active transfers
> > +  //
> > +  for (i =3D 0; i < DWC_XDCI_MAX_ENDPOINTS; i++){
> > +    if (LocalCoreHandle->EpHandles[i].CurrentXferRscIdx){
> > +      DwcXdciEndXfer(LocalCoreHandle, i);
> > +    }
> > +  }
> > +  //
> > +  // Clear Run bit to disconnect from host
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCTL_REG,
> > +    UsbRegRead(BaseAddr, DWC_XDCI_DCTL_REG) &
> ~DWC_XDCI_DCTL_RUN_STOP_MASK);
> > +
> > +  //
> > +  // Wait until core is halted
> > +  //
> > +  do {
> > +    dsts =3D UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG);
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: waiting halt:
> DSTS=3D0x%x\n", dsts));
> > +    if ((dsts & DWC_XDCI_DSTS_DEV_CTRL_HALTED_MASK) !=3D 0){
> > +      break;
> > +    } else {
> > +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> > +    }
> > +  } while (--MaxDelayIter);
> > +
> > +  if (!MaxDelayIter) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreDisconnect: Failed to halt the
> device controller\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to obtain current USB bus Speed
> > +  @CoreHandle: xDCI controller handle
> > +  @Speed: Address of variable to save the Speed
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreGetSpeed (
> > +  IN VOID         *CoreHandle,
> > +  IN USB_SPEED    *Speed
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE *LocalCoreHandle =3D (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreGetSpeed: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (Speed =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreGetSpeed: INVALID
> parameter\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  *Speed =3D UsbRegRead (LocalCoreHandle->BaseAddress,
> DWC_XDCI_DSTS_REG) & DWC_XDCI_DSTS_CONN_SPEED_MASK;
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to obtain current USB bus Speed
> > +  @CoreHandle: xDCI controller handle
> > +  @address: USB address to set (assigned by USB host)
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreSetAddress (
> > +  IN VOID      *CoreHandle,
> > +  IN UINT32    address
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE  *LocalCoreHandle =3D (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  UINT32            BaseAddr;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetAddress: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr =3D LocalCoreHandle->BaseAddress;
> > +
> > +  DEBUG ((DEBUG_INFO, "DwcXdciCoreSetAddress is 0x%x \n", address));
> > +  //
> > +  // Program USB device address
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCFG_REG,
> > +    (UsbRegRead(BaseAddr, DWC_XDCI_DCFG_REG) &
> ~DWC_XDCI_DCFG_DEV_ADDRESS_MASK) | (address <<
> DWC_XDCI_DCFG_DEV_ADDRESS_BIT_POS)
> > +    );
> > +
> > +  LocalCoreHandle->DevState =3D UsbDevStateAddress;
> > +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_GCTL_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG)));
> > +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DEVTEN_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DEVTEN_REG)));
> > +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DCFG_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG)));
> > +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DSTS_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG)));
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to set configuration
> > +  @CoreHandle: xDCI controller handle
> > +  @ConfigNum: config num to set (assigned by USB host)
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreSetConfig (
> > +  IN VOID      *CoreHandle,
> > +  IN UINT32    ConfigNum
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE              *LocalCoreHandle =3D (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> > +  EFI_STATUS                    status;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetConfig: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Issue DEPSTARTCFG command on EP0 (new config for
> > +  // non-control EPs)
> > +  //
> > +  status =3D DwcXdciCoreInitEpCmdParams (
> > +            LocalCoreHandle,
> > +            &LocalCoreHandle->EpHandles[0].EpInfo,
> > +            DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> > +            EPCMD_START_NEW_CONFIG,
> > +            &EpCmdParams
> > +            );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetConfig: Failed to init params
> for EPCMD_START_NEW_CONFIG command\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status =3D DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             0,
> > +             (EPCMD_START_NEW_CONFIG | (2 <<
> DWC_XDCI_EPCMD_RES_IDX_BIT_POS)),
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreSetConfig: Failed to issue
> EPCMD_START_NEW_CONFIG command\n"));
> > +    return status;
> > +  }
> > +
> > +  return status;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to set link state
> > +  @CoreHandle: xDCI controller handle
> > +  @state: Desired link state
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciSetLinkState (
> > +  IN VOID                        *CoreHandle,
> > +  IN USB_DEVICE_SS_LINK_STATE    state
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE  *LocalCoreHandle =3D (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  UINT32            BaseAddr;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciSetLinkState: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr =3D LocalCoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Clear old mask
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCTL_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) &
> ~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK
> > +    );
> > +
> > +  //
> > +  // Request new state
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCTL_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) | (state <<
> DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS)
> > +    );
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to initialize endpoint
> > +  @CoreHandle: xDCI controller handle
> > +  @EpInfo: Address of structure describing properties of EP
> > +  to be initialized
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciInitEp (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE              *LocalCoreHandle =3D (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> > +  EFI_STATUS                    status;
> > +  UINT32                        EpNum;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Convert to physical endpoint
> > +  //
> > +  EpNum =3D DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> > +
> > +  //
> > +  // Save EP properties
> > +  //
> > +  CopyMem (&(LocalCoreHandle->EpHandles[EpNum].EpInfo), EpInfo,
> sizeof (USB_EP_INFO));
> > +
> > +  //
> > +  // Init CheckFlag
> > +  //
> > +  LocalCoreHandle->EpHandles[EpNum].CheckFlag =3D FALSE;
> > +
> > +  //
> > +  // Init DEPCFG cmd params for EP
> > +  //
> > +  status =3D DwcXdciCoreInitEpCmdParams (
> > +             CoreHandle,
> > +             &LocalCoreHandle->EpHandles[EpNum].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to init params for
> EPCMD_SET_EP_CONFIG command\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status =3D DwcXdciCoreIssueEpCmd (
> > +             CoreHandle,
> > +             EpNum,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to issue
> EPCMD_SET_EP_CONFIG command\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue a DEPXFERCFG command for endpoint
> > +  //
> > +  status =3D DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[EpNum].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to init params for
> EPCMD_SET_EP_XFER_RES_CONFIG command\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status =3D DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             EpNum,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciInitEp: Failed to issue
> EPCMD_SET_EP_XFER_RES_CONFIG command\n"));
> > +  }
> > +
> > +  return status;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to enable non-Ep0 endpoint
> > +  @CoreHandle: xDCI controller handle
> > +  @EpInfo: Address of structure describing properties of EP
> > +  to be enabled
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpEnable (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE  *LocalCoreHandle =3D (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  UINT32            EpNum;
> > +  UINT32            BaseAddr;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpEnable: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr =3D LocalCoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Convert to physical endpoint
> > +  //
> > +  EpNum =3D DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> > +
> > +  //
> > +  // Enable Physical Endpoint EpNum
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EP_DALEPENA_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 <<
> EpNum)
> > +    );
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to disable non-Ep0 endpoint
> > +  @CoreHandle: xDCI controller handle
> > +  @EpInfo: Address of structure describing properties of EP
> > +  to be enabled
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpDisable (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE  *LocalCoreHandle =3D (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  UINT32            EpNum;
> > +  UINT32            BaseAddr;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpDisable: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr =3D LocalCoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Convert to physical endpoint
> > +  //
> > +  EpNum =3D DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> > +
> > +  //
> > +  // Disable Physical Endpoint EpNum
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EP_DALEPENA_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) & ~(1 <<
> EpNum)
> > +    );
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to STALL and endpoint
> > +  @CoreHandle: xDCI controller handle
> > +  @EpInfo: Address of structure describing properties of EP
> > +  to be enabled
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpStall (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE              *LocalCoreHandle =3D (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> > +  EFI_STATUS                    status;
> > +  UINT32                        EpNum;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpStall: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Convert to physical endpoint
> > +  //
> > +  EpNum =3D DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> > +
> > +  //
> > +  // Set Ep State Info
> > +  //
> > +  if (LocalCoreHandle->EpHandles[EpNum].State !=3D
> USB_EP_STATE_STALLED) {
> > +    LocalCoreHandle->EpHandles[EpNum].OrgState =3D LocalCoreHandle-
> >EpHandles[EpNum].State;
> > +    LocalCoreHandle->EpHandles[EpNum].State =3D USB_EP_STATE_STALLED;
> > +  }
> > +  //
> > +  // Issue a DWC_XDCI_EPCMD_SET_STALL for EP
> > +  // Reset params
> > +  //
> > +  EpCmdParams.Param0 =3D EpCmdParams.Param1 =3D
> EpCmdParams.Param2 =3D 0;
> > +
> > + //
> > + // Issue the command
> > + //
> > + status =3D DwcXdciCoreIssueEpCmd (
> > +            LocalCoreHandle,
> > +            EpNum,
> > +            DWC_XDCI_EPCMD_SET_STALL,
> > +            &EpCmdParams
> > +            );
> > +
> > + if (status) {
> > +   DEBUG ((DEBUG_INFO, "DwcXdciEpStall: Failed to issue EP stall
> command\n"));
> > + }
> > +
> > + return status;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to clear endpoint STALL
> > +  @CoreHandle: xDCI controller handle
> > +  @EpInfo: Address of structure describing properties of EP
> > +  to be enabled
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpClearStall (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE              *LocalCoreHandle =3D (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> > +  EFI_STATUS                    status;
> > +  UINT32                        EpNum;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpClearStall: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Convert to physical endpoint
> > +  //
> > +  EpNum =3D DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> > +
> > +  //
> > +  // Set Ep State Info
> > +  //
> > +  LocalCoreHandle->EpHandles[EpNum].State =3D LocalCoreHandle-
> >EpHandles[EpNum].OrgState;
> > +
> > +  //
> > +  // Issue a DWC_XDCI_EPCMD_CLEAR_STALL for EP
> > +  // Reset params
> > +  //
> > +  EpCmdParams.Param0 =3D EpCmdParams.Param1 =3D
> EpCmdParams.Param2 =3D 0;
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > + status =3D DwcXdciCoreIssueEpCmd (
> > +            LocalCoreHandle,
> > +            EpNum,
> > +            DWC_XDCI_EPCMD_CLEAR_STALL,
> > +            &EpCmdParams
> > +            );
> > +
> > + if (status) {
> > +   DEBUG ((DEBUG_INFO, "DwcXdciEpStall: Failed to issue EP clea stall
> command\n"));
> > + }
> > +
> > + return status;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to set endpoint in NOT READY state
> > +  @CoreHandle: xDCI controller handle
> > +  @EpInfo: Address of structure describing properties of EP
> > +  to be enabled
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpSetNrdy (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE  *LocalCoreHandle =3D (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  UINT32            EpNum;
> > +  UINT32            BaseAddr;
> > +  UINT32            MaxDelayIter =3D DWC_XDCI_MAX_DELAY_ITERATIONS;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpSetNrdy: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr =3D LocalCoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Convert to physical endpoint
> > +  //
> > +  EpNum =3D DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> > +
> > +  //
> > +  // Program the EP number in command's param reg
> > +  //
> > +  UsbRegWrite (BaseAddr, DWC_XDCI_DGCMD_PARAM_REG, EpNum);
> > +
> > +  //
> > +  // Issue EP not ready generic device command
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DGCMD_REG,
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) |
> DWC_XDCI_DGCMD_CMD_SET_EP_NRDY)
> > +    );
> > +
> > +  //
> > +  // Activate the command
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DGCMD_REG,
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) |
> DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
> > +    );
> > +
> > +  //
> > +  // Wait until command completes
> > +  //
> > +  do {
> > +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_REG) &
> DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
> > +      break;
> > +    else
> > +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> > +  } while (--MaxDelayIter);
> > +
> > +  if (!MaxDelayIter) {
> > +    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to queue receive SETUP packet request
> > +  @CoreHandle: xDCI controller handle
> > +  @Buffer: Address of Buffer to receive SETUP packet
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEp0ReceiveSetupPkt (
> > +  IN VOID     *CoreHandle,
> > +  IN UINT8    *Buffer
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE                *LocalCoreHandle =3D (XDCI_CORE_HAND=
LE
> *)CoreHandle;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> > +  EFI_STATUS                      Status =3D EFI_DEVICE_ERROR;
> > +  DWC_XDCI_TRB                    *Trb;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveSetupPkt: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  LocalCoreHandle->EpHandles[0].EpInfo.EpNum =3D 0;
> > +  LocalCoreHandle->EpHandles[0].EpInfo.EpDir =3D 0;
> > +  LocalCoreHandle->EpHandles[0].State =3D USB_EP_STATE_SETUP;
> > +  Trb =3D LocalCoreHandle->Trbs;
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciEp0ReceiveSetupPkt)\n"));
> > +
> > +  Status =3D DwcXdciCoreInitTrb (
> > +             LocalCoreHandle,
> > +             Trb,
> > +             TRBCTL_SETUP,
> > +             Buffer,
> > +             8
> > +             );
> > +
> > +  if (Status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveSetupPkt: Init TRB Failed
> \n"));
> > +    return Status;
> > +  }
> > +
> > +  //
> > +  // Issue a DEPSTRTXFER for EP0
> > +  // Reset params
> > +  //
> > +  EpCmdParams.Param0 =3D EpCmdParams.Param1 =3D
> EpCmdParams.Param2 =3D 0;
> > +
> > +  //
> > +  // Init the lower re-bits for TRB address
> > +  //
> > +  EpCmdParams.Param1 =3D (UINT32)(UINTN)Trb;
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  Status =3D DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             0,
> > +             EPCMD_START_XFER,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (Status) {
> > +    DEBUG ((DEBUG_INFO, "\nDwcXdciEp0ReceiveSetupPkt: Failed to issue
> Start Transfer command"));
> > +  }
> > +
> > +  //
> > +  // Save new resource index for this transfer
> > +  //
> > +  LocalCoreHandle->EpHandles[0].CurrentXferRscIdx =3D
> ((UsbRegRead(LocalCoreHandle->BaseAddress, DWC_XDCI_EPCMD_REG(0))
> &
> > +                                                         DWC_XDCI_EPCM=
D_RES_IDX_MASK) >>
> DWC_XDCI_EPCMD_RES_IDX_BIT_POS
> > +                                                         );
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to queue receive status packet on EP0
> > +  @CoreHandle: xDCI controller handle
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEp0ReceiveStatusPkt (
> > +  IN VOID    *CoreHandle
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE                *LocalCoreHandle =3D (XDCI_CORE_HAND=
LE
> *)CoreHandle;
> > +  DWC_XDCI_TRB                    *Trb;
> > +  DWC_XDCI_TRB_CONTROL            TrbCtrl;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> > +  EFI_STATUS                      Status;
> > +  UINT32                          BaseAddr;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveStatusPkt: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr =3D LocalCoreHandle->BaseAddress;
> > +
> > +  //
> > +  // We are receiving on EP0 so physical EP is 0
> > +  //
> > +  Trb =3D LocalCoreHandle->Trbs;
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciEp0ReceiveStatusPkt)\n"));
> > +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> > +    DEBUG ((DEBUG_INFO, "statusPkt still not transferred.\n"));
> > +    return EFI_SUCCESS;
> > +  }
> > +
> > +  LocalCoreHandle->EpHandles[0].EpInfo.EpNum =3D 0;
> > +  LocalCoreHandle->EpHandles[0].EpInfo.EpDir =3D 0;
> > +
> > +  //
> > +  // OUT data phase for 3-phased control transfer
> > +  //
> > +  TrbCtrl =3D TRBCTL_3_PHASE;
> > +
> > +  //
> > +  // Init TRB for the transfer
> > +  //
> > +  Status =3D DwcXdciCoreInitTrb (
> > +             LocalCoreHandle,
> > +             Trb,
> > +             TrbCtrl,
> > +             LocalCoreHandle->AlignedSetupBuffer,
> > +             0
> > +             );
> > +
> > +  if (!Status) {
> > +    //
> > +    // Issue a DEPSTRTXFER for EP0
> > +    // Reset params
> > +    //
> > +    EpCmdParams.Param0 =3D EpCmdParams.Param1 =3D
> EpCmdParams.Param2 =3D 0;
> > +
> > +    //
> > +    // Init the lower bits for TRB address
> > +    //
> > +    EpCmdParams.Param1 =3D (UINT32)(UINTN)Trb;
> > +
> > +    //
> > +    // Issue the command
> > +    //
> > +    Status =3D DwcXdciCoreIssueEpCmd (
> > +               LocalCoreHandle,
> > +               0,
> > +               EPCMD_START_XFER,
> > +               &EpCmdParams
> > +               );
> > +
> > +    if (Status) {
> > +      DEBUG ((DEBUG_INFO, "DwcXdciEp0ReceiveStatusPkt: Failed to issue
> Start Transfer command for EP0\n"));
> > +    }
> > +    //
> > +    // Save new resource index for this transfer
> > +    //
> > +    LocalCoreHandle->EpHandles[0].CurrentXferRscIdx =3D
> ((UsbRegRead(BaseAddr, DWC_XDCI_EPCMD_REG(0)) &
> DWC_XDCI_EPCMD_RES_IDX_MASK) >>
> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
> > +
> > +    //
> > +    // TODO: We are not using the EP state for control transfers
> > +    // right now simply because we're only supporting IN
> > +    // data phase. For the current use case, we don't
> > +    // need OUT data phase. We can add that later and we will
> > +    // add some of the state and SETUP packet awareness code
> > +    //
> > +    LocalCoreHandle->EpHandles[0].State =3D USB_EP_STATE_STATUS;
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to send status packet on EP0
> > +  @CoreHandle: xDCI controller handle
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEp0SendStatusPkt (
> > +  IN VOID    *CoreHandle
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE                *LocalCoreHandle =3D (XDCI_CORE_HAND=
LE
> *)CoreHandle;
> > +  DWC_XDCI_TRB                    *Trb;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> > +  EFI_STATUS                      Status;
> > +  UINT32                          BaseAddr;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEp0SendStatusPkt: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr =3D LocalCoreHandle->BaseAddress;
> > +
> > +  //
> > +  // We are sending on EP0 so physical EP is 1
> > +  //
> > +  Trb =3D (LocalCoreHandle->Trbs + (1 * DWC_XDCI_TRB_NUM));
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciEp0SendStatusPkt)\n"));
> > +
> > +  LocalCoreHandle->EpHandles[0].State =3D USB_EP_STATE_STATUS;
> > +  Status =3D DwcXdciCoreInitTrb (
> > +             LocalCoreHandle,
> > +             Trb,
> > +             TRBCTL_2_PHASE,
> > +             LocalCoreHandle->AlignedMiscBuffer,
> > +             0
> > +             );
> > +
> > +  if (Status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEp0SendStatusPkt: TRB failed during
> status phase\n"));
> > +    return Status;
> > +  }
> > +
> > +  //
> > +  // Issue a DEPSTRTXFER for EP1
> > +  // Reset params
> > +  //
> > +  EpCmdParams.Param0 =3D EpCmdParams.Param1 =3D
> EpCmdParams.Param2 =3D 0;
> > +
> > +  //
> > +  // Init the lower re-bits for TRB address
> > +  //
> > +  EpCmdParams.Param1 =3D (UINT32)(UINTN)Trb;
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  Status =3D DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             1,
> > +             EPCMD_START_XFER,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (Status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEp0SendStatusPkt: Failed to issue Star=
t
> Transfer on EP0\n"));
> > +  }
> > +
> > +  //
> > +  // Save new resource index for this transfer
> > +  //
> > +  LocalCoreHandle->EpHandles[1].CurrentXferRscIdx =3D
> ((UsbRegRead(BaseAddr, DWC_XDCI_EPCMD_REG(1)) &
> DWC_XDCI_EPCMD_RES_IDX_MASK) >>
> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
> > +  LocalCoreHandle->EpHandles[0].State =3D USB_EP_STATE_STATUS;
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to send data on non-EP0 endpoint
> > +  @CoreHandle: xDCI controller handle
> > +  @EpInfo: Address of structure describing properties of EP
> > +  @Buffer: Buffer containing data to transmit
> > +  @size: Size of transfer (in bytes)
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpTxData (
> > +  IN VOID                *CoreHandle,
> > +  IN USB_XFER_REQUEST    *XferReq
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE              *LocalCoreHandle =3D (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> > +  DWC_XDCI_TRB                  *Trb;
> > +  DWC_XDCI_TRB_CONTROL          TrbCtrl;
> > +  EFI_STATUS                    Status;
> > +  UINT32                        EpNum;
> > +  UINT32                        BaseAddr;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (XferReq =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: INVALID transfer
> request\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  BaseAddr =3D LocalCoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Convert to physical endpoint
> > +  //
> > +  EpNum =3D DwcXdciGetPhysicalEpNum (
> > +             XferReq->EpInfo.EpNum,
> > +             XferReq->EpInfo.EpDir
> > +             );
> > +
> > +  Trb =3D (LocalCoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM));
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciEpTxData)EpNum is %d\n", EpNum));
> > +
> > +
> > +  if (EpNum > 1)
> > +    TrbCtrl =3D TRBCTL_NORMAL;
> > +  else
> > +    TrbCtrl =3D TRBCTL_CTRL_DATA_PHASE;
> > +
> > +  if (Trb->TrbCtrl & DWC_XDCI_TRB_CTRL_HWO_MASK) {
> > +    Status =3D DwcXdciEndXfer (LocalCoreHandle, EpNum);
> > +    if (Status) {
> > +      DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: Failed to end previous
> transfer\n"));
> > +    }
> > +
> > +    Status =3D DwcXdciCoreFlushEpTxFifo (LocalCoreHandle, EpNum);
> > +    if (Status) {
> > +      DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: Failed to end previous
> transfer\n"));
> > +    }
> > +  }
> > +
> > +  //
> > +  // Data phase
> > +  //
> > +  CopyMem (&(LocalCoreHandle->EpHandles[EpNum].XferHandle),
> XferReq, sizeof (USB_XFER_REQUEST));
> > +  LocalCoreHandle->EpHandles[EpNum].State =3D USB_EP_STATE_DATA;
> > +
> > +  LocalCoreHandle->EpHandles[EpNum].Trb =3D Trb;
> > +
> > +  Status =3D DwcXdciCoreInitTrb (
> > +             LocalCoreHandle,
> > +             Trb,
> > +             TrbCtrl,
> > +             XferReq->XferBuffer,
> > +             XferReq->XferLen
> > +             );
> > +
> > +  if (Status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpTxData: TRB failed\n"));
> > +    return Status;
> > +  }
> > +
> > +  //
> > +  // Issue a DEPSTRTXFER for EP
> > +  // Reset params
> > +  //
> > +  EpCmdParams.Param0 =3D EpCmdParams.Param1 =3D
> EpCmdParams.Param2 =3D 0;
> > +
> > +  //
> > +  // Init the lower re-bits for TRB address
> > +  //
> > +  EpCmdParams.Param1 =3D (UINT32)(UINTN)Trb;
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  Status =3D DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             EpNum,
> > +             EPCMD_START_XFER,
> > +             &EpCmdParams
> > +             );
> > +
> > +  //
> > +  // Save new resource index for this transfer
> > +  //
> > +  LocalCoreHandle->EpHandles[EpNum].CurrentXferRscIdx =3D
> ((UsbRegRead (BaseAddr, DWC_XDCI_EPCMD_REG(EpNum)) &
> DWC_XDCI_EPCMD_RES_IDX_MASK) >>
> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  Interface:
> > +  This function is used to receive data on non-EP0 endpoint
> > +  @CoreHandle: xDCI controller handle
> > +  @EpInfo: Address of structure describing properties of EP
> > +  @Buffer: Buffer containing data to transmit
> > +  @size: Size of transfer (in bytes)
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpRxData (
> > +  IN VOID                *CoreHandle,
> > +  IN USB_XFER_REQUEST    *XferReq
> > +  )
> > +{
> > +  XDCI_CORE_HANDLE              *LocalCoreHandle =3D (XDCI_CORE_HANDLE
> *)CoreHandle;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS  EpCmdParams;
> > +  DWC_XDCI_TRB                  *Trb;
> > +  DWC_XDCI_TRB_CONTROL          TrbCtrl;
> > +  EFI_STATUS                    Status;
> > +  UINT32                        EpNum;
> > +  UINT32                        BaseAddr;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: INVALID handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  if (XferReq =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: INVALID transfer
> request\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  BaseAddr =3D LocalCoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Convert to physical endpoint
> > +  //
> > +  EpNum =3D DwcXdciGetPhysicalEpNum (XferReq->EpInfo.EpNum, XferReq-
> >EpInfo.EpDir);
> > +
> > +  Trb =3D (LocalCoreHandle->Trbs + (EpNum * DWC_XDCI_TRB_NUM));
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciEpRxData)EpNum is %d\n", EpNum));
> > +
> > +  if (EpNum > 1)
> > +    TrbCtrl =3D TRBCTL_NORMAL;
> > +  else
> > +    TrbCtrl =3D TRBCTL_CTRL_DATA_PHASE;
> > +
> > +  //
> > +  // If CheckFlag didn't set to FALSE, means the previous transfer req=
uest
> didn't complete,
> > +  // need to wait the previous request done.
> > +  //
> > +  if (LocalCoreHandle->EpHandles[EpNum].CheckFlag =3D=3D TRUE) {
> > +    return EFI_NOT_READY;
> > +  }
> > +
> > +  LocalCoreHandle->EpHandles[EpNum].CheckFlag =3D TRUE;
> > +
> > +  //
> > +  // Data phase
> > +  //
> > +  CopyMem (&(LocalCoreHandle->EpHandles[EpNum].XferHandle),
> XferReq, sizeof (USB_XFER_REQUEST));
> > +
> > +  LocalCoreHandle->EpHandles[EpNum].State =3D USB_EP_STATE_DATA;
> > +
> > +  LocalCoreHandle->EpHandles[EpNum].Trb =3D Trb;
> > +
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciEpRxData)XferReq->XferLen is
> 0x%x\n", XferReq->XferLen));
> > +
> > +  Status =3D DwcXdciCoreInitTrb (
> > +             LocalCoreHandle,
> > +             Trb,
> > +             TrbCtrl,
> > +             XferReq->XferBuffer,
> > +             XferReq->XferLen
> > +             );
> > +
> > +  if (Status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: TRB failed\n"));
> > +    return Status;
> > +  }
> > +  //
> > +  // Issue a DEPSTRTXFER for EP
> > +  // Reset params
> > +  //
> > +  EpCmdParams.Param0 =3D EpCmdParams.Param1 =3D
> EpCmdParams.Param2 =3D 0;
> > +
> > +  //
> > +  // Init the lower re-bits for TRB address
> > +  //
> > +  EpCmdParams.Param1 =3D (UINT32)(UINTN)Trb;
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  Status =3D DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             EpNum,
> > +             EPCMD_START_XFER,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (Status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpRxData: Failed to start transfer\n")=
);
> > +  }
> > +
> > +  //
> > +  // Save new resource index for this transfer
> > +  //
> > +  LocalCoreHandle->EpHandles[EpNum].CurrentXferRscIdx =3D
> ((UsbRegRead(BaseAddr, DWC_XDCI_EPCMD_REG(EpNum)) &
> DWC_XDCI_EPCMD_RES_IDX_MASK) >>
> DWC_XDCI_EPCMD_RES_IDX_BIT_POS);
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +
> > +STATIC
> > +EFI_STATUS
> > +DwcXdciCoreFlushEpFifo (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle,
> > +  IN UINT32              EpNum
> > +  )
> > +{
> > +  UINT32 BaseAddr;
> > +  UINT32 MaxDelayIter =3D DWC_XDCI_MAX_DELAY_ITERATIONS;
> > +  UINT32 fifoNum;
> > +  UINT32 Param;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "ERROR: DwcXdciCoreFlushEpTxFifo: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  BaseAddr =3D CoreHandle->BaseAddress;
> > +
> > +  //
> > +  // Translate to FIFOnum
> > +  // NOTE: Assuming this is a Tx EP
> > +  //
> > +  fifoNum =3D (EpNum >> 1);
> > +
> > +  //
> > +  // TODO: Currently we are only using TxFIFO 0. Later map these
> > +  // Write the FIFO num/dir param for the generic command.
> > +  //
> > +
> > +  Param =3D UsbRegRead (BaseAddr, DWC_XDCI_DGCMD_PARAM_REG);
> > +  Param &=3D ~(DWC_XDCI_DGCMD_PARAM_TX_FIFO_NUM_MASK |
> DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK);
> > +
> > +  if ((EpNum & 0x01) !=3D 0) {
> > +    Param |=3D (fifoNum |
> DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK);
> > +  } else {
> > +    Param |=3D fifoNum;
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "USB FU Flash: CMD 0x%08x :: Param 0x%08x\n",
> > +        (UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) |
> DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH |
> DWC_XDCI_DGCMD_CMD_ACTIVE_MASK),
> > +        Param));
> > +
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DGCMD_PARAM_REG,
> > +    Param
> > +    );
> > +
> > +  //
> > +  // Write the command to flush all FIFOs
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DGCMD_REG,
> > +    (UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) |
> DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH |
> DWC_XDCI_DGCMD_CMD_ACTIVE_MASK)
> > +    );
> > +
> > +
> > +  //
> > +  // Wait until command completes
> > +  //
> > +  do {
> > +    if (!(UsbRegRead(BaseAddr, DWC_XDCI_DGCMD_REG) &
> DWC_XDCI_DGCMD_CMD_ACTIVE_MASK))
> > +      break;
> > +    else
> > +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> > +  } while (--MaxDelayIter);
> > +
> > +  if (!MaxDelayIter) {
> > +    DEBUG ((DEBUG_INFO, "Failed to issue Command\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  return EFI_SUCCESS;
> > +}
> > +
> > +/**
> > +  Interface:
> > +  This function is used to cancel a transfer on non-EP0 endpoint
> > +  @CoreHandle: xDCI controller handle
> > +  @EpInfo: Address of structure describing properties of EP
> > +
> > +**/
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpCancelTransfer (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  )
> > +{
> > +  EFI_STATUS  Status =3D EFI_DEVICE_ERROR;
> > +  UINT32      EpNum;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpCancelTransfer: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Get physical EP num
> > +  //
> > +  EpNum =3D DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> > +  Status =3D DwcXdciEndXfer(CoreHandle, EpNum);
> > +  DwcXdciCoreFlushEpFifo(CoreHandle, EpNum);
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +EFI_STATUS
> > +usbProcessDeviceResetDet (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle
> > +  )
> > +{
> > +   return DwcXdciProcessDeviceResetDet (CoreHandle);
> > +}
> > +
> > +EFI_STATUS
> > +usbProcessDeviceResetDone (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle
> > +  )
> > +{
> > +  return DwcXdciProcessDeviceResetDone (CoreHandle);
> > +}
> > +
> > +UINT32
> > +UsbGetPhysicalEpNum (
> > +  IN UINT32        EndpointNum,
> > +  IN USB_EP_DIR    EndpointDir
> > +  )
> > +{
> > +  return DwcXdciGetPhysicalEpNum(
> > +                            EndpointNum,
> > +                            EndpointDir
> > +                            );
> > +}
> > +
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +UsbXdciCoreReinit (
> > +  IN VOID                     *CoreHandle
> > +  )
> > +{
> > +  EFI_STATUS                      status =3D EFI_DEVICE_ERROR;
> > +  UINT32                          BaseAddr;
> > +  XDCI_CORE_HANDLE                *LocalCoreHandle;
> > +  DWC_XDCI_ENDPOINT_CMD_PARAMS    EpCmdParams;
> > +  UINT32                          MaxDelayIter =3D
> DWC_XDCI_MAX_DELAY_ITERATIONS;
> > +  UINT8                           i;
> > +
> > +  LocalCoreHandle =3D CoreHandle;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  if (LocalCoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to allocate handle fo=
r
> xDCI\n"));
> > +    return EFI_OUT_OF_RESOURCES;
> > +  }
> > +
> > +  BaseAddr =3D LocalCoreHandle->BaseAddress;
> > +
> > +  DEBUG ((DEBUG_INFO, "Resetting the USB core\n"));
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCTL_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) |
> DWC_XDCI_DCTL_CSFTRST_MASK
> > +    );
> > +
> > +  //
> > +  // Wait until core soft reset completes
> > +  //
> > +  do {
> > +    if (!(UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) &
> DWC_XDCI_DCTL_CSFTRST_MASK)) {
> > +      break;
> > +    } else {
> > +      gBS->Stall (DWC_XDCI_MAX_DELAY_ITERATIONS);
> > +    }
> > +  } while (--MaxDelayIter);
> > +
> > +  if (!MaxDelayIter) {
> > +    DEBUG ((DEBUG_INFO, "Failed to reset device controller\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "USB core has been reset\n"));
> > +
> > +  LocalCoreHandle->DevState =3D UsbDevStateDefault;
> > +
> > +  //
> > +  // Clear KeepConnect bit so we can allow disconnect and
> > +  // re-connect. Stay in RX_DETECT state
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCTL_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_DCTL_REG) &
> > +    (~DWC_XDCI_DCTL_KEEP_CONNECT_MASK) &
> > +    ((~DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK) |
> > +    (DWC_XDCI_DCTL_STATE_CHANGE_REQ_RX_DETECT <<
> DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS))
> > +    );
> > +
> > +  DEBUG ((DEBUG_INFO, "Device controller Synopsys ID: %x\n",
> UsbRegRead (BaseAddr, DWC_XDCI_GSNPSID_REG)));
> > +  DEBUG ((DEBUG_INFO, "Default value of xDCI GSBUSCFG0 and
> GSBUSCFG1: %x, %x\n",
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG0_REG),
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GSBUSCFG1_REG)));
> > +
> > +  DEBUG ((DEBUG_INFO, "Default value of xDCI GTXTHRCFG and
> GRXTHRCFG: %x, %x\n",
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GTXTHRCFG_REG),
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GRXTHRCFG_REG)));
> > +
> > +  //
> > +  // Clear ULPI auto-resume bit
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_GUSB2PHYCFG_REG (0),
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)) &
> ~DWC_XDCI_GUSB2PHYCFG_ULPI_AUTO_RESUME_MASK)
> > +    );
> > +
> > +  DEBUG ((DEBUG_INFO, "Default value of xDCI GUSB2PHYCFG and
> GUSB3PIPECTL: %x, %x\n",
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG (0)),
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG (0))));
> > +
> > +  //
> > +  // Only one RxFIFO
> > +  //
> > +  DEBUG ((DEBUG_INFO, "Default value of DWC_XDCI_GRXFIFOSIZ: %x\n",
> > +          UsbRegRead (BaseAddr, DWC_XDCI_GRXFIFOSIZ_REG (0))));
> > +
> > +  for (i =3D 0; i < DWC_XDCI_MAX_ENDPOINTS; i++) {
> > +    DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_GTXFIFOSIZ
> %d: %x\n",
> > +            i, UsbRegRead (BaseAddr, DWC_XDCI_GTXFIFOSIZ_REG (i))));
> > +  }
> > +
> > +  //
> > +  // TODO: Need to check if TxFIFO should start where RxFIFO ends
> > +  // or default is correct i.e. TxFIFO starts at 0 just like RxFIFO
> > +  //
> > +
> > +  //
> > +  // Allocate and Initialize Event Buffers
> > +  //
> > +  LocalCoreHandle->MaxDevIntLines =3D ((UsbRegRead (BaseAddr,
> DWC_XDCI_GHWPARAMS1_REG) &
> > +                                           DWC_XDCI_GHWPARAMS1_NUM_INT=
_MASK) >>
> > +                                           DWC_XDCI_GHWPARAMS1_NUM_INT=
_BIT_POS);
> > +
> > +  DEBUG ((DEBUG_INFO, "Max dev int lines: %d\n", LocalCoreHandle-
> >MaxDevIntLines));
> > +  //
> > +  // One event Buffer per interrupt line.
> > +  //  Need to align it to size of event Buffer
> > +  //  Buffer needs to be big enough. Otherwise the core
> > +  //  won't operate
> > +  //
> > +  LocalCoreHandle->AlignedEventBuffers =3D (DWC_XDCI_EVENT_BUFFER *)
> > +                                             ((UINT32)(UINTN)(LocalCor=
eHandle-
> >EventBuffers) +
> > +                                             ((sizeof (DWC_XDCI_EVENT_=
BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER) -
> > +                                             (((UINT32)(UINTN)(LocalCo=
reHandle-
> >EventBuffers)) %
> > +                                             (sizeof (DWC_XDCI_EVENT_B=
UFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER))));
> > +
> > +  for (i =3D 0; i < LocalCoreHandle->MaxDevIntLines; i++) {
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_GEVNTADR_REG (i),
> > +      (UINT32)(UINTN)(LocalCoreHandle->AlignedEventBuffers + i *
> sizeof(DWC_XDCI_EVENT_BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER)
> > +      );
> > +
> > +    //
> > +    // Clear High 32bit address register, GEVNTADR register is 64-bit =
register
> > +    // default is 0xffffffffffffffff
> > +    //
> > +    UsbRegWrite (BaseAddr, DWC_XDCI_GEVNTADR_REG (i) + 4,
> 0x00000000);
> > +
> > +    LocalCoreHandle->CurrentEventBuffer =3D LocalCoreHandle-
> >AlignedEventBuffers;
> > +    //
> > +    // Write size and clear the mask
> > +    //
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_EVNTSIZ_REG (i),
> > +      sizeof (DWC_XDCI_EVENT_BUFFER) *
> DWC_XDCI_MAX_EVENTS_PER_BUFFER
> > +      );
> > +
> > +    //
> > +    // Write 0 to the event count register as the last step
> > +    // for event configuration
> > +    //
> > +    UsbRegWrite (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (i), 0);
> > +
> > +    DEBUG ((DEBUG_INFO, "Value of xDCI Event Buffer %d: %x, Size: %x,
> Count: %x\n",
> > +                        i,
> > +                        UsbRegRead (BaseAddr, DWC_XDCI_GEVNTADR_REG (i=
)),
> > +                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTSIZ_REG (i)=
),
> > +                        UsbRegRead (BaseAddr, DWC_XDCI_EVNTCOUNT_REG (=
i))));
> > +  }
> > +
> > +    //
> > +    // Program Global Control Register to disable scaledown,
> > +    // disable clock gating
> > +    //
> > +    UsbRegWrite (
> > +      BaseAddr,
> > +      DWC_XDCI_GCTL_REG,
> > +      ((UsbRegRead(BaseAddr, DWC_XDCI_GCTL_REG) &
> > +                    ~(DWC_XDCI_GCTL_SCALE_DOWN_MODE_MASK +
> DWC_XDCI_GCTL_RAMCLKSEL_MASK +
> DWC_XDCI_GCTL_DISABLE_SCRAMB_MASK)) |
> > +                    DWC_XDCI_GCTL_DISABLE_CLK_GATING_MASK |
> > +                    (DWC_XDCI_GCTL_PRT_CAP_DEVICE <<
> DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)));
> > +
> > +    DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_GCTL_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG)));
> > +
> > +
> > +  //
> > +  // TODO: Program desired Speed and set LPM capable
> > +  // We will do this when SuperSpeed works. For now,
> > +  // force into High-Speed mode to aVOID anyone trying this
> > +  // on Super Speed port
> > +  //
> > +#ifdef SUPPORT_SUPER_SPEED
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCFG_REG,
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) &
> ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) | LocalCoreHandle-
> >DesiredSpeed
> > +    );
> > +#else
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DCFG_REG,
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG) &
> ~DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK) |
> DWC_XDCI_DCFG_DESIRED_HS_SPEED
> > +    );
> > +#endif
> > +
> > +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DCFG_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DCFG_REG)));
> > +  DEBUG ((DEBUG_INFO, "Setup value of xDCI DWC_XDCI_DSTS_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DSTS_REG)));
> > +
> > +  //
> > +  // Enable Device Interrupt Events
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_DEVTEN_REG,
> > +    DWC_XDCI_DEVTEN_DEVICE_INTS
> > +    );
> > +
> > +  //
> > +  // Program the desired role
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_GCTL_REG,
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_GCTL_REG) &
> ~DWC_XDCI_GCTL_PRT_CAP_DIR_MASK) | (LocalCoreHandle->Role <<
> DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS)
> > +    );
> > +
> > +  //
> > +  // Clear USB2 suspend for start new config command
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_GUSB2PHYCFG_REG (0),
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB2PHYCFG_REG(0)) &
> ~DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK)
> > +    );
> > +  //
> > +  // Clear USB3 suspend for start new config command
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_GUSB3PIPECTL_REG (0),
> > +    (UsbRegRead (BaseAddr, DWC_XDCI_GUSB3PIPECTL_REG(0)) &
> ~DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK)
> > +    );
> > +  //
> > +  // Issue DEPSTARTCFG command for EP0
> > +  //
> > +  status =3D DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[0].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> > +             EPCMD_START_NEW_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> START_NEW_CONFIG EP command on xDCI\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status =3D DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             0,
> > +             EPCMD_START_NEW_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> START_NEW_CONFIG EP command on xDCI\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue DEPCFG command for EP0
> > +  //
> > +  status =3D DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[0].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> SET_EP_CONFIG command on xDCI for EP0\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status =3D DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             0,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams);
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> SET_EP_CONFIG command on xDCI for EP0\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue DEPCFG command for EP1
> > +  //
> > +  status =3D DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[1].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> SET_EP_CONFIG command on xDCI for EP1\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status =3D DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             1,
> > +             EPCMD_SET_EP_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> SET_EP_CONFIG command on xDCI for EP1\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue DEPXFERCFG command for EP0
> > +  //
> > +  status =3D DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[0].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status =3D DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             0,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP0\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue DEPXFERCFG command for EP1
> > +  //
> > +  status =3D DwcXdciCoreInitEpCmdParams (
> > +             LocalCoreHandle,
> > +             &LocalCoreHandle->EpHandles[1].EpInfo,
> > +             DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to init params for
> EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Issue the command
> > +  //
> > +  status =3D DwcXdciCoreIssueEpCmd (
> > +             LocalCoreHandle,
> > +             1,
> > +             EPCMD_SET_EP_XFER_RES_CONFIG,
> > +             &EpCmdParams
> > +             );
> > +
> > +  if (status) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciCoreInit: Failed to issue
> EPCMD_SET_EP_XFER_RES_CONFIG command on xDCI for EP1\n"));
> > +    return status;
> > +  }
> > +
> > +  //
> > +  // Prepare a Buffer for SETUP packet
> > +  //
> > +  LocalCoreHandle->Trbs =3D (DWC_XDCI_TRB *)((UINTN)
> > +                            LocalCoreHandle->UnalignedTrbs +
> > +                            (UINTN)(DWC_XDCI_TRB_BYTE_ALIGNMENT -
> > +                            ((UINT32)(UINTN)LocalCoreHandle->Unaligned=
Trbs %
> > +                            DWC_XDCI_TRB_BYTE_ALIGNMENT)));
> > +
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@
> unalignedTrbs address is 0x%x\n", LocalCoreHandle->UnalignedTrbs));
> > +  DEBUG ((DEBUG_INFO, "(DwcXdciCoreInit)@@@@@@@@@ TRB
> address is 0x%x\n", LocalCoreHandle->Trbs));
> > +
> > +  //
> > +  // Allocate Setup Buffer that is 8-byte aligned
> > +  //
> > +  LocalCoreHandle->AlignedSetupBuffer =3D LocalCoreHandle-
> >DefaultSetupBuffer +
> > +                                            (DWC_XDCI_SETUP_BUFF_SIZE =
-
> > +                                            ((UINT32)(UINTN)(LocalCore=
Handle-
> >DefaultSetupBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
> > +
> > +  //
> > +  // Aligned Buffer for status phase
> > +  //
> > +  LocalCoreHandle->AlignedMiscBuffer =3D LocalCoreHandle->MiscBuffer +
> > +                                           (DWC_XDCI_SETUP_BUFF_SIZE -
> > +                                           ((UINT32)(UINTN)(LocalCoreH=
andle-
> >AlignedMiscBuffer) % DWC_XDCI_SETUP_BUFF_SIZE));
> > +
> > +  //
> > +  // We will queue SETUP request when we see bus reset
> > +  //
> > +
> > +  //
> > +  // Enable Physical Endpoints 0
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EP_DALEPENA_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 0)
> > +    );
> > +
> > +  //
> > +  // Enable Physical Endpoints 1
> > +  //
> > +  UsbRegWrite (
> > +    BaseAddr,
> > +    DWC_XDCI_EP_DALEPENA_REG,
> > +    UsbRegRead (BaseAddr, DWC_XDCI_EP_DALEPENA_REG) | (1 << 1)
> > +    );
> > +
> > +  DEBUG ((DEBUG_INFO, "Default value of xDCI DWC_XDCI_DEVTEN_REG:
> 0x%x\n", UsbRegRead (BaseAddr, DWC_XDCI_DEVTEN_REG)));
> > +  return status;
> > +
> > +
> > +}
> > +
> > +
> > +EFI_STATUS
> > +UsbXdciCoreFlushEpFifo (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  )
> > +{
> > +  EFI_STATUS  Status =3D EFI_DEVICE_ERROR;
> > +  UINT32      EpNum;
> > +
> > +  if (CoreHandle =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "DwcXdciEpCancelTransfer: INVALID
> handle\n"));
> > +    return EFI_DEVICE_ERROR;
> > +  }
> > +
> > +  //
> > +  // Get physical EP num
> > +  //
> > +  EpNum =3D DwcXdciGetPhysicalEpNum (EpInfo->EpNum, EpInfo->EpDir);
> > +  DwcXdciCoreFlushEpFifo(CoreHandle, EpNum);
> > +
> > +  return Status;
> > +}
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
> > new file mode 100644
> > index 0000000000..9c1b2d1d85
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDWC.h
> > @@ -0,0 +1,741 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#ifndef _XDCI_DWC_H_
> > +#define _XDCI_DWC_H_
> > +
> > +#include "XdciCommon.h"
> > +#include "XdciDevice.h"
> > +
> > +#define DWC_XDCI_MAX_ENDPOINTS                             (16)
> > +#define DWC_XDCI_SS_CTRL_EP_MPS                            (512)
> > +#define DWC_XDCI_HS_CTRL_EP_MPS                            (64)
> > +#define DWC_XDCI_FS_CTRL_EP_MPS                            (64)
> > +#define DWC_XDCI_LS_CTRL_EP_MPS                            (8)
> > +#define DWC_XDCI_SS_CTRL_BUF_SIZE                          (512)
> > +#define DWC_XDCI_SETUP_BUFF_SIZE                           (8)
> > +#define DWC_XDCI_MAX_EVENTS_PER_BUFFER                     (16)
> > +#define DWC_XDCI_TRB_BYTE_ALIGNMENT                        (16)
> > +#define DWC_XDCI_DEFAULT_TX_FIFO_SIZE                      (1024)
> > +#define DWC_XDCI_TRB_NUM                                   (32)
> > +#define DWC_XDCI_MASK                                      (DWC_XDCI_T=
RB_NUM - 1)
> > +
> > +#define DWC_XDCI_MAX_DELAY_ITERATIONS                      (1000)
> > +
> > +#define DWC_XDCI_GSBUSCFG0_REG                             (0xC100)
> > +#define DWC_XDCI_GSBUSCFG1_REG                             (0xC104)
> > +#define DWC_XDCI_GTXTHRCFG_REG                             (0xC108)
> > +#define DWC_XDCI_GRXTHRCFG_REG                             (0xC10C)
> > +
> > +//
> > +// Global Control Register and bit definitions
> > +//
> > +#define DWC_XDCI_GCTL_REG                                  (0xC110)
> > +#define DWC_XDCI_GCTL_PWRDNSCALE_MASK                      (0xFFF80000=
)
> > +#define DWC_XDCI_GCTL_PWRDNSCALE_VAL                       (0x13880000=
)
> > +#define DWC_XDCI_GCTL_U2RSTECN_MASK                        (0x00010000=
)
> > +#define DWC_XDCI_GCTL_PRT_CAP_DIR_MASK                     (0x00003000=
)
> > +#define DWC_XDCI_GCTL_PRT_CAP_DIR_BIT_POS                  (12)
> > +#define DWC_XDCI_GCTL_PRT_CAP_HOST                         (1)
> > +#define DWC_XDCI_GCTL_PRT_CAP_DEVICE                       (2)
> > +#define DWC_XDCI_GCTL_PRT_CAP_OTG                          (3)
> > +#define DWC_XDCI_GCTL_RAMCLKSEL_MASK                       (0x000000C0=
)
> > +#define DWC_XDCI_GCTL_SCALE_DOWN_MODE_MASK
> (0x00000030)
> > +#define DWC_XDCI_GCTL_DISABLE_CLK_GATING_MASK
> (0x00000001)
> > +#define DWC_XDCI_GCTL_DISABLE_SCRAMB_MASK
> (0x00000008)
> > +
> > +#define DWC_XDCI_GSTS_REG                                  (0xC118)
> > +#define DWC_XDCI_GSNPSID_REG                               (0xC120)
> > +#define DWC_XDCI_GGPIO_REG                                 (0xC124)
> > +#define DWC_XDCI_GUID_REG                                  (0xC128)
> > +#define DWC_XDCI_GUCTL_REG                                 (0xC12C)
> > +#define DWC_XDCI_GBUSERRADDR                               (0xC130)
> > +
> > +//
> > +// Global Hardware Parameters Registers
> > +//
> > +#define DWC_XDCI_GHWPARAMS0_REG                            (0xC140)
> > +#define DWC_XDCI_GHWPARAMS1_REG                            (0xC144)
> > +#define DWC_XDCI_GHWPARAMS1_NUM_INT_MASK
> (0x1F8000)
> > +#define DWC_XDCI_GHWPARAMS1_NUM_INT_BIT_POS                (15)
> > +
> > +#define DWC_XDCI_GHWPARAMS2_REG                            (0xC148)
> > +#define DWC_XDCI_GHWPARAMS3_REG                            (0xC14C)
> > +#define DWC_XDCI_GHWPARAMS4_REG                            (0xC150)
> > +#define DWC_XDCI_GHWPARAMS4_CACHE_TRBS_PER_XFER_MASK
> (0x0000003F)
> > +#define DWC_XDCI_GHWPARAMS5_REG                            (0xC154)
> > +#define DWC_XDCI_GHWPARAMS6_REG                            (0xC158)
> > +#define DWC_XDCI_GHWPARAMS7_REG                            (0xC15C)
> > +#define DWC_XDCI_GHWPARAMS8_REG                            (0xC600)
> > +
> > +#define DWC_XDCI_GDBGFIFOSPACE_REG                         (0xC160)
> > +
> > +#define DWC_XDCI_GUSB2PHYCFG_REG(n)                        (0xC200 + (=
n <<
> 2))
> > +#define DWC_XDCI_GUSB2PHYCFG_ULPI_AUTO_RESUME_MASK
> (0x00008000)
> > +#define DWC_XDCI_GUSB2PHYCFG_SUSPEND_PHY_MASK
> (0x00000040)
> > +
> > +#define DWC_XDCI_GUSB3PIPECTL_REG(n)                       (0xC2C0 + (=
n << 2))
> > +#define DWC_XDCI_GUSB3PIPECTL_SUSPEND_PHY_MASK
> (0x00020000)
> > +
> > +#define DWC_XDCI_GTXFIFOSIZ_REG(n)                         (0xC300 + (=
n << 2))
> > +#define DWC_XDCI_GTXFIFOSIZ_START_ADDRESS_MASK
> (0xFFFF0000)
> > +#define DWC_XDCI_GTXFIFOSIZ_START_ADDRESS_BIT_POS          (16)
> > +#define DWC_XDCI_GRXFIFOSIZ_REG(n)                         (0xC380 + (=
n << 2))
> > +
> > +//
> > +// Global Event Buffer Registers
> > +//
> > +#define DWC_XDCI_GEVNTADR_REG(n)                           (0xC400 + (=
n << 4))
> > +#define DWC_XDCI_EVNTSIZ_REG(n)                            (0xC408 + (=
n << 4))
> > +#define DWC_XDCI_EVNTSIZ_MASK                              (0x0000FFFF=
)
> > +#define DWC_XDCI_EVNT_INTR_MASK                            (0x80000000=
)
> > +#define DWC_XDCI_EVNTCOUNT_REG(n)                          (0xC40C + (=
n << 4))
> > +#define DWC_XDCI_EVNTCOUNT_MASK                            (0x0000FFFF=
)
> > +
> > +//
> > +// Device Configuration Register and Bit Definitions
> > +//
> > +#define DWC_XDCI_DCFG_REG                                  (0xC700)
> > +#define DWC_XDCI_DCFG_LPM_CAPABLE_MASK                     (0x00400000=
)
> > +#define DWC_XDCI_DCFG_DEV_ADDRESS_MASK                     (0x000003F8=
)
> > +#define DWC_XDCI_DCFG_DEV_ADDRESS_BIT_POS                  (3)
> > +#define DWC_XDCI_DCFG_DESIRED_DEV_SPEED_MASK
> (0x00000007)
> > +#define DWC_XDCI_DCFG_DESIRED_SS_SPEED                     (0x00000004=
)
> > +#define DWC_XDCI_DCFG_DESIRED_FS_SPEED                     (0x00000001=
)
> > +#define DWC_XDCI_DCFG_DESIRED_HS_SPEED                     (0x00000000=
)
> > +
> > +//
> > +// Device Control Register
> > +//
> > +#define DWC_XDCI_DCTL_REG                                  (0xC704)
> > +#define DWC_XDCI_DCTL_RUN_STOP_MASK                        (0x80000000=
)
> > +#define DWC_XDCI_DCTL_RUN_STOP_BIT_POS                     (31)
> > +#define DWC_XDCI_DCTL_CSFTRST_MASK                         (0x40000000=
)
> > +#define DWC_XDCI_DCTL_CSFTRST_BIT_POS                      (30)
> > +#define DWC_XDCI_DCTL_KEEP_CONNECT_MASK                    (0x00080000=
)
> > +#define DWC_XDCI_DCTL_KEEP_CONNECT_BIT_POS                 (19)
> > +#define DWC_XDCI_DCTL_CSFTRST_BIT_POS                      (30)
> > +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_MASK
> (0x000001E0)
> > +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_BIT_POS             (5)
> > +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_NO_ACTION           (1)
> > +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_SS_DISABLED         (4)
> > +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_RX_DETECT           (5)
> > +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_SS_INACTIVE         (6)
> > +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_RECOVERY            (8)
> > +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_COMPLIANCE          (10)
> > +#define DWC_XDCI_DCTL_STATE_CHANGE_REQ_REMOTE_WAKEUP       (8)
> > +
> > +//
> > +// Device Event Enable Register
> > +//
> > +#define DWC_XDCI_DEVTEN_REG                                (0xC708)
> > +#define DWC_XDCI_DEVTEN_DISCONN_DET_EN_MASK
> (0x00000001)
> > +#define DWC_XDCI_DEVTEN_RESET_DET_EN_MASK
> (0x00000002)
> > +#define DWC_XDCI_DEVTEN_CONN_DONE_DET_EN_MASK
> (0x00000004)
> > +#define DWC_XDCI_DEVTEN_LINK_STATE_CHANGE_DET_EN_MASK
> (0x00000008)
> > +#define DWC_XDCI_DEVTEN_RESUME_WAKEUP_DET_EN_MASK
> (0x00000010)
> > +#define DWC_XDCI_DEVTEN_HIBERNATION_REQ_EN_MASK
> (0x00000020)
> > +#define DWC_XDCI_DEVTEN_U3L2L1_DET_EN_MASK
> (0x00000040)
> > +#define DWC_XDCI_DEVTEN_SOF_DET_EN_MASK                    (0x00000080=
)
> > +#define DWC_XDCI_DEVTEN_ERRATIC_ERR_DET_EN_MASK
> (0x00000200)
> > +#define DWC_XDCI_DEVTEN_VNDR_DEV_TST_RX_DET_EN_MASK
> (0x00001000)
> > +
> > +#define DWC_XDCI_DEVTEN_DEVICE_INTS
> (DWC_XDCI_DEVTEN_DISCONN_DET_EN_MASK | \
> > +        DWC_XDCI_DEVTEN_RESET_DET_EN_MASK |
> DWC_XDCI_DEVTEN_CONN_DONE_DET_EN_MASK | \
> > +        DWC_XDCI_DEVTEN_LINK_STATE_CHANGE_DET_EN_MASK |
> DWC_XDCI_DEVTEN_RESUME_WAKEUP_DET_EN_MASK | \
> > +        DWC_XDCI_DEVTEN_HIBERNATION_REQ_EN_MASK |
> DWC_XDCI_DEVTEN_U3L2L1_DET_EN_MASK | \
> > +        DWC_XDCI_DEVTEN_ERRATIC_ERR_DET_EN_MASK)
> > +
> > +#define DWC_XDCI_EVENT_BUFF_BULK_STREAM_ID_MASK
> (0xFFFF0000)
> > +#define DWC_XDCI_EVENT_BUFF_ISOCH_UFRAME_NUM_MASK
> (0xFFFF0000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_CMD_TYPE_MASK
> (0x0F000000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_XFER_RES_INDEX_MASK
> (0x007F0000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_XFER_ACTIVE_MASK
> (0x00008000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_CTRL_DATA_REQ_MASK
> (0x00001000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_CTRL_STATUS_REQ_MASK
> (0x00002000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_LST_MASK                    (0x00008000=
)
> > +#define DWC_XDCI_EVENT_BUFF_EP_MISSED_ISOCH_MASK
> (0x00008000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_IOC_MASK                    (0x00004000=
)
> > +#define DWC_XDCI_EVENT_BUFF_EP_LAST_PKT_MASK
> (0x00002000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_STREAM_NOT_FND_MASK
> (0x00002000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_STREAM_FND_MASK
> (0x00001000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_ERR_NO_RES_MASK
> (0x00001000)
> > +#define DWC_XDCI_EVENT_BUFF_EP_INVALID_RES_MASK
> (0x00001000)
> > +
> > +#define DWC_XDCI_EVENT_BUFF_EP_EVENT_MASK
> (0x000003C0)
> > +#define DWC_XDCI_EVENT_BUFF_EP_EVENT_BIT_POS               (6)
> > +#define DWC_XDCI_EVENT_BUFF_EP_XFER_CMPLT                  (1)
> > +#define DWC_XDCI_EVENT_BUFF_EP_XFER_IN_PROGRESS            (2)
> > +#define DWC_XDCI_EVENT_BUFF_EP_XFER_NOT_READY              (3)
> > +#define DWC_XDCI_EVENT_BUFF_EP_STREAM_EVENT                (6)
> > +#define DWC_XDCI_EVENT_BUFF_EP_CMD_CMPLT                   (7)
> > +
> > +#define DWC_XDCI_EVENT_BUFF_EP_NUM_MASK
> (0x0000003E)
> > +#define DWC_XDCI_EVENT_BUFF_EP_NUM_BIT_POS                 (1)
> > +
> > +#define DWC_XDCI_EVENT_BUFF_EP_EVENT_STATUS_MASK
> (0x0000F000)
> > +
> > +
> > +#define DWC_XDCI_EVENT_BUFF_DEV_HIRD_MASK
> (0x01E00000)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_HIRD_BIT_POS               (21)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_SS_EVENT_MASK
> (0x00100000)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_MASK
> (0x000F0000)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_LINK_STATE_BIT_POS         (16)
> > +
> > +#define DWC_XDCI_EVENT_BUFF_DEV_EVT_MASK                   (0x00000F00=
)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_EVT_BIT_POS                (8)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_TST_LMP_RX_EVENT           (12)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_BUFF_OVFL_EVENT            (11)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_CMD_CMPLT_EVENT            (10)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_ERRATIC_ERR_EVENT          (9)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_SOF_EVENT                  (7)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_HBRNTN_REQ_EVENT           (5)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_WKUP_EVENT                 (4)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_STATE_CHANGE_EVENT         (3)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_CONN_DONE_EVENT            (2)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_USB_RESET_EVENT            (1)
> > +#define DWC_XDCI_EVENT_BUFF_DEV_DISCONN_EVENT              (0)
> > +
> > +#define DWC_XDCI_EVENT_DEV_MASK                            (0x00000001=
)
> > +
> > +//
> > +// Device Status Register and Bit Definitions
> > +//
> > +#define DWC_XDCI_DSTS_REG                                  (0xC70C)
> > +#define DWC_XDCI_DSTS_DEV_CTRL_HALTED_MASK
> (0x00400000)
> > +#define DWC_XDCI_DSTS_DEV_CTRL_HALTED_BIT_POS              (22)
> > +#define DWC_XDCI_DSTS_CORE_IDLE                            (1 << 23)
> > +#define DWC_XDCI_DSTS_CONN_SPEED_MASK                      (0x00000007=
)
> > +#define DWC_XDCI_DSTS_LINK_STATE_MASK                      (0x003C0000=
)
> > +#define DWC_XDCI_DSTS_LINK_STATE_DISCONNECT
> (0x00100000)
> > +
> > +//
> > +// Device Generic Command Parameter Register
> > +//
> > +#define DWC_XDCI_DGCMD_PARAM_REG                           (0xC710)
> > +#define DWC_XDCI_DGCMD_PARAM_TX_FIFO_NUM_MASK
> (0x0000001F)
> > +#define DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_MASK
> (0x00000020)
> > +#define DWC_XDCI_DGCMD_PARAM_TX_FIFO_DIR_BIT_POS           (5)
> > +
> > +//
> > +// Device Generic Command Register
> > +//
> > +#define DWC_XDCI_DGCMD_REG                                 (0xC714)
> > +#define DWC_XDCI_DGCMD_CMD_STATUS_MASK
> (0x00008000)
> > +#define DWC_XDCI_DGCMD_CMD_ACTIVE_MASK
> (0x00000400)
> > +#define DWC_XDCI_DGCMD_CMD_IOC_MASK                        (0x00000100=
)
> > +#define DWC_XDCI_DGCMD_CMD_TYPE_MASK                       (0x000000FF=
)
> > +#define DWC_XDCI_DGCMD_CMD_SET_PERIODIC_PARAMS             (0x2)
> > +#define DWC_XDCI_DGCMD_CMD_SET_SCRATCH_PAD_BUFF_ARR_LO
> (0x4)
> > +#define DWC_XDCI_DGCMD_CMD_SET_SCRATCH_PAD_BUFF_ARR_HI
> (0x5)
> > +#define DWC_XDCI_DGCMD_CMD_XMIT_DEVICE_NOTIFICATION
> (0x7)
> > +#define DWC_XDCI_DGCMD_CMD_SEL_FIFO_FLUSH                  (0x9)
> > +#define DWC_XDCI_DGCMD_CMD_ALL_FIFO_FLUSH                  (0xA)
> > +#define DWC_XDCI_DGCMD_CMD_SET_EP_NRDY                     (0xC)
> > +#define DWC_XDCI_DGCMD_CMD_RUN_SOC_BUS_LPBK                (0x10)
> > +
> > +//
> > +// Device Active USB EP Enable Register
> > +//
> > +#define DWC_XDCI_EP_DALEPENA_REG                           (0xC720)
> > +
> > +//
> > +// Device Physical EP CMD Param 2 Register. Value is 32-bit
> > +//
> > +#define DWC_XDCI_EPCMD_PARAM2_REG(n)                       (0xC800 + (=
n <<
> 4))
> > +
> > +//
> > +// Device Physical EP CMD Param 1 Register. Value is 32-bit
> > +//
> > +#define DWC_XDCI_EPCMD_PARAM1_REG(n)                       (0xC804 + (=
n <<
> 4))
> > +
> > +//
> > +// Device Physical EP CMD Param 0 Register. Value is 32-bit
> > +//
> > +#define DWC_XDCI_EPCMD_PARAM0_REG(n)                       (0xC808 + (=
n <<
> 4))
> > +
> > +//
> > +// Device Physical EP Command Registers and Bit Definitions
> > +//
> > +#define DWC_XDCI_EPCMD_REG(n)                              (0xC80C + (=
n << 4))
> > +#define DWC_XDCI_EPCMD_RES_IDX_MASK                        (0x007F0000=
)
> > +#define DWC_XDCI_EPCMD_RES_IDX_BIT_POS                     (16)
> > +#define DWC_XDCI_EPCMD_CMDTYPE_MASK                        (0x0000000F=
)
> > +#define DWC_XDCI_EPCMD_SET_EP_CONFIG                       (0x1)
> > +#define DWC_XDCI_EPCMD_SET_EP_XFER_RES_CONFIG              (0x2)
> > +#define DWC_XDCI_EPCMD_GET_EP_STATE                        (0x3)
> > +#define DWC_XDCI_EPCMD_SET_STALL                           (0x4)
> > +#define DWC_XDCI_EPCMD_CLEAR_STALL                         (0x5)
> > +#define DWC_XDCI_EPCMD_START_XFER                          (0x6)
> > +#define DWC_XDCI_EPCMD_UPDATE_XFER                         (0x7)
> > +#define DWC_XDCI_EPCMD_END_XFER                            (0x8)
> > +#define DWC_XDCI_EPCMD_START_NEW_CONFIG                    (0x9)
> > +
> > +#define DWC_XDCI_EPCMD_CMD_IOC_MASK                        (0x00000100=
)
> > +#define DWC_XDCI_EPCMD_CMD_ACTIVE_MASK                     (0x00000400=
)
> > +#define DWC_XDCI_EPCMD_HIGH_PRIO_MASK                      (0x00000800=
)
> > +#define DWC_XDCI_EPCMD_FORCE_RM_MASK                       (0x00000800=
)
> > +
> > +//
> > +// Command status and parameter values same as event status and
> parameters values
> > +//
> > +#define DWC_XDCI_EPCMD_CMD_STATUS_MASK
> (0x0000F000)
> > +
> > +//
> > +// Command Params bit masks
> > +//
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_FIFO_BASED_MASK
> (0x80000000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_BULK_BASED_MASK
> (0x40000000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_MASK
> (0x3C000000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_MASK
> (0x02000000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_STRM_CAP_MASK
> (0x01000000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_MASK
> (0x00FF0000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_BIT_POS          (16)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EBC_MASK
> (0x00008000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_MASK
> (0x00003F00)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_BIT_POS          (8)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_STRM_MASK
> (0x00002000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_NRDY_MASK
> (0x00000400)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_IN_PRG_MASK
> (0x00000200)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_CMPLT_MASK
> (0x00000100)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_INTR_NUM_MASK
> (0x0000001F)
> > +
> > +//
> > +// CMD 1 param 0
> > +//
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MASK
> (0xC0000000)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_BIT_POS            (30)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_INIT_STATE         (0)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_RESTORE_ST         (1)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_MDFY_STATE         (2)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_ACTN_NONE               (3)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_MASK
> (0x03C00000)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_BRST_SIZE_BIT_POS       (22)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_MASK
> (0x003E0000)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_FIFO_NUM_BIT_POS        (17)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_MPS_MASK
> (0x00003FF8)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_MPS_BIT_POS             (3)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_MASK
> (0x00000006)
> > +#define DWC_XDCI_PARAM0_SET_EP_CFG_EP_TYPE_BIT_POS         (1)
> > +#define DWC_XDCI_PARAM0_EP_TYPE_CTRL                       (0)
> > +#define DWC_XDCI_PARAM0_EP_TYPE_ISOCH                      (1)
> > +#define DWC_XDCI_PARAM0_EP_TYPE_BULK                       (2)
> > +#define DWC_XDCI_PARAM0_EP_TYPE_INTR                       (3)
> > +
> > +//
> > +// CMD 1 param 1
> > +//
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_BULK_BASED_MASK
> (0x40000000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_MASK
> (0x3C000000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_NUM_BIT_POS          (26)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_MASK
> (0x02000000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EP_DIR_BIT_POS          (25)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_STRM_CAP_MASK
> (0x01000000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_MASK
> (0x00FF0000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_BINTM1_BIT_POS          (16)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EBC_MASK
> (0x00008000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_MASK
> (0x00003F00)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_EN_BIT_POS          (8)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_STRM_MASK
> (0x00002000)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_NRDY_MASK
> (0x00000400)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_IN_PRG_MASK
> (0x00000200)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_EVT_XFER_CMPLT_MASK
> (0x00000100)
> > +#define DWC_XDCI_PARAM1_SET_EP_CFG_INTR_NUM_MASK
> (0x0000001F)
> > +
> > +//
> > +// CMD 2 param 0
> > +//
> > +#define DWC_XDCI_PARAM0_SET_EP_XFER_RES_NUM_MASK
> (0x0000FFFF)
> > +
> > +//
> > +// CMD 3 param 2
> > +//
> > +#define DWC_XDCI_PARAM2_GET_EP_STATE_MASK
> (0xFFFFFFFF)
> > +
> > +//
> > +// CMD 6 param 1
> > +//
> > +#define DWC_XDCI_PARAM1_STRT_XFER_TD_ADDR_LO_MASK
> (0xFFFFFFFF)
> > +
> > +//
> > +// CMD 6 param 0
> > +//
> > +#define DWC_XDCI_PARAM0_STRT_XFER_TD_ADDR_HI_MASK
> (0xFFFFFFFF)
> > +
> > +//
> > +// Transfer Request Block Fields' Bit Definitions
> > +//
> > +#define DWC_XDCI_TRB_BUFF_SIZE_MASK                        (0x00FFFFFF=
)
> > +#define DWC_XDCI_TRB_PCM1_MASK                             (0x03000000=
)
> > +#define DWC_XDCI_TRB_PCM1_BIT_POS                          (24)
> > +#define DWC_XDCI_TRB_STATUS_MASK                           (0xF0000000=
)
> > +#define DWC_XDCI_TRB_STATUS_BIT_POS                        (28)
> > +#define DWC_XDCI_TRB_STATUS_OK                             (0)
> > +#define DWC_XDCI_TRB_STATUS_MISSED_ISOCH                   (1)
> > +#define DWC_XDCI_TRB_STATUS_SETUP_PENDING                  (2)
> > +
> > +#define DWC_XDCI_TRB_CTRL_HWO_MASK                         (0x00000001=
)
> > +#define DWC_XDCI_TRB_CTRL_LST_TRB_MASK                     (0x00000002=
)
> > +#define DWC_XDCI_TRB_CTRL_LST_TRB_BIT_POS                  (1)
> > +#define DWC_XDCI_TRB_CTRL_CHAIN_BUFF_MASK
> (0x00000004)
> > +#define DWC_XDCI_TRB_CTRL_CHAIN_BUFF_BIT_POS               (2)
> > +#define DWC_XDCI_TRB_CTRL_CSP_MASK                         (0x00000008=
)
> > +#define DWC_XDCI_TRB_CTRL_CSP_BIT_POS                      (3)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_MASK                        (0x000003F0=
)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_BIT_POS                     (4)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_NORMAL                      (1)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_SETUP                       (2)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_STATUS2                     (3)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_STATUS3                     (4)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_DATA                        (5)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_ISOCH_FIRST                 (6)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_ISOCH                       (7)
> > +#define DWC_XDCI_TRB_CTRL_TYPE_LINK_TRB                    (8)
> > +#define DWC_XDCI_TRB_CTRL_IOSP_MISOCH_MASK
> (0x00000400)
> > +#define DWC_XDCI_TRB_CTRL_IOSP_MISOCH_BIT_POS              (10)
> > +#define DWC_XDCI_TRB_CTRL_IOC_MASK                         (0x00000800=
)
> > +#define DWC_XDCI_TRB_CTRL_IOC_BIT_POS                      (11)
> > +#define DWC_XDCI_TRB_CTRL_STRM_ID_SOF_NUM_MASK
> (0x3FFFC000)
> > +#define DWC_XDCI_TRB_CTRL_STRM_ID_SOF_BIT_POS              (14)
> > +
> > +#define DWC_XDCI_DEV_EVENT_DEFAULT_SIZE_IN_BYTES           (4)
> > +#define DWC_XDCI_DEV_EVENT_TST_LMP_SIZE_IN_BYTES           (12)
> > +
> > +typedef enum {
> > +  EPCMD_SET_EP_CONFIG =3D 1,
> > +  EPCMD_SET_EP_XFER_RES_CONFIG,
> > +  EPCMD_GET_EP_STATE,
> > +  EPCMD_SET_STALL,
> > +  EPCMD_CLEAR_STALL,
> > +  EPCMD_START_XFER,
> > +  EPCMD_UPDATE_XFER,
> > +  EPCMD_END_XFER,
> > +  EPCMD_START_NEW_CONFIG =3D 9
> > +} DWC_XDCI_ENDPOINT_CMD;
> > +
> > +typedef enum {
> > +  ON =3D 0,
> > +  SLEEP =3D 2,
> > +  SUSPEND,
> > +  DISCONNECTED,
> > +  EARLY_SUSPEND,
> > +  RESET =3D 14,
> > +  RESUME =3D 15
> > +} DWC_XDCI_HS_LINK_STATE;
> > +
> > +typedef enum {
> > +  TRBCTL_NORMAL =3D 1,
> > +  TRBCTL_SETUP,
> > +  TRBCTL_2_PHASE,
> > +  TRBCTL_3_PHASE,
> > +  TRBCTL_CTRL_DATA_PHASE,
> > +  TRBCTL_ISOCH_FIRST,
> > +  TRBCTL_ISOCH,
> > +  TRBCTL_LINK
> > +} DWC_XDCI_TRB_CONTROL;
> > +
> > +//
> > +// DWC XDCI Endpoint Commands Parameters struct
> > +//
> > +typedef struct {
> > +  UINT32 Param2;
> > +  UINT32 Param1;
> > +  UINT32 Param0;
> > +} DWC_XDCI_ENDPOINT_CMD_PARAMS;
> > +
> > +//
> > +// Event Buffer Struct
> > +//
> > +typedef struct {
> > +  UINT32 Event;
> > +  UINT32 DevTstLmp1;
> > +  UINT32 DevTstLmp2;
> > +  UINT32 Reserved;
> > +} DWC_XDCI_EVENT_BUFFER;
> > +
> > +//
> > +// Transfer Request Block
> > +//
> > +typedef struct {
> > +  UINT32 BuffPtrLow;
> > +  UINT32 BuffPtrHigh;
> > +  UINT32 LenXferParams;
> > +  UINT32 TrbCtrl;
> > +} DWC_XDCI_TRB;
> > +
> > +typedef struct  {
> > +  USB_EP_INFO       EpInfo;
> > +  DWC_XDCI_TRB      *Trb;
> > +  USB_XFER_REQUEST  XferHandle;
> > +  UINT32            CurrentXferRscIdx;
> > +  VOID              *CoreHandle;
> > +  USB_EP_STATE      State;
> > +  USB_EP_STATE      OrgState;
> > +  BOOLEAN           CheckFlag;
> > +} DWC_XDCI_ENDPOINT;
> > +
> > +typedef struct {
> > +  //
> > +  // CbEventParams must be copied over by upper layer if
> > +  // it defers event processing
> > +  //
> > +  USB_DEVICE_CALLBACK_PARAM CbEventParams;
> > +
> > +  //
> > +  // Callback function list
> > +  //
> > +  USB_DEVICE_CALLBACK_FUNC  DevDisconnectCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevBusResetCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevResetDoneCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevLinkStateCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevWakeupCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevHibernationCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevSofCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevErraticErrCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevCmdCmpltCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevBuffOvflwCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevTestLmpRxCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevSetupPktReceivedCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevXferNrdyCallback;
> > +  USB_DEVICE_CALLBACK_FUNC  DevXferDoneCallback;
> > +} USB_DEV_CALLBACK_LIST;
> > +
> > +typedef struct {
> > +  VOID                     *ParentHandle;                             =
          // Pointer to the
> parent this driver is associated
> > +  USB_CONTROLLER_ID        Id;                                        =
          // ID of the
> controllers supported in our DCD
> > +  USB_SPEED                DesiredSpeed;                              =
          // Desired SS,
> HS, FS or LS Speeds for the core
> > +  USB_ROLE                 Role;                                      =
          // Desired role i.e.
> host, Device or OTG
> > +  USB_SPEED                ActualSpeed;                               =
          // Actual Speed
> > +  USB_DEVICE_STATE         DevState;                                  =
          // Device state
> > +  UINT32                   BaseAddress;                               =
          // Register Base
> address
> > +  UINT32                   Flags;                                     =
          // Init flags
> > +  UINT32                   MaxDevIntLines;                            =
          // One event
> Buffer per interrupt line
> > +  DWC_XDCI_EVENT_BUFFER    EventBuffers
> [DWC_XDCI_MAX_EVENTS_PER_BUFFER * 2];   // Event Buffer pool
> > +  DWC_XDCI_EVENT_BUFFER    *AlignedEventBuffers;                      =
          //
> Aligned event Buffer pool
> > +  DWC_XDCI_EVENT_BUFFER    *CurrentEventBuffer;                       =
          //
> Current event Buffer address
> > +  DWC_XDCI_TRB             UnalignedTrbs [(DWC_XDCI_MAX_ENDPOINTS +
> 1) * DWC_XDCI_TRB_NUM];    // TRBs.
> > +  DWC_XDCI_TRB             *Trbs;                                     =
          // 16-bytes
> aligned TRBs.
> > +  DWC_XDCI_ENDPOINT        EpHandles [DWC_XDCI_MAX_ENDPOINTS];
> // EPs
> > +  UINT8                    DefaultSetupBuffer [DWC_XDCI_SETUP_BUFF_SIZ=
E * 2];
> // Unaligned setup Buffer
> > +  UINT8                    *AlignedSetupBuffer;                       =
          // Aligned setup
> Buffer. Aligned to 8-byte boundary
> > +  UINT8                    MiscBuffer [528];                          =
          // Unaligned misc
> Buffer
> > +  UINT8                    *AlignedMiscBuffer;                        =
          // Aligned misc
> Buffer
> > +  UINT32                   LinkState;                                 =
          // Link state
> > +  UINT32                   HirdVal;                                   =
          // HIRD value
> > +  USB_DEV_CALLBACK_LIST    EventCallbacks;
> > +  volatile BOOLEAN         InterrupProcessing;
> > +} XDCI_CORE_HANDLE;
> > +
> > +//
> > +// DWC XDCI API prototypes
> > +//
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreInit (
> > +  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
> > +  IN VOID                     *ParentHandle,
> > +  IN VOID                     **CoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreDeinit (
> > +  IN VOID      *CoreHandle,
> > +  IN UINT32    flags
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreRegisterCallback (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_DEVICE_EVENT_ID       Event,
> > +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreUnregisterCallback (
> > +  IN VOID                   *CoreHandle,
> > +  IN USB_DEVICE_EVENT_ID    Event
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreIsrRoutine (
> > +  IN VOID *CoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreIsrRoutineTimerBased (
> > +  IN VOID *CoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreConnect (
> > +  IN VOID    *CoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreDisconnect (
> > +  IN VOID *CoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreGetSpeed (
> > +  IN VOID         *CoreHandle,
> > +  IN USB_SPEED    *Speed
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreSetAddress (
> > +  IN VOID      *CoreHandle,
> > +  IN UINT32    Address
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciCoreSetConfig (
> > +  IN VOID      *CoreHandle,
> > +  IN UINT32    ConfigNum
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciSetLinkState (
> > +  IN VOID                        *CoreHandle,
> > +  IN USB_DEVICE_SS_LINK_STATE    State
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciInitEp (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpEnable (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpDisable (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpStall (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpClearStall (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpSetNrdy (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEp0ReceiveSetupPkt (
> > +  IN VOID     *CoreHandle,
> > +  IN UINT8    *Buffer
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEp0ReceiveStatusPkt (
> > +  IN VOID    *CoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEp0SendStatusPkt (
> > +  IN VOID    *CoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpTxData (
> > +  IN VOID                *CoreHandle,
> > +  IN USB_XFER_REQUEST    *XferReq
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpRxData(
> > +  IN VOID                *CoreHandle,
> > +  IN USB_XFER_REQUEST    *XferReq
> > +  );
> > +
> > +EFI_STATUS
> > +EFIAPI
> > +DwcXdciEpCancelTransfer (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +usbProcessDeviceResetDet (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +usbProcessDeviceResetDone (
> > +  IN XDCI_CORE_HANDLE    *CoreHandle
> > +  );
> > +
> > +UINT32
> > +UsbGetPhysicalEpNum (
> > +  IN UINT32        EndpointNum,
> > +  IN USB_EP_DIR    EndpointDir
> > +  );
> > +
> > +UINT32
> > +UsbRegRead (
> > +  IN UINT32    Base,
> > +  IN UINT32    Offset
> > +  );
> > +
> > +VOID
> > +UsbRegWrite (
> > +  IN UINT32    Base,
> > +  IN UINT32    Offset,
> > +  IN UINT32    val
> > +  );
> > +
> > +EFI_STATUS
> > +UsbXdciCoreFlushEpFifo (
> > +  IN VOID           *CoreHandle,
> > +  IN USB_EP_INFO    *EpInfo
> > +  );
> > +#endif
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
> > new file mode 100644
> > index 0000000000..7c94de0a60
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.c
> > @@ -0,0 +1,695 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#include <Library/UsbDeviceLib.h>
> > +#include "XdciCommon.h"
> > +#include "XdciDevice.h"
> > +#include "XdciInterface.h"
> > +#include "UsbDeviceMode.h"
> > +
> > +/**
> > +  This function is used to initialize the device controller
> > +  @configParams: Parameters from app to configure the core
> > +  @DevCoreHandle: Return parameter for upper layers to use
> > +  for all HW-independent APIs
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceInit (
> > +  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
> > +  IN OUT VOID                 **DevCoreHandle
> > +  )
> > +{
> > +  USB_DEV_CORE    *DevCorePtr;
> > +  EFI_STATUS      Status =3D EFI_INVALID_PARAMETER;
> > +
> > +  DEBUG ((DEBUG_INFO, "Call UsbDeviceInit start\n"));
> > +
> > +  //
> > +  // Allocate device handle
> > +  //
> > +  DevCorePtr =3D AllocateZeroPool (sizeof (USB_DEV_CORE));
> > +  DEBUG ((DEBUG_INFO, "device handle =3D 0x%x\n", DevCorePtr));
> > +
> > +  if (DevCorePtr =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceInit. ERROR: Failed to allocate
> memory\n"));
> > +    return EFI_OUT_OF_RESOURCES;
> > +  }
> > +
> > +  DEBUG ((DEBUG_INFO, "call UsbDeviceGetCoreDriver, ID=3D%x, \n",
> ConfigParams->ControllerId));
> > +
> > +  //
> > +  // Get the driver for this USB device core
> > +  //
> > +  DevCorePtr->CoreDriver =3D UsbDeviceGetCoreDriver(ConfigParams-
> >ControllerId);
> > +  if (DevCorePtr->CoreDriver !=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "call DevCoreInit\n"));
> > +    Status =3D DevCorePtr->CoreDriver->DevCoreInit(
> > +                                        ConfigParams,
> > +                                        (VOID*)DevCorePtr,
> > +                                        &DevCorePtr->ControllerHandle)=
;
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceInit. ERROR: Driver not found\n"));
> > +    return EFI_INVALID_PARAMETER;
> > +  }
> > +
> > +  *DevCoreHandle =3D (VOID *)DevCorePtr;
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to de-initialize the device controller
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @flags: Flags indicating what type of de-initialization is required
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceDeinit (
> > +  IN VOID      *DevCoreHandle,
> > +  IN UINT32    Flags
> > +  )
> > +{
> > +  USB_DEV_CORE    *Core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS      Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (Core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceDeinit: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    if (Core->CoreDriver !=3D NULL) {
> > +      Status =3D Core->CoreDriver->DevCoreDeinit(
> > +                                    Core->ControllerHandle,
> > +                                    Flags
> > +                                    );
> > +      FreePool(DevCoreHandle);
> > +    } else {
> > +      DEBUG ((DEBUG_INFO, "UsbDeviceDeinit: Driver not found\n"));
> > +      Status =3D EFI_INVALID_PARAMETER;
> > +    }
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to register callback function for
> > +  specified event
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @event: Event for which callback is to be registered
> > +  @callbackFn: Callback function to be called by the
> > +  controller driver for above event after critical processing
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceRegisterCallback (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_DEVICE_EVENT_ID       EventId,
> > +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
> > +  )
> > +{
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbDeviceRegisterCallback start\n"));
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceRegisterCallback: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    if (core->CoreDriver !=3D NULL) {
> > +      DEBUG ((DEBUG_INFO, "Call DevCoreRegisterCallback\n"));
> > +      Status =3D core->CoreDriver->DevCoreRegisterCallback (
> > +                                    core->ControllerHandle,
> > +                                    EventId,
> > +                                    CallbackFunc
> > +                                    );
> > +    }
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to register callback function for
> > +  specified event
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @eventId: Event for which callback is to be unregistered
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceUnregisterCallback (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_DEVICE_EVENT_ID       EventId
> > +  )
> > +{
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceUnregisterCallback: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    if (core->CoreDriver !=3D NULL) {
> > +      Status =3D core->CoreDriver->DevCoreUnregisterCallback(
> > +                                    core->ControllerHandle,
> > +                                    EventId
> > +                                    );
> > +    }
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to service interrupt events on device
> > +  controller. Use this API in your OS/stack-specific ISR framework
> > +  In polled mode scenario, invoke this API in a loop to service the
> > +  events
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceIsrRoutine (
> > +  IN VOID                      *DevCoreHandle
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceIsrRoutine: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    if (core->CoreDriver !=3D NULL) {
> > +      Status =3D core->CoreDriver->DevCoreIsrRoutine (core-
> >ControllerHandle);
> > +    }
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  This function is used to service interrupt events on device
> > +  controller. Use this API in your OS/stack-specific ISR framework
> > +  In polled mode scenario, invoke this API in a loop to service the
> > +  events
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceIsrRoutineTimerBased (
> > +  IN VOID                      *DevCoreHandle
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceIsrRoutine: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    if (core->CoreDriver !=3D NULL) {
> > +      Status =3D core->CoreDriver->DevCoreIsrRoutineTimerBased (core-
> >ControllerHandle);
> > +    }
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +
> > +/**
> > +  This function is used to enable device controller to connect
> > +  to USB host
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +
> > +**/
> > +EFI_STATUS
> > +UsbXdciDeviceConnect (
> > +  IN VOID                      *DevCoreHandle
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbXdciDeviceConnect: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "UsbXdciDeviceConnect\n"));
> > +    Status =3D core->CoreDriver->DevCoreConnect (core->ControllerHandl=
e);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to disconnect device controller
> > +  from USB host
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceDisconnect (
> > +  IN VOID                      *DevCoreHandle
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D(USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceDisconnect: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceDisconnect\n"));
> > +    Status =3D core->CoreDriver->DevCoreDisconnect(core-
> >ControllerHandle);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to obtain USB bus Speed after bus reset comple=
te
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @Speed: negotiated Speed
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceGetSpeed (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_SPEED                 *Speed
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceGetSpeed: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status =3D core->CoreDriver->DevCoreGetSpeed(core->ControllerHandl=
e,
> Speed);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to set USB device address
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @address: USB device address to set
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceSetAddress (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN UINT32                    Address
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  DEBUG ((DEBUG_INFO, "UsbDeviceSetAddress: enter......\n"));
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceSetAddress: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status =3D core->CoreDriver->DevCoreSetAddress(core-
> >ControllerHandle, Address);
> > +  }
> > +  DEBUG ((DEBUG_INFO, "UsbDeviceSetAddress: exit......\n"));
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to do device controller-specific processing
> > +  of set configuration device framework request
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @ConfigNum: configuration number selected by USB host
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceSetConfiguration (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN UINT32                    ConfigNum
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceSetConfiguration: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status =3D core->CoreDriver->DevCoreSetConfig (core->ControllerHan=
dle,
> ConfigNum);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to set desired link state in device controller
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @state: Desired link state
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceSetLinkState (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_DEVICE_SS_LINK_STATE  State
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceSetLinkState: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status =3D core->CoreDriver->DevCoreSetLinkState (core-
> >ControllerHandle, State);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to initialize non-EP0 endpoints
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @EpInfo: Endpoint information for EP to be initialized
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceInitEp (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceInitEp: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status =3D core->CoreDriver->DevCoreInitEp (core->ControllerHandle=
,
> EpInfo);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to enable an endpoint
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @EpInfo: Endpoint information for EP to be enabled
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceEpEnable (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceEpEnable: ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status =3D core->CoreDriver->DevCoreEpEnable (core->ControllerHand=
le,
> EpInfo);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to disable an endpoint
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @EpInfo: Endpoint information for EP to be disabled
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceEpDisable (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceEpDisable ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status =3D core->CoreDriver->DevCoreEpDisable (core->ControllerHan=
dle,
> EpInfo);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to STALL an endpoint
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @EpInfo: Endpoint information for EP to be stalled
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceEpStall (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceEpStall ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status =3D core->CoreDriver->DevCoreEpStall (core->ControllerHandl=
e,
> EpInfo);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to clear STALL on an endpoint
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @EpInfo: Endpoint information for which STALL needs to be cleared
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceEpClearStall (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceEpClearStall ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status =3D core->CoreDriver->DevCoreEpClearStall (core-
> >ControllerHandle, EpInfo);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to set EP not ready state
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @EpInfo: Endpoint information for EP that needs to be
> > +  set in not ready state
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceEpSetNrdy (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceEpSetNrdy ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status =3D core->CoreDriver->DevCoreEpSetNrdy (core->ControllerHan=
dle,
> EpInfo);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to queue request to receive SETUP packet
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @Buffer: Buffer (bus-width aligned) where SETUP packet
> > +  needs to be received
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceEp0RxSetup (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN UINT8                     *Buffer
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceEp0RxSetup ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status =3D core->CoreDriver->DevCoreEp0RxSetupPkt (core-
> >ControllerHandle, Buffer);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to queue request to receive status phase
> > +  for control transfer on EP0
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceEp0RxStatus (
> > +  IN VOID                      *DevCoreHandle
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceEp0RxStatus ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status =3D core->CoreDriver->DevCoreEp0RxStatusPkt (core-
> >ControllerHandle);
> > +  }
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to queue request to send status phase for
> > +  control transfer on EP0
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceEp0TxStatus (
> > +  IN VOID                      *DevCoreHandle
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceEp0TxStatus ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status =3D core->CoreDriver->DevCoreEp0TxStatusPkt (core-
> >ControllerHandle);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to queue a single request to transmit data on
> > +  an endpoint. If more than one request need to be queued before
> > +  previous requests complete then a request queue needs to be
> > +  implemented in upper layers. This API should be not be invoked until
> > +  current request completes.
> > +  Callback for transfer completion is invoked when requested transfer
> length
> > +  is reached or if a short packet is received
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @XferReq: Address to transfer request describing this transfer
> > +
> > +**/
> > +EFI_STATUS
> > +UsbXdciDeviceEpTxData (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_XFER_REQUEST          *XferReq
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbXdciDeviceEpTxData ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status =3D core->CoreDriver->DevCoreEpTxData (core->ControllerHand=
le,
> XferReq);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to queue a single request to receive data on
> > +  an endpoint. If more than one request need to be queued before
> > +  previous requests complete then a request queue needs to be
> implemented
> > +  in upper layers. This API should be not be invoked until current req=
uest
> > +  completes.
> > +  Callback for transfer completion is invoked when requested transfer
> length
> > +  is reached or if a short packet is received
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @XferReq: Address to transfer request describing this transfer
> > +
> > +**/
> > +EFI_STATUS
> > +UsbXdciDeviceEpRxData (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_XFER_REQUEST          *XferReq
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbXdciDeviceEpRxData ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status =3D core->CoreDriver->DevCoreEpRxData (core->ControllerHand=
le,
> XferReq);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > +/**
> > +  This function is used to cancel a transfer request that was
> > +  previously queued on an endpoint
> > +  @DevCoreHandle: Handle to HW-independent APIs for device
> > +  controller
> > +  @EpInfo: Endpoint info where transfer needs to be cancelled
> > +
> > +**/
> > +EFI_STATUS
> > +UsbDeviceEpCancelTransfer (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  )
> > +{
> > +  USB_DEV_CORE  *core =3D (USB_DEV_CORE *)DevCoreHandle;
> > +  EFI_STATUS    Status =3D EFI_DEVICE_ERROR;
> > +
> > +  if (core =3D=3D NULL) {
> > +    DEBUG ((DEBUG_INFO, "UsbDeviceEpCancelTransfer ERROR: INVALID
> HANDLE\n"));
> > +  } else {
> > +    Status =3D core->CoreDriver->DevCoreEpCancelTransfer (core-
> >ControllerHandle, EpInfo);
> > +  }
> > +
> > +  return Status;
> > +}
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
> > new file mode 100644
> > index 0000000000..a10ec61732
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciDevice.h
> > @@ -0,0 +1,184 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#ifndef _USB_DEVICE_H_
> > +#define _USB_DEVICE_H_
> > +
> > +//
> > +// @USB_DEV_CONFIG_PARAMS: Struct to be filled in with configuration
> > +// parameters and passed to the init routine for device controller
> > +//
> > +typedef struct {
> > +  USB_CONTROLLER_ID  ControllerId; // Controller ID of the core
> > +  UINT32             BaseAddress;  // Base address of the controller r=
egisters
> and on-chip memory
> > +  UINT32             Flags;        // Initialization flags
> > +  USB_SPEED          Speed;        // Desired USB bus Speed
> > +  USB_ROLE           Role;         // Default USB role
> > +} USB_DEV_CONFIG_PARAMS;
> > +
> > +//
> > +// @USB_DEV_CORE: Struct used as a handle for all
> > +// hardware-independent APIs
> > +//
> > +typedef struct {
> > +  const struct UsbDeviceCoreDriver *CoreDriver;
> > +  VOID                                *ControllerHandle;
> > +} USB_DEV_CORE;
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *USB_DEVICE_CALLBACK_FUNC) (
> > +  IN USB_DEVICE_CALLBACK_PARAM  *Param
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceInit (
> > +  IN USB_DEV_CONFIG_PARAMS    *ConfigParams,
> > +  IN OUT VOID                 **DevCoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceDeinit (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN UINT32                    Flags
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceRegisterCallback (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_DEVICE_EVENT_ID       EventId,
> > +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFunc
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceUnregisterCallback (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_DEVICE_EVENT_ID       EventId
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceIsrRoutine (
> > +  IN VOID                      *DevCoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceIsrRoutineTimerBased (
> > +  IN VOID                      *DevCoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +UsbXdciDeviceConnect (
> > +  IN VOID                      *DevCoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceDisconnect (
> > +  IN VOID                      *DevCoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceGetSpeed (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_SPEED                 *Speed
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceSetLinkState (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_DEVICE_SS_LINK_STATE  State
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceSetAddress (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN UINT32                    Address
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceSetConfiguration (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN UINT32                    ConfigNum
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceInitEp (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceEpEnable (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceEpDisable (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceEpStall (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceEpClearStall (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceEpSetNrdy (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceEp0RxSetup (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN UINT8                     *Buffer
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceEp0RxStatus (
> > +  IN VOID                      *DevCoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceEp0TxStatus (
> > +  IN VOID                      *DevCoreHandle
> > +  );
> > +
> > +EFI_STATUS
> > +UsbXdciDeviceEpTxData (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_XFER_REQUEST          *XferReq
> > +  );
> > +
> > +EFI_STATUS
> > +UsbXdciDeviceEpRxData (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_XFER_REQUEST          *XferReq
> > +  );
> > +
> > +EFI_STATUS
> > +UsbDeviceEpCancelTransfer (
> > +  IN VOID                      *DevCoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +#endif
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
> > new file mode 100644
> > index 0000000000..75ce0ecab3
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciInterface.h
> > @@ -0,0 +1,241 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#ifndef _USB_DCD_IF_H_
> > +#define _USB_DCD_IF_H_
> > +
> > +/* Core driver for device controller
> > + * @DevCoreInit: Intializes device controller
> > + * @DevCoreDeinit: De-initializes device controller
> > + * @DevCoreRegisterCallback: Registers callback function for
> > + * an event to be called by the controller driver
> > + * @DevCoreUnregisterCallback: Unregisters callback function
> > + * for an event
> > + * @DevCoreIsrRoutine: core interrupt service routine for
> > + * device controller to be used by OS/stack-i/f layer
> > + * @DevCoreConnect: Enable device controller to connect to USB host
> > + * @DevCoreDisconnect: Soft disconnect device controller from
> > + * USB host
> > + * @DevCoreGetSpeed: Get USB bus Speed on which device controller
> > + * is attached
> > + * @DevCoreSetAddress: Set USB device address in device controller
> > + * @DevCoreSetConfig: Set configuration number for device controller
> > + * @DevCoreSetLinkState: Set link state for device controller
> > + * @DevCoreInitEp: Initialize non-EP0 endpoint
> > + * @DevCoreEpEnable: Enable endpoint
> > + * @DevCoreEpDisable: Disable endpoint
> > + * @DevCoreEpStall: Stall/Halt endpoint
> > + * @DevCoreEpClearStall: Clear Stall/Halt on endpoint
> > + * @DevCoreEpSetNrdy: Set endpoint to not ready state
> > + * @DevCoreEp0RxSetupPkt: Receive SETUP packet on EP0
> > + * @DevCoreEp0RxStatusPkt: Receive status packet on EP0
> > + * @DevCoreEp0TxStatusPkt: Transmit status packet from EP0
> > + * @DevCoreEpTxData: Transmit data from EP
> > + * @DevCoreEpRxData: Received data on EP
> > + * @DevCoreEpCancelTransfer: Cancel transfer on EP
> > + */
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_INIT) (
> > +  IN USB_DEV_CONFIG_PARAMS     *ConfigParams,
> > +  IN VOID                      *ParentHandle,
> > +  IN VOID                      **CoreHandle
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_DEINIT) (
> > +  IN VOID                      *CoreHandle,
> > +  IN UINT32                    Flags
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_REG_CALLBACK) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_DEVICE_EVENT_ID       Event,
> > +  IN USB_DEVICE_CALLBACK_FUNC  CallbackFn
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_UNREG_CALLBACK) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_DEVICE_EVENT_ID       Event
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_ISR_ROUTINE) (
> > +  IN VOID                      *CoreHandle
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_CONNECT) (
> > +  IN VOID                      *CoreHandle
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_DISCONNECT) (
> > +  IN VOID                      *CoreHandle
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_GET_SPEED) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_SPEED                 *Speed
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_SET_ADDRESS) (
> > +  IN VOID                      *CoreHandle,
> > +  IN UINT32                    Address
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_SET_CONFIG) (
> > +  IN VOID                      *CoreHandle,
> > +  IN UINT32                    ConfigNum
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_SET_LINK_STATE) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_DEVICE_SS_LINK_STATE  State
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_INIT_EP) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP_ENABLE) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP_DISABLE) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP_STALL) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP_CLEAR_STALL) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP_SET_NRDY) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP0_RX_SETUP_PKT) (
> > +  IN VOID                      *CoreHandle,
> > +  IN UINT8                     *Buffer
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP0_RX_STATUS_PKT) (
> > +  IN VOID                      *CoreHandle
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP0_TX_STATUS_PKT) (
> > +  IN VOID                      *CoreHandle
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP_TX_DATA) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_XFER_REQUEST          *XferHandle
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP_RX_DATA) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_XFER_REQUEST          *XferHandle
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *DEV_CORE_EP_CANCEL_TRANSFER) (
> > +  IN VOID                      *CoreHandle,
> > +  IN USB_EP_INFO               *EpInfo
> > +  );
> > +
> > +struct UsbDeviceCoreDriver {
> > +  DEV_CORE_INIT                 DevCoreInit;
> > +  DEV_CORE_DEINIT               DevCoreDeinit;
> > +  DEV_CORE_REG_CALLBACK         DevCoreRegisterCallback;
> > +  DEV_CORE_UNREG_CALLBACK       DevCoreUnregisterCallback;
> > +  DEV_CORE_ISR_ROUTINE          DevCoreIsrRoutine;
> > +  DEV_CORE_ISR_ROUTINE          DevCoreIsrRoutineTimerBased;
> > +  DEV_CORE_CONNECT              DevCoreConnect;
> > +  DEV_CORE_DISCONNECT           DevCoreDisconnect;
> > +  DEV_CORE_GET_SPEED            DevCoreGetSpeed;
> > +  DEV_CORE_SET_ADDRESS          DevCoreSetAddress;
> > +  DEV_CORE_SET_CONFIG           DevCoreSetConfig;
> > +  DEV_CORE_SET_LINK_STATE       DevCoreSetLinkState;
> > +  DEV_CORE_INIT_EP              DevCoreInitEp;
> > +  DEV_CORE_EP_ENABLE            DevCoreEpEnable;
> > +  DEV_CORE_EP_DISABLE           DevCoreEpDisable;
> > +  DEV_CORE_EP_STALL             DevCoreEpStall;
> > +  DEV_CORE_EP_CLEAR_STALL       DevCoreEpClearStall;
> > +  DEV_CORE_EP_SET_NRDY          DevCoreEpSetNrdy;
> > +  DEV_CORE_EP0_RX_SETUP_PKT     DevCoreEp0RxSetupPkt;
> > +  DEV_CORE_EP0_RX_STATUS_PKT    DevCoreEp0RxStatusPkt;
> > +  DEV_CORE_EP0_TX_STATUS_PKT    DevCoreEp0TxStatusPkt;
> > +  DEV_CORE_EP_TX_DATA           DevCoreEpTxData;
> > +  DEV_CORE_EP_RX_DATA           DevCoreEpRxData;
> > +  DEV_CORE_EP_CANCEL_TRANSFER   DevCoreEpCancelTransfer;
> > +};
> > +
> > +//
> > +// This API is used to obtain the driver handle for HW-independent API
> > +// @id: The ID of the core for which this driver is requested
> > +//
> > +const struct UsbDeviceCoreDriver *UsbDeviceGetCoreDriver(
> > +  USB_CONTROLLER_ID id);
> > +
> > +#endif
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
> > new file mode 100644
> > index 0000000000..97a97db3db
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciTable.c
> > @@ -0,0 +1,55 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#include <Library/UsbDeviceLib.h>
> > +#include "XdciCommon.h"
> > +#include "XdciDevice.h"
> > +#include "XdciInterface.h"
> > +#include "XdciDWC.h"
> > +#include "UsbDeviceMode.h"
> > +
> > +static const struct UsbDeviceCoreDriver
> CoreDriverTbl[USB_CORE_ID_MAX] =3D {
> > +  DwcXdciCoreInit,
> > +  DwcXdciCoreDeinit,
> > +  DwcXdciCoreRegisterCallback,
> > +  DwcXdciCoreUnregisterCallback,
> > +  DwcXdciCoreIsrRoutine,
> > +  DwcXdciCoreIsrRoutineTimerBased,
> > +  DwcXdciCoreConnect,
> > +  DwcXdciCoreDisconnect,
> > +  DwcXdciCoreGetSpeed,
> > +  DwcXdciCoreSetAddress,
> > +  DwcXdciCoreSetConfig,
> > +  DwcXdciSetLinkState,
> > +  DwcXdciInitEp,
> > +  DwcXdciEpEnable,
> > +  DwcXdciEpDisable,
> > +  DwcXdciEpStall,
> > +  DwcXdciEpClearStall,
> > +  DwcXdciEpSetNrdy,
> > +  DwcXdciEp0ReceiveSetupPkt,
> > +  DwcXdciEp0ReceiveStatusPkt,
> > +  DwcXdciEp0SendStatusPkt,
> > +  DwcXdciEpTxData,
> > +  DwcXdciEpRxData,
> > +  DwcXdciEpCancelTransfer
> > +};
> > +
> > +const struct UsbDeviceCoreDriver
> *UsbDeviceGetCoreDriver(USB_CONTROLLER_ID id)
> > +{
> > +  if (id >=3D USB_CORE_ID_MAX)
> > +    return NULL;
> > +
> > +  return &CoreDriverTbl[id];
> > +}
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
> > new file mode 100644
> > index 0000000000..2e02475cd0
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.c
> > @@ -0,0 +1,148 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#include "XdciUtility.h"
> > +
> > +VOID
> > +PrintDeviceDescriptor (
> > +  IN USB_DEVICE_DESCRIPTOR    *DevDesc
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "--- Device Descriptor ---\n"));
> > +  DEBUG ((DEBUG_INFO, "Length            : 0x%x\n", DevDesc->Length));
> > +  DEBUG ((DEBUG_INFO, "DescriptorType    : 0x%x\n", DevDesc-
> >DescriptorType));
> > +  DEBUG ((DEBUG_INFO, "BcdUSB            : 0x%x\n", DevDesc->BcdUSB));
> > +  DEBUG ((DEBUG_INFO, "DeviceClass       : 0x%x\n", DevDesc-
> >DeviceClass));
> > +  DEBUG ((DEBUG_INFO, "DeviceSubClass    : 0x%x\n", DevDesc-
> >DeviceSubClass));
> > +  DEBUG ((DEBUG_INFO, "DeviceProtocol    : 0x%x\n", DevDesc-
> >DeviceProtocol));
> > +  DEBUG ((DEBUG_INFO, "MaxPacketSize0    : 0x%x\n", DevDesc-
> >MaxPacketSize0));
> > +  DEBUG ((DEBUG_INFO, "IdVendor          : 0x%x\n", DevDesc->IdVendor)=
);
> > +  DEBUG ((DEBUG_INFO, "IdProduct         : 0x%x\n", DevDesc->IdProduct=
));
> > +  DEBUG ((DEBUG_INFO, "BcdDevice         : 0x%x\n", DevDesc-
> >BcdDevice));
> > +  DEBUG ((DEBUG_INFO, "StrManufacturer   : 0x%x\n", DevDesc-
> >StrManufacturer));
> > +  DEBUG ((DEBUG_INFO, "StrProduct        : 0x%x\n", DevDesc-
> >StrProduct));
> > +  DEBUG ((DEBUG_INFO, "StrSerialNumber   : 0x%x\n", DevDesc-
> >StrSerialNumber));
> > +  DEBUG ((DEBUG_INFO, "NumConfigurations : 0x%x\n", DevDesc-
> >NumConfigurations));
> > +  DEBUG ((DEBUG_INFO, "\n"));
> > +}
> > +
> > +VOID
> > +PrintConfigDescriptor (
> > +  IN EFI_USB_CONFIG_DESCRIPTOR    *ConfigDesc
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "--- Configuration Descriptor ---\n"));
> > +  DEBUG ((DEBUG_INFO, "Length             : 0x%x\n", ConfigDesc->Lengt=
h));
> > +  DEBUG ((DEBUG_INFO, "DescriptorType     : 0x%x\n", ConfigDesc-
> >DescriptorType));
> > +  DEBUG ((DEBUG_INFO, "TotalLength        : 0x%x\n", ConfigDesc-
> >TotalLength));
> > +  DEBUG ((DEBUG_INFO, "NumInterfaces      : 0x%x\n", ConfigDesc-
> >NumInterfaces));
> > +  DEBUG ((DEBUG_INFO, "ConfigurationValue : 0x%x\n", ConfigDesc-
> >ConfigurationValue));
> > +  DEBUG ((DEBUG_INFO, "Configuration      : 0x%x\n", ConfigDesc-
> >Configuration));
> > +  DEBUG ((DEBUG_INFO, "Attributes         : 0x%x\n", ConfigDesc-
> >Attributes));
> > +  DEBUG ((DEBUG_INFO, "MaxPower           : 0x%x\n", ConfigDesc-
> >MaxPower));
> > +  DEBUG ((DEBUG_INFO, "\n"));
> > +}
> > +
> > +VOID
> > +PrintInterfaceDescriptor (
> > +  IN EFI_USB_INTERFACE_DESCRIPTOR    *IfDesc
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "--- Interface Descriptor ---\n"));
> > +  DEBUG ((DEBUG_INFO, "Length            : 0x%x\n", IfDesc->Length));
> > +  DEBUG ((DEBUG_INFO, "DescriptorType    : 0x%x\n", IfDesc-
> >DescriptorType));
> > +  DEBUG ((DEBUG_INFO, "InterfaceNumber   : 0x%x\n", IfDesc-
> >InterfaceNumber));
> > +  DEBUG ((DEBUG_INFO, "AlternateSetting  : 0x%x\n", IfDesc-
> >AlternateSetting));
> > +  DEBUG ((DEBUG_INFO, "NumEndpoints      : 0x%x\n", IfDesc-
> >NumEndpoints));
> > +  DEBUG ((DEBUG_INFO, "InterfaceClass    : 0x%x\n", IfDesc-
> >InterfaceClass));
> > +  DEBUG ((DEBUG_INFO, "InterfaceSubClass : 0x%x\n", IfDesc-
> >InterfaceSubClass));
> > +  DEBUG ((DEBUG_INFO, "InterfaceProtocol : 0x%x\n", IfDesc-
> >InterfaceProtocol));
> > +  DEBUG ((DEBUG_INFO, "Interface         : 0x%x\n", IfDesc->Interface)=
);
> > +  DEBUG ((DEBUG_INFO, "\n"));
> > +}
> > +
> > +VOID
> > +PrintEpDescriptor (
> > +  IN EFI_USB_ENDPOINT_DESCRIPTOR    *EpDesc
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "--- Endpoint Descriptor ---\n"));
> > +  DEBUG ((DEBUG_INFO, "Length          : 0x%x\n", EpDesc->Length));
> > +  DEBUG ((DEBUG_INFO, "DescriptorType  : 0x%x\n", EpDesc-
> >DescriptorType));
> > +  DEBUG ((DEBUG_INFO, "EndpointAddress : 0x%x\n", EpDesc-
> >EndpointAddress));
> > +  DEBUG ((DEBUG_INFO, "Attributes      : 0x%x\n", EpDesc->Attributes))=
;
> > +  DEBUG ((DEBUG_INFO, "MaxPacketSize   : 0x%x\n", EpDesc-
> >MaxPacketSize));
> > +  DEBUG ((DEBUG_INFO, "Interval        : 0x%x\n", EpDesc->Interval));
> > +  DEBUG ((DEBUG_INFO, "\n"));
> > +}
> > +
> > +VOID
> > +PrintEpCompDescriptor (
> > +  IN EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpDesc
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "--- Endpoint Companion Descriptor ---\n"));
> > +  DEBUG ((DEBUG_INFO, "Length           : 0x%x\n", EpDesc->Length));
> > +  DEBUG ((DEBUG_INFO, "DescriptorType   : 0x%x\n", EpDesc-
> >DescriptorType));
> > +  DEBUG ((DEBUG_INFO, "MaxBurst         : 0x%x\n", EpDesc->MaxBurst));
> > +  DEBUG ((DEBUG_INFO, "Attributes       : 0x%x\n", EpDesc->Attributes)=
);
> > +  DEBUG ((DEBUG_INFO, "BytesPerInterval : 0x%x\n", EpDesc-
> >BytesPerInterval));
> > +  DEBUG ((DEBUG_INFO, "\n"));
> > +}
> > +
> > +VOID
> > +PrintStringDescriptor (
> > +  IN USB_STRING_DESCRIPTOR    *StrDesc
> > +  )
> > +{
> > +  UINT16 StrLen =3D 0;
> > +
> > +  if (StrDesc->Length > 2) {
> > +    StrLen =3D ((StrDesc->Length - 2) >> 1);
> > +    DEBUG ((DEBUG_INFO, "--- String Descriptor ---\n"));
> > +    DEBUG ((DEBUG_INFO, "Length         : 0x%x\n", StrDesc->Length));
> > +    DEBUG ((DEBUG_INFO, "DescriptorType : 0x%x\n", StrDesc-
> >DescriptorType));
> > +    DEBUG ((DEBUG_INFO, "String         : %s\n",   StrDesc->LangID));
> > +  }
> > +  DEBUG ((DEBUG_INFO, "\n"));
> > +}
> > +
> > +VOID
> > +PrintDeviceRequest (
> > +  IN EFI_USB_DEVICE_REQUEST    *DevReq
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "--- Device Request ---\n"));
> > +  DEBUG ((DEBUG_INFO, "RequestType : 0x%x\n", DevReq-
> >RequestType));
> > +  DEBUG ((DEBUG_INFO, "Request     : 0x%x\n", DevReq->Request));
> > +  DEBUG ((DEBUG_INFO, "Value       : 0x%x\n", DevReq->Value));
> > +  DEBUG ((DEBUG_INFO, "Index       : 0x%x\n", DevReq->Index));
> > +  DEBUG ((DEBUG_INFO, "Length      : 0x%x\n", DevReq->Length));
> > +  DEBUG ((DEBUG_INFO, "\n"));
> > +}
> > +
> > +#ifdef SUPPORT_SUPER_SPEED
> > +VOID
> > +PrintBOSDescriptor (
> > +  IN EFI_USB_BOS_DESCRIPTOR    *BosDesc
> > +  )
> > +{
> > +  DEBUG ((DEBUG_INFO, "--- BOS Descriptor ---\n"));
> > +  DEBUG ((DEBUG_INFO, "Length           : 0x%x\n", BosDesc->Length));
> > +  DEBUG ((DEBUG_INFO, "DescriptorType   : 0x%x\n", BosDesc-
> >DescriptorType));
> > +  DEBUG ((DEBUG_INFO, "TotalLength      : 0x%x\n", BosDesc-
> >TotalLength));
> > +  DEBUG ((DEBUG_INFO, "NumDeviceCaps    : 0x%x\n", BosDesc-
> >NumDeviceCaps));
> > +  DEBUG ((DEBUG_INFO, "\n"));
> > +}
> > +#endif
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
> b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
> > new file mode 100644
> > index 0000000000..e3d004e579
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Drivers/UsbDeviceDxe/XdciUtility.h
> > @@ -0,0 +1,62 @@
> > +/** @file
> > +  Copyright (c) 2006 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#ifndef _XDCI_UTILITY_H_
> > +#define _XDCI_UTILITY_H_
> > +
> > +#include <Library/UsbDeviceLib.h>
> > +
> > +VOID
> > +PrintDeviceDescriptor (
> > +  IN USB_DEVICE_DESCRIPTOR    *DevDesc
> > +  );
> > +
> > +VOID
> > +PrintConfigDescriptor (
> > +  IN EFI_USB_CONFIG_DESCRIPTOR    *ConfigDesc
> > +  );
> > +
> > +VOID
> > +PrintInterfaceDescriptor (
> > +  IN EFI_USB_INTERFACE_DESCRIPTOR    *IfDesc
> > +  );
> > +
> > +VOID
> > +PrintEpDescriptor (
> > +  IN EFI_USB_ENDPOINT_DESCRIPTOR    *EpDesc
> > +  );
> > +
> > +VOID
> > +PrintEpCompDescriptor (
> > +  IN EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EpDesc
> > +  );
> > +
> > +VOID
> > +PrintStringDescriptor (
> > +  IN USB_STRING_DESCRIPTOR    *StrDesc
> > +  );
> > +
> > +VOID
> > +PrintDeviceRequest (
> > +  IN EFI_USB_DEVICE_REQUEST    *DevReq
> > +  );
> > +
> > +#ifdef SUPPORT_SUPER_SPEED
> > +VOID
> > +PrintBOSDescriptor (
> > +  IN EFI_USB_BOS_DESCRIPTOR    *BosDesc
> > +  );
> > +#endif
> > +
> > +#endif
> > +
> > diff --git a/Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
> b/Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
> > new file mode 100644
> > index 0000000000..fe5f3bcd03
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Include/Library/UsbDeviceLib.h
> > @@ -0,0 +1,323 @@
> > +/** @file
> > +  Copyright (c) 2009 - 2016, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#ifndef _EFI_XDCI_LIB_H_
> > +#define _EFI_XDCI_LIB_H_
> > +
> > +#include <Uefi.h>
> > +#include <Library/DebugLib.h>
> > +#include <Library/BaseMemoryLib.h>
> > +#include <Library/MemoryAllocationLib.h>
> > +#include <Library/UefiBootServicesTableLib.h>
> > +#include <Protocol/UsbIo.h>
> > +
> > +#define MAX_DESCRIPTOR_SIZE         64
> > +#define STRING_ARR_SIZE             (MAX_DESCRIPTOR_SIZE - 2)
> > +#define USB_ADDRESS_TABLE_SIZE      16  //4
> > +
> > +//
> > +// Endpoint Zero
> > +//
> > +#define USB_EP0_MAX_PKT_SIZE_HS     0x40 // High Speed mode is
> explicitly set as 64 bytes
> > +#define USB_EP0_MAX_PKT_SIZE_SS     0x9  // Must be 0x9 (2^9 =3D 512
> Bytes) in SuperSpeed mode
> > +#define USB_EPO_MAX_PKT_SIZE_ALL    512  // Overall max bytes for any
> type
> > +
> > +//
> > +// Bulk Endpoints
> > +//
> > +#define USB_BULK_EP_PKT_SIZE_HS     0x200 // Bulk-Endpoint HighSpeed
> > +#define USB_BULK_EP_PKT_SIZE_SS     0x400 // Bulk-Endpoint SuperSpeed
> > +#define USB_BULK_EP_PKT_SIZE_MAX    USB_BULK_EP_PKT_SIZE_SS
> > +
> > +//
> > +// Transmit Direction Bits
> > +//
> > +#define USB_ENDPOINT_DIR_OUT                 0x00
> > +
> > +//
> > +// Endpoint Companion Bulk Attributes
> > +//
> > +#define USB_EP_BULK_BM_ATTR_MASK    0x1F
> > +
> > +//
> > +// Configuration Modifiers (Attributes)
> > +//
> > +#define USB_BM_ATTR_RESERVED        0x80
> > +#define USB_BM_ATTR_SELF_POWERED    0x40
> > +#define USB_BM_ATTR_REMOTE_WAKE     0X20
> > +
> > +//
> > +// USB BCD version
> > +//
> > +#define USB_BCD_VERSION_LS          0x0110
> > +#define USB_BCD_VERSION_HS          0x0200
> > +#define USB_BCD_VERSION_SS          0x0300
> > +
> > +//
> > +// Device RequestType Flags
> > +//
> > +#define USB_RT_TX_DIR_H_TO_D        (0x0)       // Tx direction Host t=
o
> Device
> > +#define USB_RT_TX_DIR_D_TO_H        (0x1 << 7)  // Tx direction Device=
 to
> Host
> > +#define USB_RT_TX_DIR_MASK          (0x80)
> > +
> > +//
> > +// USB request type
> > +//
> > +#define USB_REQ_TYPE_MASK           (0x60)
> > +
> > +//
> > +// Usb control transfer target
> > +//
> > +#define USB_TARGET_MASK             (0x1F)
> > +
> > +//
> > +// Device GetStatus bits
> > +//
> > +#define USB_STATUS_SELFPOWERED      (0x01)
> > +#define USB_STATUS_REMOTEWAKEUP     (0x02)
> > +
> > +//
> > +// USB Device class identifiers
> > +//
> > +#define USB_DEVICE_MS_CLASS         (0x08)
> > +#define USB_DEVICE_VENDOR_CLASS     (0xFF)
> > +
> > +//
> > +// USB Descriptor types
> > +//
> > +#define USB_DESC_TYPE_BOS                    0x0F
> > +#define USB_DESC_TYPE_DEVICE_CAPABILITY      0x10
> > +#define USB_DESC_TYPE_SS_ENDPOINT_COMPANION  0x30
> > +
> > +#ifdef SUPPORT_SUPER_SPEED
> > +//
> > +// USB device capability Type Codes
> > +// USB3 Table 9-13
> > +//
> > +typedef enum {
> > +  WirelessUSB =3D 0x01,
> > +  USB2Extension,
> > +  SuperSpeedUSB,
> > +  ContainerID,
> > +  SuperSpeedPlusUSB =3D 0x0A
> > +} USB_DEVICE_CAP_TYPE_CODE;
> > +#endif
> > +
> > +//
> > +// USB device states from USB spec sec 9.1
> > +//
> > +typedef enum {
> > +  UsbDevStateOff =3D 0,
> > +  UsbDevStateInit,
> > +  UsbDevStateAttached,
> > +  UsbDevStatePowered,
> > +  UsbDevStateDefault,
> > +  UsbDevStateAddress,
> > +  UsbDevStateConfigured,
> > +  UsbDevStateSuspended,
> > +  UsbDevStateError
> > +} USB_DEVICE_STATE;
> > +
> > +//
> > +// The following set of structs are used during USB data transaction
> > +// operatitions, including requests and completion events.
> > +//
> > +#pragma pack(1)
> > +
> > +typedef struct {
> > +  UINT32     EndpointNum;
> > +  UINT8      EndpointDir;
> > +  UINT8      EndpointType;
> > +  UINT32     Length;
> > +  VOID       *Buffer;
> > +} EFI_USB_DEVICE_XFER_INFO;
> > +
> > +//
> > +// SuperSpeed Endpoint companion descriptor
> > +// USB3 table 9-22
> > +//
> > +typedef struct {
> > +  UINT8      Length;
> > +  UINT8      DescriptorType;
> > +  UINT8      MaxBurst;
> > +  UINT8      Attributes;
> > +  UINT16     BytesPerInterval;
> > +} EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR;
> > +
> > +typedef struct {
> > +  EFI_USB_ENDPOINT_DESCRIPTOR              *EndpointDesc;
> > +  EFI_USB_ENDPOINT_COMPANION_DESCRIPTOR    *EndpointCompDesc;
> > +} USB_DEVICE_ENDPOINT_INFO, USB_DEVICE_ENDPOINT_OBJ;
> > +
> > +typedef struct {
> > +  VOID        *Buffer;
> > +  UINT32      Length;
> > +} USB_DEVICE_IO_INFO;
> > +
> > +typedef struct {
> > +  USB_DEVICE_IO_INFO           IoInfo;
> > +  USB_DEVICE_ENDPOINT_INFO     EndpointInfo;
> > +} USB_DEVICE_IO_REQ;
> > +
> > +//
> > +// Optional string descriptor
> > +//
> > +typedef struct {
> > +  UINT8           Length;
> > +  UINT8           DescriptorType;
> > +  UINT16          LangID[STRING_ARR_SIZE];
> > +} USB_STRING_DESCRIPTOR;
> > +
> > +//
> > +// The following structures abstract the device descriptors a class
> > +// driver needs to provide to the USBD core.
> > +// These structures are filled & owned by the class/function layer.
> > +//
> > +typedef struct {
> > +  EFI_USB_INTERFACE_DESCRIPTOR         *InterfaceDesc;
> > +  USB_DEVICE_ENDPOINT_OBJ              *EndpointObjs;
> > +} USB_DEVICE_INTERFACE_OBJ;
> > +
> > +typedef struct {
> > +  EFI_USB_CONFIG_DESCRIPTOR     *ConfigDesc;
> > +  VOID                          *ConfigAll;
> > +  USB_DEVICE_INTERFACE_OBJ      *InterfaceObjs;
> > +} USB_DEVICE_CONFIG_OBJ;
> > +
> > +#ifdef SUPPORT_SUPER_SPEED
> > +//
> > +// SuperSpeed Binary Device Object Store(BOS) descriptor
> > +// USB3 9.6.2
> > +//
> > +typedef struct {
> > +  UINT8      Length;
> > +  UINT8      DescriptorType;
> > +  UINT16     TotalLength;
> > +  UINT8      NumDeviceCaps;
> > +} EFI_USB_BOS_DESCRIPTOR;
> > +
> > +//
> > +// Generic Header of Device Capability descriptor
> > +// USB3 9.6.2.2
> > +//
> > +typedef struct {
> > +  UINT8      Length;
> > +  UINT8      DescriptorType;
> > +  UINT8      DevCapabilityType;
> > +  UINT8      CapDependent;
> > +} EFI_USB_SS_DEVICE_CAP_DESCRIPTOR;
> > +
> > +//
> > +// USB2.0 Extension descriptor
> > +// USB3 Table 9-14
> > +//
> > +typedef struct {
> > +  UINT8      Length;
> > +  UINT8      DescriptorType;
> > +  UINT8      DeviceCapabilityType;
> > +  UINT32     Attributes;
> > +} EFI_USB_USB2_EXT_CAP_DESCRIPTOR;
> > +
> > +//
> > +// SuperSpeed USB Device Capability descriptor
> > +// USB3 Table 9-15
> > +//
> > +typedef struct {
> > +  UINT8      Length;
> > +  UINT8      DescriptorType;
> > +  UINT8      DeviceCapabilityType;
> > +  UINT8      Attributes;
> > +  UINT16     SpeedSupported;
> > +  UINT8      FunctionalitySupport;
> > +  UINT8      U1DevExitLat;
> > +  UINT16     U2DevExitLat;
> > +} EFI_USB_SS_USB_DEV_CAP_DESCRIPTOR;
> > +
> > +//
> > +// Container ID descriptor
> > +// USB3 Table 9-16
> > +//
> > +typedef struct {
> > +  UINT8      Length;
> > +  UINT8      DescriptorType;
> > +  UINT8      DeviceCapabilityType;
> > +  UINT8      Reserved;
> > +  UINT8      UUID[16];
> > +} EFI_USB_CONTAINER_ID_DESCRIPTOR;
> > +
> > +//
> > +// Container ID descriptor
> > +// USB3 Table 9-16
> > +//
> > +typedef struct {
> > +  UINT8      Length;
> > +  UINT8      DescriptorType;
> > +  UINT8      DeviceCapabilityType;
> > +  UINT8      ReservedByte;
> > +  UINT32     Attributes;
> > +  UINT16     FunctionalitySupport;
> > +  UINT16     ReservedWord;
> > +  UINT32     SublinkSpeedAttr[2];
> > +} EFI_USB_SS_PLUS_USB_DEV_CAP_DESCRIPTOR;
> > +
> > +#endif
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_CONFIG_CALLBACK) (
> > +  IN UINT8                      CfgVal
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_SETUP_CALLBACK) (
> > +  IN EFI_USB_DEVICE_REQUEST     *CtrlRequest,
> > +  IN USB_DEVICE_IO_INFO         *IoInfo
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DATA_CALLBACK) (
> > +  IN EFI_USB_DEVICE_XFER_INFO   *XferInfo
> > +  );
> > +
> > +typedef struct {
> > +  USB_DEVICE_DESCRIPTOR       *DeviceDesc;
> > +  USB_DEVICE_CONFIG_OBJ       *ConfigObjs;
> > +  USB_STRING_DESCRIPTOR       *StringTable;
> > +#ifdef SUPPORT_SUPER_SPEED
> > +  EFI_USB_BOS_DESCRIPTOR      *BosDesc;
> > +#endif
> > +  UINT8                       StrTblEntries;
> > +  EFI_USB_CONFIG_CALLBACK     ConfigCallback;
> > +  EFI_USB_SETUP_CALLBACK      SetupCallback;
> > +  EFI_USB_DATA_CALLBACK       DataCallback;
> > +} USB_DEVICE_OBJ;
> > +
> > +//
> > +// Main USBD driver object structure containing all data necessary
> > +// for USB device mode processing at this layer
> > +//
> > +typedef struct {
> > +  USB_DEVICE_OBJ              *UsbdDevObj;      /* pointer to a Device=
 Object
> */
> > +  VOID                        *XdciDrvObj;      /* Opaque handle to XD=
CI driver */
> > +  BOOLEAN                     XdciInitialized;  /* flag to specify if =
the XDCI driver is
> initialized */
> > +  USB_DEVICE_CONFIG_OBJ       *ActiveConfigObj; /* pointer to currentl=
y
> active configuraiton */
> > +  USB_DEVICE_STATE            State;            /* current state of th=
e USB Device
> state machine */
> > +  UINT8                       Address;          /* configured device a=
ddress */
> > +} USB_DEVICE_DRIVER_OBJ;
> > +
> > +#pragma pack()
> > +
> > +#endif
> > +
> > diff --git a/Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
> b/Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
> > new file mode 100644
> > index 0000000000..97f276f1cc
> > --- /dev/null
> > +++ b/Silicon/Synopsys/DesignWare/Include/Protocol/EfiUsbFnIo.h
> > @@ -0,0 +1,430 @@
> > +/** @file
> > +  EFI USB function IO Protocol
> > +  This protocol supports Usb Function IO API.
> > +  Copyright (c) 1999 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +#ifndef __EFI_USB_FUNC_IO_H__
> > +#define __EFI_USB_FUNC_IO_H__
> > +
> > +#include <IndustryStandard/Usb.h>
> > +
> > +#define EFI_USBFN_IO_PROTOCOL_REVISION   0x00010001
> > +
> > +//
> > +// {32D2963A-FE5D-4f30-B633-6E5DC55803CC}
> > +// #define EFI_USBFN_IO_PROTOCOL_GUID  {0x32d2963a, 0xfe5d, 0x4f30,
> 0xb6, 0x33, 0x6e, 0x5d, 0xc5, 0x58, 0x3, 0xcc };
> > +//
> > +
> > +typedef struct _EFI_USBFN_IO_PROTOCOL   EFI_USBFN_IO_PROTOCOL;
> > +
> > +//
> > +// USB standard descriptors and reqeust
> > +//
> > +typedef USB_DEVICE_REQUEST        EFI_USB_DEVICE_REQUEST;
> > +typedef USB_DEVICE_DESCRIPTOR     EFI_USB_DEVICE_DESCRIPTOR;
> > +typedef USB_CONFIG_DESCRIPTOR     EFI_USB_CONFIG_DESCRIPTOR;
> > +typedef USB_INTERFACE_DESCRIPTOR  EFI_USB_INTERFACE_DESCRIPTOR;
> > +typedef USB_ENDPOINT_DESCRIPTOR   EFI_USB_ENDPOINT_DESCRIPTOR;
> > +
> > +typedef enum _EFI_USBFN_PORT_TYPE {
> > +  EfiUsbUnknownPort =3D 0,
> > +  EfiUsbStandardDownstreamPort,
> > +  EfiUsbChargingDownstreamPort,
> > +  EfiUsbDedicatedChargingPort,
> > +  EfiUsbInvalidDedicatedChargingPort
> > +} EFI_USBFN_PORT_TYPE;
> > +
> > +/**
> > + USB_DEVICE_DESCRIPTOR, USB_CONFIG_DESCRIPTOR,
> USB_INTERFACE_DESCRIPTOR, and
> > + USB_ENDPOINT_DESCRIPTOR are already defined
> > + in UEFI spec 2.3, as par USB 2.0 spec.
> > +**/
> > +
> > +typedef struct {
> > +  EFI_USB_INTERFACE_DESCRIPTOR        *InterfaceDescriptor;
> > +  EFI_USB_ENDPOINT_DESCRIPTOR         **EndpointDescriptorTable;
> > +} EFI_USB_INTERFACE_INFO;
> > +
> > +typedef struct {
> > +  EFI_USB_CONFIG_DESCRIPTOR           *ConfigDescriptor;
> > +  EFI_USB_INTERFACE_INFO              **InterfaceInfoTable;
> > +} EFI_USB_CONFIG_INFO;
> > +
> > +typedef struct {
> > +  EFI_USB_DEVICE_DESCRIPTOR           *DeviceDescriptor;
> > +  EFI_USB_CONFIG_INFO                 **ConfigInfoTable;
> > +} EFI_USB_DEVICE_INFO;
> > +
> > +
> > +typedef enum _EFI_USB_ENDPOINT_TYPE {
> > +  UsbEndpointControl     =3D 0x00,
> > +  UsbEndpointIsochronous =3D 0x01,
> > +  UsbEndpointBulk        =3D 0x02,
> > +  UsbEndpointInterrupt   =3D 0x03
> > +} EFI_USB_ENDPOINT_TYPE;
> > +
> > +
> > +typedef enum _EFI_USBFN_DEVICE_INFO_ID {
> > +  EfiUsbDeviceInfoUnknown =3D 0,
> > +  EfiUsbDeviceInfoSerialNumber,
> > +  EfiUsbDeviceInfoManufacturerName,
> > +  EfiUsbDeviceInfoProductName
> > +} EFI_USBFN_DEVICE_INFO_ID;
> > +
> > +
> > +typedef enum _EFI_USBFN_ENDPOINT_DIRECTION {
> > +  EfiUsbEndpointDirectionHostOut  =3D 0,
> > +  EfiUsbEndpointDirectionHostIn,
> > +  EfiUsbEndpointDirectionDeviceTx =3D EfiUsbEndpointDirectionHostIn,
> > +  EfiUsbEndpointDirectionDeviceRx =3D EfiUsbEndpointDirectionHostOut
> > +} EFI_USBFN_ENDPOINT_DIRECTION;
> > +
> > +
> > +typedef enum _EFI_USBFN_MESSAGE {
> > +  //
> > +  // Nothing
> > +  //
> > +  EfiUsbMsgNone =3D 0,
> > +  //
> > +  // SETUP packet is received, returned Buffer contains
> > +  // EFI_USB_DEVICE_REQUEST struct
> > +  //
> > +  EfiUsbMsgSetupPacket,
> > +  //
> > +  // Indicates that some of the requested data has been received from =
the
> > +  // host. It is the responsibility of the class driver to determine i=
f it
> > +  // needs to wait for any remaining data. Returned Buffer contains
> > +  // EFI_USBFN_TRANSFER_RESULT struct containing endpoint number,
> transfer
> > +  // status and count of bytes received.
> > +  //
> > +  EfiUsbMsgEndpointStatusChangedRx,
> > +  //
> > +  // Indicates that some of the requested data has been transmitted to=
 the
> > +  // host. It is the responsibility of the class driver to determine i=
f any
> > +  // remaining data needs to be resent. Returned Buffer contains
> > +  // EFI_USBFN_TRANSFER_RESULT struct containing endpoint number,
> transfer
> > +  // status and count of bytes sent.
> > +  //
> > +  EfiUsbMsgEndpointStatusChangedTx,
> > +  //
> > +  // DETACH bus event signaled
> > +  //
> > +  EfiUsbMsgBusEventDetach,
> > +  //
> > +  // ATTACH bus event signaled
> > +  //
> > +  EfiUsbMsgBusEventAttach,
> > +  //
> > +  // RESET bus event signaled
> > +  //
> > +  EfiUsbMsgBusEventReset,
> > +  //
> > +  // SUSPEND bus event signaled
> > +  //
> > +  EfiUsbMsgBusEventSuspend,
> > +  //
> > +  // RESUME bus event signaled
> > +  //
> > +  EfiUsbMsgBusEventResume,
> > +  //
> > +  // Bus speed updated, returned buffer indicated bus speed using
> > +  // following enumeration named EFI_USB_BUS_SPEED
> > +  //
> > +  EfiUsbMsgBusEventSpeed
> > +} EFI_USBFN_MESSAGE;
> > +
> > +
> > +typedef enum _EFI_USBFN_TRANSFER_STATUS {
> > +  UsbTransferStatusUnknown =3D 0,
> > +  UsbTransferStatusComplete,
> > +  UsbTransferStatusAborted,
> > +  UsbTransferStatusActive,
> > +  UsbTransferStatusNone
> > +} EFI_USBFN_TRANSFER_STATUS;
> > +
> > +
> > +typedef struct _EFI_USBFN_TRANSFER_RESULT {
> > +  UINTN                         BytesTransferred;
> > +  EFI_USBFN_TRANSFER_STATUS     TransferStatus;
> > +  UINT8                         EndpointIndex;
> > +  EFI_USBFN_ENDPOINT_DIRECTION  Direction;
> > +  VOID                          *Buffer;
> > +} EFI_USBFN_TRANSFER_RESULT;
> > +
> > +typedef enum _EFI_USB_BUS_SPEED {
> > +  UsbBusSpeedUnknown =3D 0,
> > +  UsbBusSpeedLow,
> > +  UsbBusSpeedFull,
> > +  UsbBusSpeedHigh,
> > +  UsbBusSpeedSuper,
> > +  UsbBusSpeedMaximum =3D UsbBusSpeedSuper
> > +} EFI_USB_BUS_SPEED;
> > +
> > +typedef union _EFI_USBFN_MESSAGE_PAYLOAD {
> > +  EFI_USB_DEVICE_REQUEST      udr;
> > +  EFI_USBFN_TRANSFER_RESULT   utr;
> > +  EFI_USB_BUS_SPEED           ubs;
> > +} EFI_USBFN_MESSAGE_PAYLOAD;
> > +
> > +typedef enum _EFI_USBFN_POLICY_TYPE {
> > +  EfiUsbPolicyUndefined =3D 0,
> > +  EfiUsbPolicyMaxTransactionSize,
> > +  EfiUsbPolicyZeroLengthTerminationSupport,
> > +  EfiUsbPolicyZeroLengthTermination
> > +} EFI_USBFN_POLICY_TYPE;
> > +
> > +
> > +/**
> > +
> > + Allocates transfer buffer of the specified size that satisfies
> > + controller requirements.
> > +
> > + The AllocateTransferBuffer function allocates a memory region of Size
> bytes and
> > + returns the address of the allocated memory that satisfies underlying
> > + controller requirements in the location referenced by Buffer.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_ALLOCATE_TRANSFER_BUFFER) (
> > +  IN EFI_USBFN_IO_PROTOCOL    *This,
> > +  IN UINTN                    Size,
> > +  OUT VOID                    **Buffer
> > +  );
> > +
> > +/**
> > +
> > +  Deallocates the memory allocated for the transfer buffer by
> AllocateTransferBuffer function.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_FREE_TRANSFER_BUFFER) (
> > +  IN EFI_USBFN_IO_PROTOCOL    *This,
> > +  IN VOID                     *Buffer
> > +  );
> > +
> > +/**
> > +  Returns information about what type of device was attached.
> > +
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_DETECT_PORT) (
> > +  IN EFI_USBFN_IO_PROTOCOL   *This,
> > +  OUT EFI_USBFN_PORT_TYPE    *PortType
> > +  );
> > +
> > +/**
> > +  Configure endpoints based on supplied device and configuration
> descriptors.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_CONFIGURE_ENABLE_ENDPOINTS) (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN EFI_USB_DEVICE_INFO           *DeviceInfo
> > +  );
> > +
> > +
> > +/**
> > +  Returns the maximum packet size of the specified endpoint type for t=
he
> supplied bus speed.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_GET_ENDPOINT_MAXPACKET_SIZE) (
> > +  IN EFI_USBFN_IO_PROTOCOL       *This,
> > +  IN EFI_USB_ENDPOINT_TYPE       EndpointType,
> > +  IN EFI_USB_BUS_SPEED           BusSpeed,
> > +  OUT UINT16                     *MaxPacketSize
> > +  );
> > +
> > +/**
> > +  Returns the maximum supported transfer size.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_GET_MAXTRANSFER_SIZE) (
> > +  IN EFI_USBFN_IO_PROTOCOL     *This,
> > +  OUT UINTN                    *MaxTransferSize
> > +  );
> > +
> > +/**
> > +  Returns device specific information based on the supplied identifier=
 as a
> > +  Unicode string.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_GET_DEVICE_INFO) (
> > +  IN EFI_USBFN_IO_PROTOCOL      *This,
> > +  IN EFI_USBFN_DEVICE_INFO_ID   Id,
> > +  IN OUT UINTN                  *BufferSize,
> > +  OUT VOID                      *Buffer OPTIONAL
> > +  );
> > +
> > +/**
> > +  Returns vendor-id and product-id of the device.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_GET_VENDOR_ID_PRODUCT_ID) (
> > +  IN EFI_USBFN_IO_PROTOCOL      *This,
> > +  OUT UINT16                    *Vid,
> > +  OUT UINT16                    *Pid
> > +  );
> > +
> > +/**
> > +  Aborts transfer on the specified endpoint.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_ABORT_TRANSFER) (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction
> > +  );
> > +
> > +/**
> > +  Returns the stall state on the specified endpoint.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_GET_ENDPOINT_STALL_STATE) (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> > +  IN OUT BOOLEAN                  *State
> > +  );
> > +
> > +/**
> > +  Sets or clears the stall state on the specified endpoint.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_SET_ENDPOINT_STALL_STATE) (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> > +  IN BOOLEAN                      State
> > +  );
> > +
> > +
> > +/**
> > +  This function is called repeatedly to receive updates on USB bus sta=
tes,
> > +  receive, transmit status changes on endpoints and setup packet on
> endpoint 0.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_EVENTHANDLER) (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  OUT EFI_USBFN_MESSAGE           *Message,
> > +  IN OUT UINTN                    *PayloadSize,
> > +  OUT EFI_USBFN_MESSAGE_PAYLOAD   *Payload
> > +  );
> > +
> > +/**
> > +  Primary function to handle transfer in either direction based on spe=
cified
> > +  direction and on the specified endpoint.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USBFN_IO_TRANSFER) (
> > +  IN EFI_USBFN_IO_PROTOCOL         *This,
> > +  IN UINT8                         EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION  Direction,
> > +  IN OUT UINTN                     *BufferSize,
> > +  IN OUT VOID                      *Buffer
> > +  );
> > +
> > +/**
> > +  This function supplies power to the USB controller if needed,
> > +  initialize hardware and internal data structures, and then return.
> > +
> > +  The port must not be activated by this function.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_START_CONTROLLER) (
> > +    IN EFI_USBFN_IO_PROTOCOL    *This
> > +    );
> > +
> > +/**
> > +  This function disables the hardware device by resetting the run/stop=
 bit
> and
> > +  power off the USB controller if needed.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_STOP_CONTROLLER) (
> > +    IN EFI_USBFN_IO_PROTOCOL    *This
> > +    );
> > +
> > +/**
> > +  This function sets the configuration policy for the specified non-co=
ntrol
> endpoint.
> > +
> > +  Refer to the description for calling restrictions.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_SET_ENDPOINT_POLICY) (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> > +  IN EFI_USBFN_POLICY_TYPE        PolicyType,
> > +  IN UINTN                        BufferSize,
> > +  IN VOID                         *Buffer
> > +  );
> > +
> > +/**
> > +  This function retrieves the configuration policy for the specified n=
on-
> control endpoint.
> > +
> > +  There are no associated calling restrictions for this function.
> > +**/
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI * EFI_USBFN_IO_GET_ENDPOINT_POLICY) (
> > +  IN EFI_USBFN_IO_PROTOCOL        *This,
> > +  IN UINT8                        EndpointIndex,
> > +  IN EFI_USBFN_ENDPOINT_DIRECTION Direction,
> > +  IN EFI_USBFN_POLICY_TYPE        PolicyType,
> > +  IN OUT UINTN                    *BufferSize,
> > +  IN OUT VOID                     *Buffer
> > +  );
> > +
> > +
> > +struct _EFI_USBFN_IO_PROTOCOL {
> > +  UINT32                                      Revision;
> > +  EFI_USBFN_IO_DETECT_PORT                    DetectPort;
> > +  EFI_USBFN_IO_CONFIGURE_ENABLE_ENDPOINTS
> ConfigureEnableEndpoints;
> > +  EFI_USBFN_IO_GET_ENDPOINT_MAXPACKET_SIZE
> GetEndpointMaxPacketSize;
> > +  EFI_USBFN_IO_GET_DEVICE_INFO                GetDeviceInfo;
> > +  EFI_USBFN_IO_GET_VENDOR_ID_PRODUCT_ID
> GetVendorIdProductId;
> > +  EFI_USBFN_IO_ABORT_TRANSFER                 AbortTransfer;
> > +  EFI_USBFN_IO_GET_ENDPOINT_STALL_STATE       GetEndpointStallState;
> > +  EFI_USBFN_IO_SET_ENDPOINT_STALL_STATE       SetEndpointStallState;
> > +  EFI_USBFN_IO_EVENTHANDLER                   EventHandler;
> > +  EFI_USBFN_IO_TRANSFER                       Transfer;
> > +  EFI_USBFN_IO_GET_MAXTRANSFER_SIZE           GetMaxTransferSize;
> > +  EFI_USBFN_IO_ALLOCATE_TRANSFER_BUFFER       AllocateTransferBuffer;
> > +  EFI_USBFN_IO_FREE_TRANSFER_BUFFER           FreeTransferBuffer;
> > +  //
> > +  // Valid for version EFI_USBFN_IO_PROTOCOL_REVISION2 and above
> > +  //
> > +  EFI_USBFN_IO_START_CONTROLLER               StartController;
> > +  EFI_USBFN_IO_STOP_CONTROLLER                StopController;
> > +  EFI_USBFN_IO_SET_ENDPOINT_POLICY            SetEndpointPolicy;
> > +  EFI_USBFN_IO_GET_ENDPOINT_POLICY            GetEndpointPolicy;
> > +};
> > +
> > +
> > +extern EFI_GUID gEfiUsbFnIoProtocolGuid;
> > +#endif
> > +
> > diff --git
> a/Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h
> b/Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h
> > new file mode 100644
> > index 0000000000..c301fa00d3
> > --- /dev/null
> > +++
> b/Silicon/Synopsys/DesignWare/Include/Protocol/UsbDeviceModeProtocol.h
> > @@ -0,0 +1,104 @@
> > +/** @file
> > +  Copyright (c) 1999 - 2017, Intel Corporation. All rights reserved.<B=
R>
> > +
> > +  This program and the accompanying materials
> > +  are licensed and made available under the terms and conditions of th=
e
> BSD License
> > +  which accompanies this distribution.  The full text of the license m=
ay be
> found at
> > +  http://opensource.org/licenses/bsd-license.php.
> > +
> > +  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS"
> BASIS,
> > +  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER
> EXPRESS OR IMPLIED.
> > +
> > +**/
> > +
> > +
> > +#ifndef _USB_DEVICE_MODE_PROTOCOL_H_
> > +#define _USB_DEVICE_MODE_PROTOCOL_H_
> > +
> > +#include <Library/UsbDeviceLib.h>
> > +
> > +///
> > +/// UsbDeviceMode Protocol GUID.
> > +///
> > +#define EFI_USB_DEVICE_MODE_PROTOCOL_GUID \
> > +  {0xC9923F7E, 0x1746, 0x4802, { 0x86, 0x2e, 0x1, 0x1c, 0x2c, 0x2d, 0x=
9d,
> 0x86 } }
> > +
> > +typedef struct _EFI_USB_DEVICE_MODE_PROTOCOL
> EFI_USB_DEVICE_MODE_PROTOCOL;
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DEVICE_MODE_INIT_XDCI) (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DEVICE_MODE_CONNECT) (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DEVICE_MODE_DISCONNECT) (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DEVICE_EP_TX_DATA) (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> > +  IN USB_DEVICE_IO_REQ                          *IoRequest
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DEVICE_EP_RX_DATA) (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> > +  IN USB_DEVICE_IO_REQ                          *IoRequest
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DEVICE_MODE_BIND) (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> > +  IN USB_DEVICE_OBJ                             *UsbdDevObj
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DEVICE_MODE_UNBIND) (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DEVICE_MODE_STOP) (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This
> > +  );
> > +
> > +typedef
> > +EFI_STATUS
> > +(EFIAPI *EFI_USB_DEVICE_MODE_RUN) (
> > +  IN EFI_USB_DEVICE_MODE_PROTOCOL               *This,
> > +  IN UINT32                                     TimeoutMs
> > +  );
> > +
> > +///
> > +/// Usb Device Mode Protocol Structure.
> > +///
> > +struct _EFI_USB_DEVICE_MODE_PROTOCOL {
> > +  EFI_USB_DEVICE_MODE_INIT_XDCI            InitXdci;
> > +  EFI_USB_DEVICE_MODE_CONNECT              Connect;
> > +  EFI_USB_DEVICE_MODE_DISCONNECT           DisConnect;
> > +  EFI_USB_DEVICE_EP_TX_DATA                EpTxData;
> > +  EFI_USB_DEVICE_EP_RX_DATA                EpRxData;
> > +  EFI_USB_DEVICE_MODE_BIND                 Bind;
> > +  EFI_USB_DEVICE_MODE_UNBIND               UnBind;
> > +  EFI_USB_DEVICE_MODE_RUN                  Run;
> > +  EFI_USB_DEVICE_MODE_STOP                 Stop;
> > +};
> > +
> > +extern EFI_GUID gEfiUsbDeviceModeProtocolGuid;
> > +
> > +#endif
> > +
> > --
> > 2.27.0.windows.1
> >