usb_plat/usb_shai_api/inc/usb_peripheral_shai.h
branchRCL_3
changeset 15 f92a4f87e424
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/usb_plat/usb_shai_api/inc/usb_peripheral_shai.h	Tue Aug 31 17:01:47 2010 +0300
@@ -0,0 +1,1181 @@
+/*
+* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of "Eclipse Public License v1.0"
+* which accompanies this distribution, and is available
+* at the URL "http://www.eclipse.org/legal/epl-v10.html".
+*
+* Initial Contributors:
+* Nokia Corporation - initial contribution.
+*
+* Contributors:
+*
+* Description: 
+*
+*/
+
+/** @file
+    
+    @brief USB Peripheral SHAI header
+    
+    @version 0.3.0
+ 
+    Abstract interface for USB Peripheral Controller.
+ 
+    @publishedDeviceAbstraction
+  
+ */
+ 
+#ifndef USB_PERIPHERAL_SHAI_H
+#define USB_PERIPHERAL_SHAI_H
+
+// System includes
+#include <kern_priv.h>
+#include <usb/usb_common_shai.h> // Common types shared between the USB SHAIs
+#include <usb/usb_peripheral_shai_shared.h> // Common types shared with upper layers
+
+/**
+ * This macro specifies the version of the USB Peripheral SHAI header
+ * in binary coded decimal format. This allows the PSL layer to
+ * confirm a certain definition is available, if needed. This can for
+ * example make it possible for a new PSL to support compilation in an
+ * older environment with old USB SHAI version that is missing some
+ * new definitions.
+ */
+#define USB_PERIPHERAL_SHAI_VERSION 0x030
+
+// The namespace is documented in file usb_common_shai.h, so it is not
+// repeated here
+namespace UsbShai
+    {
+    /** 
+     * Masks defined for TUsbPeripheralEndpointCaps.iSizes.
+     *
+     * Zero means this endpoint is not available (= no size).
+     */
+    const TUint KUsbEpNotAvailable = 0x00000000;
+    
+    /**    
+     * Max packet size is continuously variable up to some size specified.
+     * (Interrupt and Isochronous endpoints only.)
+     */
+    const TUint KUsbEpSizeCont     = 0x00000001;
+    
+    /** Max packet size 8 bytes is supported */
+    const TUint KUsbEpSize8        = 0x00000008;
+    
+    /** Max packet size 16 bytes is supported */
+    const TUint KUsbEpSize16       = 0x00000010;
+    
+    /** Max packet size 32 bytes is supported */
+    const TUint KUsbEpSize32       = 0x00000020;
+    
+    /** Max packet size 64 bytes is supported */
+    const TUint KUsbEpSize64       = 0x00000040;
+    
+    /** Max packet size 128 bytes is supported */
+    const TUint KUsbEpSize128      = 0x00000080;
+    
+    /** Max packet size 256 bytes is supported */
+    const TUint KUsbEpSize256      = 0x00000100;
+    
+    /** Max packet size 512 bytes is supported */
+    const TUint KUsbEpSize512      = 0x00000200;
+    
+    /** Max packet size 1023 bytes is supported */
+    const TUint KUsbEpSize1023     = 0x00000400;
+    
+    /** Max packet size 1024 bytes is supported */
+    const TUint KUsbEpSize1024     = 0x00000800;
+    
+    /** 
+     * Test Mode Selectors (Set/ClearFeature)
+     * Refer to usb specification 2.0, Chapter 9.4.9, table 9-7
+     */
+    enum TUsbTestModeSelector
+        {
+        EUsbTestSelector_Test_J = 0x01,
+        EUsbTestSelector_Test_K,
+        EUsbTestSelector_Test_SE0_NAK,
+        EUsbTestSelector_Test_Packet,
+        EUsbTestSelector_Test_Force_Enable
+        };
+    
+    /** 
+     * Transfer direction of a USB transfer request.
+     * @see TUsbPeripheralRequest
+     */
+    enum TTransferDirection 
+        {
+        EControllerNone,        
+        EControllerRead,
+        EControllerWrite
+        };
+
+    /** 
+     * Enumeration listing the event codes that are passed from PSL to
+     * PIL to indicate peripheral events
+     */
+    enum TUsbPeripheralEvent
+        {
+        /** The USB Suspend bus state has been detected.
+         *
+         * When the Peripheral Controller PSL is part of an
+         * OTG-capable port, the PSL shall report this event also when
+         * operating as the A-peripheral, in which case this final
+         * suspend event starts the HNP role switch back to A-host.
+         */
+        EUsbEventSuspend,
+        
+        /** USB Resume signaling has been detected. */
+        EUsbEventResume,
+        
+        /** A USB Reset condition has been detected. */
+        EUsbEventReset,
+        
+        /**
+         * VBUS level has risen above the B-session valid threshold. This
+         * is only relevant for a stand-alone peripheral controllers
+         * (those not associated with an OTG port). For an OTG port, the
+         * VBUS state is reported to PIL layer by the OTG Controller PSL.
+         */
+        EUsbEventVbusRisen,
+        
+        /**
+         * VBUS level has fallen below the B-session valid threshold. This
+         * is only relevant for a stand-alone peripheral controllers
+         * (those not associated with an OTG port). For an OTG port, the
+         * VBUS state is reported to PIL layer by the OTG Controller PSL.
+         */
+        EUsbEventVbusFallen
+        };   
+
+    typedef TUint32 TUsbPeripheralPacketArray;
+
+    /** 
+     * @brief  A USB transfer request.
+     * 
+     * This class will be constructed in PIL or upper layer, and be
+     * passed down to PSL. After the request was done, PSL layer will
+     * modify corresponding members (like data length, packet info
+     * etc.) and re-pass it back to PIL via interface
+     * MUsbPeripheralPilCallbackIf::EndpointRequestComplete().
+     * 
+     */
+    NONSHARABLE_CLASS(TUsbPeripheralRequest)
+        {
+    public:    
+        /**
+         * This class doesn't need a destructor because it has nothing to be
+         * freed, closed, destroyed. It 'owns' nothing.
+         */
+        IMPORT_C TUsbPeripheralRequest(TInt aRealEpNum);
+        
+    public:
+        /** The 'real' endpoint number this request to be bind to. */
+        TInt iRealEpNum;
+        
+        /** 
+         * Start address of this buffer. Filled-in by PIL.
+         *
+         * PSL needs to put received data in this buffer if it's a read request.
+         * PSL needs to get data from this buffer if it is a write request.
+         */
+        TUint8* iBufferStart;
+        
+        /** Physical address of buffer start (used for DMA). */
+        TUintPtr iBufferAddr;
+        
+        /** Length in bytes to be read/write. Filled-in by PIL. */
+        TInt iLength;
+
+        /** 
+         * Number of bytes transmitted (if it is a write);
+         * This value need to be updated by PSL. 
+         */
+        TUint iTxBytes;
+        
+        /** 
+         * Number of packets received (if it is a read); 
+         * This value need to be updated by PSL.
+         */
+        TUint iRxPackets;
+        
+        /** 
+         * This is a re-interpretation of what's inside in buffer iBufferStart.
+         * It is designed to be that the first packet always contains all the
+         * bytes received. So only the following scenario are possible:
+         *
+         * 1. Nothing, iRxPackets is zero, no packet received.
+         * 
+         * 2. 1 data Packet, iRxPackets is one.
+         *    iPacketIndex[0] is the offset against iBufferStart of where the
+         *    first byte of received data begins.
+         *    iPacketSize[0] is the size (in bytes) of the received data.
+         * 
+         * 3. 1 data packet, and one ZLP packet, iRxPackets is two.
+         *    iPacketIndex[0] is the offset against iBufferStart of where the
+         *    first byte of received data begins.
+         *    iPacketSize[0] is the size (in bytes) of the data packet.
+         *    
+         *    iPacketIndex[1] is the offset of the ZLP packet.
+         *    iPacketSize[1] is always set to zero since ZLP contains no data.
+         * 
+         */
+        TUsbPeripheralPacketArray* iPacketIndex;
+        
+        /** Array of packet sizes. Details see iPacketIndex */
+        TUsbPeripheralPacketArray* iPacketSize;
+        
+        /**
+         * Indicates the transfer direction of this request.
+         * Note, SetupEndpointRead/Write likewise functions already point out 
+         * the transfer direction, PSL may select to use it or not.
+         */
+        TTransferDirection iTransferDir;
+            
+        /** 
+         * For EControllerWrite (IN) transfers, it is used to Indicates that if 
+         * a Zero Length Packet is required at the end of this transfer.
+         * It will be set to ETrue if ZLP is needed, EFalse otherwise.
+         */
+        TBool iZlpReqd;
+        
+        /** 
+         * The error code upon completion of the request;
+         * PSL need to set it to KErrNone if no errors, Set it to other 
+         * system error codes otherwise.
+         */
+        TInt iError;
+        };
+        
+    /** 
+     * Peripheral controller capabilities.
+     * 
+     * PSL should use those values to fill in data member iControllerCaps in
+     * structure TPeripheralControllerProperties.
+     *
+     * @see TPeripheralControllerProperties.
+     */
+    typedef TUint32 TDeviceCaps;
+    
+    /**
+     * Indicates whether peripheral controller hardware supports USB High-speed.
+     * This capability affects driver functionality and behavior throughout the 
+     * implementation.
+     * 
+     * Set this bit if this peripheral controller supports USB High-speed;
+     * Clear it otherwise.
+     */
+    const TDeviceCaps KDevCapHighSpeed = 0x00000001;
+    
+    /** 
+     * Indicates whether the peripheral controller supports hardware acceleration
+     * for setting the device address, i.e. automatically setting device address
+     * on conclusion of status phase of SET_ADDRESS.
+     *
+     * If this capability is supported PIL will call SetDeviceAddress() before
+     * sending a zero byte status packet.
+     *
+     * Set this bit if hardware acceleration is supported.
+     * Clear it otherwise.
+     */
+    const TDeviceCaps KDevCapSetAddressAcceleration = 0x00000002;
+    
+    /**
+     * Indicates whether controller support Session Request Protocol.
+     *
+     * Set this bit if SRP is supported.
+     * Clear it otherwise.
+     */
+    const TDeviceCaps KDevCapSrpSupport = 0x00000004;
+    
+    /**
+     * Indicates whether controller support Host Negotiation Protocol.
+     *
+     * Set this bit if HNP is supported.
+     * Clear it otherwise.
+     */
+    const TDeviceCaps KDevCapHnpSupport = 0x00000008;
+    
+    /**
+     * Indicates whether controller support Remote wakeup
+     * 
+     * Set this bit if remote wakeup is supported.
+     * Clear it otherwise.
+     */
+    const TDeviceCaps KDevCapRemoteWakeupSupport = 0x00000010;
+
+    /** 
+     * Configuration data from PSL to PIL when register a controller through
+     * interface UsbPeripheralPil::RegisterPeripheralController().
+     */
+    NONSHARABLE_CLASS(TPeripheralControllerProperties)
+        {
+        public:
+        TPeripheralControllerProperties();
+        
+        public: // Data
+        /**
+         * A bitmap used to Indicates the capabilities of this controller.
+         * PSL should set the corresponding bit to '1' if one capability is
+         * supported by this controller.
+         */
+        TDeviceCaps iControllerCaps;
+
+        /**
+         * Pointer to a DFC queue that will be used for DFCs of this controller.
+         *
+         * A stand-alone (one not associated with an OTG-port) peripheral PSL 
+         * implementation must supply a pointer to a dedicated DFC queue that 
+         * has been created for this controller. Both the PSL itself and the PIL
+         * layer must queue their DFCs for this controller in this DFC queue to
+         * ensure the code is running in the same context.
+         *
+         * A peripheral PSL that is part of an OTG port will be registered by 
+         * the OTG PSL. In this case, the DFC queue supplied here must be the 
+         * same DFC queue as the one supplied in the properties of the OTG 
+         * Controller.
+         */
+        TDfcQue* iDfcQueue;
+        
+        /** 
+         * Describe the capabilities of all endpoint owned by this controller.
+         *
+         * Note that there might be gaps in the array, because the endpoints 
+         * must be numbered by using the 'real endpoint' numbering scheme.
+         *
+         * An example of end point capability array:
+         *
+         * @code
+         * static const TUsbPeripheralEndpointCaps DevEndpointCaps[KTotalEps] =
+         * {
+         * // MaxSize mask  ,   Types&Dir                      , High  ,Reserved
+         *                                                       speed?
+         * {KEp0MaxPktSzMask,(KUsbEpTypeControl | KUsbEpDirOut), ETrue ,0 , 0},
+         * {KEp0MaxPktSzMask,(KUsbEpTypeControl | KUsbEpDirIn ), ETrue ,0 , 0},
+         *      
+         * {KUsbEpNotAvailable,KUsbEpNotAvailable              , ETrue ,0 , 0},
+         *      
+         * {KBlkMaxPktSzMask,(KUsbEpTypeBulk | KUsbEpDirIn )   , ETrue ,0 , 0},
+         * {KBlkMaxPktSzMask,(KUsbEpTypeBulk | KUsbEpDirOut)   , ETrue ,0 , 0}
+         * };
+         * @endcode
+         *
+         * For endpoint maxinum packet size on USB2.0 High-speed, PSL should
+         * provide the overlaid values for both full speed and high speed, as 
+         * PIL can deduce the appropriate values for either speed.
+         *
+         */
+        const TUsbPeripheralEndpointCaps* iDeviceEndpointCaps;
+        
+        /** 
+         * Set by the PSL to indicate the number of entries in 
+         * iDeviceEndpointCaps array.
+         * Be noted that this value include the ones that are marked as 
+         * KUsbEpNotAvailable in table iDeviceEndpointCaps.
+         */
+        TInt iDeviceTotalEndpoints;
+        
+        /** 
+         * Maximum size of ep0 packet.
+         * @see USB spec 2.0, chapter 9, table 9-8.
+         */
+        TUint8  iMaxEp0Size;
+        
+        /** 
+         * Device Release number in binary-coded decimal.
+         * @see USB spec 2.0, chapter 9, table 9-8.
+         */
+        TUint16  iDeviceRelease;
+        };
+    
+    /** 
+     * Enumeration of stages within a control transfer
+     * 
+     * Possible stages defined in USB spec include:
+     * 1. setup -> status in
+     * 2. setup -> data in -> status out
+     * 3. setup -> data out -> status in
+     */
+    enum TControlStage
+        {
+        /** 
+         * Control transfer always start with a setup stage in which a setup
+         * packet is expected.         
+         */
+        EControlTransferStageSetup,
+        
+        /** The stage that a data packet is expected from be received */
+        EControlTransferStageDataOut,
+        
+        /**
+         * Status in stage can either following a Setup stage (if no data stage)
+         * or following a data out stage.
+         */
+        EControlTransferStageStatusIn,
+                
+        /** 
+         * Depends on the request type of a setup packet, a data in stage maybe 
+         * followed after a setup packet.
+         *
+         * Within this stage we expect upper/ourself to send some data to host.
+         */
+        EControlTransferStageDataIn,
+        
+        /**
+         * This is an optional stage, some controller will silently swallow
+         * Status out packet and not able to report it.
+         * PIL has consider this situation when control transfer state machine
+         * is introduced.
+         */
+        EControlTransferStageStatusOut,
+               
+        EControlTransferStageMax
+        };
+    
+    /** 
+     * Packet types in control transfers.
+     * 
+     * PSL need to tell PIL about the types of each packet it received.
+     * @see MUsbPeripheralPilCallbackIf::Ep0RequestComplete().
+     */
+    enum TControlPacketType
+        {
+        /** Indicates a setup packet */
+        EControlPacketTypeSetup,
+        
+        /** Indicates a data out packet */
+        EControlPacketTypeDataOut,
+        
+        /** 
+         * Indicates a status in packet.
+         * optional, PSL can select not to complete this packet.
+         */
+        EControlPacketTypeStatusIn,
+        
+        /** Indicates a data in packet */
+        EControlPacketTypeDataIn,
+        
+        /** 
+         * Indicates that a status out packet.
+         * optional, PSL can select not to complete this packet.
+         */
+        EControlPacketTypeStatusOut,
+
+        };
+    
+    /** 
+     * @brief Interface for PSL to do callback to PIL
+     * 
+     * This is the interface that a PSL need talk with PIL in order to:
+     * 1. Pass device event (reset/suspend/resume/vbus high/vbus low etc) to PIL.
+     * 2. Complete a read/write request to PIL.
+     * 3. Query control transfer stage from PIL.
+     * 3. Other functions like SetAdress/Handle HNP/Get remote wake up etc.
+     *
+     * This interface already been implemented and exported via library 
+     * usbperipheralpil.lib. PSL need to add this library as a dependency in 
+     * you PSL .mmp file.
+     *
+     * @lib  usbperipheralpil.lib
+     */
+    NONSHARABLE_CLASS(MUsbPeripheralPilCallbackIf)
+        {
+        public:
+        /** 
+         * Used to synchronize the Ep0 Stage machine between PSL and PIL.
+         * Accepts a SETUP packet and returns the next Ep0 Stage.
+         *
+         * This function will NOT lead anything to be changed at PIL, it is 
+         * functioning by parsing the supplied buffer only.
+         *
+         * @param aSetupBuf The SETUP packet received by PSL.
+         * @return The next Ep0 Stage at PIL if PIL receive this setup packet.
+         *
+         */
+        virtual TControlStage EnquireEp0NextStage(const TUint8* aSetupBuf) const = 0;
+        
+        /** 
+         * This function gets called by PSL upon completion of a pending 
+         * endpoint zero data transfer request.
+         *
+         * @param aRealEndpoint Either 0 for Ep0 OUT (= Read)
+         *                      or 1 for Ep0 IN (= Write).
+         * @param aCount The number of bytes received or transmitted.
+         * @param aError The error code of the completed transfer request. 
+         *               KErrNone if no error.
+         *               KErrCancel if transfer was cancelled.
+         *               KErrPrematureEnd if a premature end was encountered.
+         * @param aPktType The type of the packet that being completed.
+         * 
+         * @return KErrNone if no error during transfer completion processing;
+         *  KErrGeneral if request was a read & a Setup packet was received &
+         *  the recipient for that packet couldn't be found (invalid packet: Ep0
+         *  has been stalled); KErrNotFound if the request was a read & the 
+         *  recipient for that packet (Setup or data) _was_ * found - however no
+         *  read had been set up by that recipient (this case should be used by 
+         *  PSL to disable Ep0 interrupt at that point and give the upper layer 
+         *  software time to set up a new Ep0 read; once the 'missing' read was 
+         *  set up either Ep0DataReceiveProceed or Ep0ReadSetupPktProceed of 
+         *  MPeripheralControllerIf class  will be called by PIL).
+         */
+        virtual TInt Ep0RequestComplete(TInt aRealEndpoint, 
+                                        TInt aCount, 
+                                        TInt aError, 
+                                        TControlPacketType aPktType) = 0;
+    
+        /** 
+         * PSL call this function upon completion of a pending data transfer 
+         * request. This function isn't to be used for endpoint zero completions
+         * (use Ep0RequestComplete instead).
+         * 
+         * @param aCallback A pointer to a data transfer request callback 
+         *        structure which was previously passed to PSL in a 
+         *        SetupEndpointWrite() or SetupEndpointRead() call.
+         * 
+         */
+        virtual void EndpointRequestComplete(TUsbPeripheralRequest* aCallback) = 0;
+        
+        /**
+         * This function gets called by PSL upon detection of either of the 
+         * following events:
+         *   - USB Reset,
+         *   - USB Suspend event,
+         *   - USB Resume signaling,
+         *
+         * When the Peripheral Controller PSL is part of an
+         * OTG-capable port, the PSL shall report the above events
+         * also when operating as the A-peripheral, including
+         * reporting the final suspend event that starts the HNP role
+         * switch back to A-host.
+         *
+         * In addition to the events above, a stand-alone peripheral
+         * controller PSL (one not associated with an OTG port) is
+         * required to report the following events:
+         *   - VBUS rising above the session valid threshold
+         *   - VBUS falling below the session valid threshold
+         * 
+         * When the peripheral controller is part of an OTG port, the
+         * PIL layer receives VBUS notifications via the OTG stack,
+         * and the peripheral PSL is not expected to report them via
+         * this interface.
+         *
+         * When USB Battery Charging is supported on the
+         * peripheral-only port, there is a dependency between normal
+         * USB functionality and USB Battery Charging (see
+         * usb_charger_detection_shai.h and specifically the
+         * description of class MChargerDetectorIf). In this case it
+         * is the responsibility of the Peripheral Controller PSL to
+         * communicate with the Charger Detector PSL (which it may
+         * implement itself) with respect to VBUS events.
+         *
+         * When VBUS rises on the peripheral-only port that fully
+         * supports Battery Charging Specification Revision 1.1, the
+         * Charger Detector PSL and the Peripheral Controller PSL need
+         * to together guarantee that Data Contact Detect is completed
+         * and the port type detected before notifying VBUS rising.
+         * When the port type is known, the port type needs to be
+         * notified to the Charger Detector PSL Observer, followed by
+         * notifying a VBUS rising event to the Peripheral Controller
+         * PIL callback interface (via this function).
+         *
+         * Where Data Contact Detect is not supported, the VBUS rise
+         * event needs to be notified to the Peripheral Controller PIL
+         * callback interface (via this function) immediately and
+         * charger detection needs to proceed in parallel with the
+         * upper layers preparing the USB personality. This is
+         * necessary in order to ensure that we can fulfill the
+         * requirement to connect to the bus within a second, while
+         * still making as long as possible charger detection cycle to
+         * minimize the changes of false detections due to datalines
+         * not making contact yet.
+         *
+         * The Peripheral Controller PSL and the Charger Detector PSL
+         * need to together guarantee that the peripheral controller
+         * does not attempt to connect to the bus while charger
+         * detection is still on-going. When detection has been
+         * completed and upper layers have indicated readiness to
+         * connect to the bus (see MPeripheralControllerIf::PeripheralConnect(),
+         * the Peripheral Controller PSL must connect to the bus.
+         *
+         * @param aEvent An enum denoting the event that has occurred.
+         *        
+         * @return KErrArgument if the event is not recognized, KErrNone
+         *         otherwise
+         */
+        virtual TInt DeviceEventNotification(TUsbPeripheralEvent aEvent) = 0;
+        
+        /** 
+         * This function should be called by PSL once the peripheral 
+         * controller (and thus the USB device) is in the Address state.
+         */
+        virtual void MoveToAddressState() = 0;
+        
+        /** 
+         * This function should be called by PSL after reception of an Ep0
+         * SET_FEATURE request with a feature selector of either {b_hnp_enable,
+         * a_hnp_support, a_alt_hnp_support}, but ONLY when that Setup packet is
+         * not handed up to PIL (for instance because it is auto-decoded and
+         * 'swallowed' by the peripheral controller hardware).
+         * 
+         * @param aHnpState A bitmask indicating the present state of the three
+         * OTG feature selectors as follows:
+         * 
+         * bit.0 == a_alt_hnp_support
+         * bit.1 == a_hnp_support
+         * bit.2 == b_hnp_enable
+         *
+         * @see TUsbHnpCaps
+         * 
+         */
+        virtual void HandleHnpRequest(TInt aHnpState) = 0;       
+        
+        /**
+         * Returns the current USB device state.
+         * 
+         * 'USB device state' here refers to the device states as defined 
+         * in chapter 9 of the USB specification.
+         * 
+         * @return The current USB device state, or EUsbPeripheralStateUndefined
+         *         if peripheral stack is disabled.
+         *
+         */
+        virtual TUsbPeripheralState DeviceStatus() const = 0;
+        
+        };
+    
+    /** 
+     * MPeripheralControllerIf
+     * @brief Abstract class for USB peripheral Chipset API.
+     * @version   0.2.
+     *
+     * PSL driver need to implement all those virtual functions in this class.
+     *    
+     * Four Steps to create a vendor specific usb peripheral PDD.
+     *
+     *    Step 1: Derive a new class from MUsbPeripheralControllerIf and 
+     *            implement all interfaces defined. 
+     *              
+     *    Step 2: Create a new instance (we call it inst_of_psl) of the new class.
+     *            Prepare the configuration data defined by structure
+     *            TUsbPeripheralControllerProps (let's call it cfg_data )
+     *
+     *    Step 3: Call UsbPeripheralPil::RegisterPeripheralController(inst_of_psl,cfg_data).
+     *                        
+     *    Step 4: Member function SetPilCallbackInterface() will be called. 
+     *            An instance of MUsbPeripheralPilCallbackIf will be passed to 
+     *            PSL via this call. Record it since PSL need to reuse it later 
+     *            for any PIL functionality callback.
+     *            
+     *    That's all.
+     *    
+     *    dynamic view of PDD creation.
+     *            PIL will be compiled and linked alone.
+     *            PSL will be compiled alone and linked against a new lib named
+     *            usbperipheralpil.lib.
+     *
+     *    For PSL vendors, the following stuff are provided:
+     *            usb_peripheral_shai.h & usb_peripheral_shai_shared.h which is 
+     *            used for PSL to implement against.
+     *            usbperipheralpil.lib which is used for PSL to link against.
+     *
+     */
+    NONSHARABLE_CLASS(MPeripheralControllerIf)
+        {
+        public: 
+        /** 
+         * This function will be called once and only once by PIL when a PSL
+         * registered itself to PIL by calling 
+         * UsbPeripheralPil::RegisterPeripheralController().
+         *
+         * PSL is expected to store the callback interface pointer so that make 
+         * it possible to reporting events back to PIL layer.
+         *
+         * For stand-alone peripheral controllers (controllers not associated 
+         * with an OTG port),the Peripheral Controller PSL is required to report
+         * a EUsbEventVbusRisen event by calling MUsbPeripheralPilCallbackIf::
+         * DeviceEventNotification() if VBUS is already high at the point this 
+         * function is called.
+         *
+         * @param aPilCallbackIf A reference to PIL callback interface which
+                  a PSL must use to report events.
+         */
+        virtual void SetPilCallbackInterface(MUsbPeripheralPilCallbackIf& aPilCallbackIf) = 0;
+        
+        /**
+         * Sets endpoint zero's RX buffer.
+         * This buffer is maintains at PIL and always exists.
+         *
+         * @param aBuffer the buffer address
+         * @param aBufferLen the length of the buffer.
+         *        
+         */
+        virtual void SetEp0RxBuffer(TUint8* aBuffer, TInt aBufferLen) = 0;
+        
+        /** 
+         * Determines the speed mode that this controller is operating at.
+         *
+         * @return one of the speed mode defined by TSpeed.
+         * @see TSpeed.
+         */
+        virtual TSpeed DeviceOperatingSpeed() = 0;
+        
+        /** 
+         * Forces the peripheral controller into a non-idle state to perform a 
+         * USB remote wakeup operation.
+         *
+         * PIL layer will make sure the following preconditions are meet before
+         * calling this function:
+         *   1. we're already in suspended state for at least 5ms (Twtrsm).
+         *   2. remote wakeup had been enabled by host.
+         *
+         * @return KErrNone if successful, otherwise one of the system-wide 
+         *         error codes.
+         */
+        virtual TInt SignalRemoteWakeup() = 0;
+
+        /** 
+         * This function will be called by PIL upon decoding a SET_ADDRESS
+         * request. PIL will make sure that a status packet will be sent before
+         * calling this function as USB spec required if capability of 
+         * KDevCapSetAddressAcceleration is not support by hardware; Otherwise
+         * SetAddress call will go ahead of status packet.
+         * @see KDevCapSetAddressAcceleration
+         *
+         * @param aAddress A valid USB device address that was received with the
+         *        SET_ADDRESS request.
+         *
+         * @return KErrNone if address was set successfully or if controller's 
+         *         address cannot be set manually. otherwise one of the system-
+         *         wide error codes.
+         */
+        virtual TInt SetDeviceAddress(TInt aAddress) = 0;
+        
+        /** 
+         * Configures (enables) an endpoint (incl. Ep0) for data transmission or
+         * reception.
+         *
+         * @param aRealEndpoint The number of the endpoint to be configured.
+         * @param aEndpointInfo A properly filled-in endpoint info structure.
+         *
+         * @return KErrNone if endpoint successfully configured; KErrArgument if
+         *         endpoint number or endpoint info invalid; otherwise one of 
+         *         the system-wide error codes.
+         */
+        virtual TInt ConfigureEndpoint(TInt aRealEndpoint, 
+                                     const TUsbPeripheralEndpointInfo& aEndpointInfo) = 0;
+        
+        /** 
+         * De-configures (disables) an endpoint (incl. Ep0).
+         *
+         * @param aRealEndpoint The number of the endpoint to be disabled.
+         *
+         * @return KErrNone if endpoint successfully de-configured; KErrArgument
+         *         if endpoint number invalid; otherwise one of the system-wide 
+         *         error codes.
+         */
+        virtual TInt DeConfigureEndpoint(TInt aRealEndpoint) = 0;
+        
+        /** 
+         * Queries the use of and endpoint resource.
+         *
+         * @param aRealEndpoint The number of the endpoint.
+         * @param aResource The endpoint resource to be queried.
+         *        they are one of the following currently:
+         *           KUsbEndpointInfoFeatureWord1_DMA.
+         *           KUsbEndpointInfoFeatureWord1_DoubleBuffering.
+         *
+         * @return ETrue if the specified resource is in use at the endpoint, 
+         *         EFalse if not.
+         */
+        virtual TBool QueryEndpointResource(TInt aRealEndpoint, TUint32 aResource) const = 0;
+        
+        /** 
+         * Sets up a read request on an endpoint (excl. Ep0) for data reception.
+         * 
+         * PIL will construct a read request as aCallback, and use this function
+         * to setup and indicate the readiness for reading data from end point.
+         * 
+         * PSL need to update related data member of aCallback and complete this
+         * request by calling EndpointRequestComplete() when request is done.
+         * 
+         * @see TUsbPeripheralRequest
+         *
+         * @param aRealEndpoint The number of the endpoint to be used.
+         * @param aCallback A properly filled-in (by PIL) request callback.
+         *
+         * @return KErrNone if read successfully set up; KErrArgument if endpoint
+         *         number is invalid. otherwise one of the system-wide error 
+         *         codes.
+         */
+        virtual TInt SetupEndpointRead(TInt aRealEndpoint, TUsbPeripheralRequest& aCallback) = 0;
+        
+        /** 
+         * Sets up a write request on an endpoint (excl. Ep0) for transmission.
+         *
+         * PIL will contruct a write request as aCallback, and use this function
+         * to pass down it to PSL.
+         * 
+         * PSL need to update related data member of aCallback and complete this
+         * request by calling EndpointRequestComplete() when data is transmitted
+         * or any error found.
+         * @see TUsbPeripheralRequest
+         *
+         * @param aRealEndpoint The number of the endpoint to be used.
+         * @param aCallback A properly filled-in request callback.
+         *
+         * @return KErrNone if write successfully set up; KErrArgument if 
+         *         endpoint number is invalid; otherwise one of the system-wide 
+         *         error codes.
+         */
+        virtual TInt SetupEndpointWrite(TInt aRealEndpoint, TUsbPeripheralRequest& aCallback) = 0;
+        
+        /** 
+         * Cancels a read request on an endpoint (excl. Ep0).
+         *
+         * Note that endpoint 0 read requests are never cancelled by PIL, so
+         * there is also no CancelEndpointZeroRead() function.
+         *
+         * @param aRealEndpoint The number of the endpoint to be used.
+         *
+         * @return KErrNone if read successfully cancelled; KErrArgument if 
+         *         endpoint number is invalid; otherwise one of the system-wide 
+         *         error codes.
+         */
+        virtual TInt CancelEndpointRead(TInt aRealEndpoint) = 0;
+        
+        /** 
+         * Cancels a write request on an endpoint (incl. Ep0).
+         *
+         * PIL calls this function also to cancel endpoint zero write requests.
+         *
+         * @param aRealEndpoint The number of the endpoint to be used.
+         *
+         * @return KErrNone if write successfully cancelled; KErrArgument if 
+         *         endpoint number is invalid; otherwise one of the system-wide 
+         *         error codes.
+         */
+        virtual TInt CancelEndpointWrite(TInt aRealEndpoint) = 0;
+        
+        /** 
+         * Same as SetupEndpointRead(), but for endpoint zero only.
+         *
+         * No callback structure is used here as reading to ep0 (host may at any
+         * time send a SETUP packet) must be ready even before upper application
+         * is ready. So, a buffer will be passed down to PSL by 
+         * MPeripheralControllerIf::SetEp0RxBuffer() during PIL construction,
+         * this will benefits the PSL to have a buffer always available for this
+         * purpose.
+         *
+         * PSL must complete this request by EndpointRequestComplete()
+         *
+         * @return KErrNone if read successfully set up; otherwise one of the 
+         *         system-wide error codes.
+         */
+        virtual TInt SetupEndpointZeroRead() = 0;
+        
+        /** 
+         * Same as SetupEndpointWrite(), but for endpoint zero only.
+         *
+         * No callback is used here as this function is only used by
+         * PIL layer only and no user side request exists for it.
+         *
+         * @param aBuffer This points to the beginning of the data to be sent.
+         * @param aLength The number of bytes to be sent.
+         * @param aZlpReqd ETrue if a ZLP is must be sent after the data.
+         *
+         * PSL must complete this request by EndpointRequestComplete()
+         *
+         * @return KErrNone if write successfully set up; otherwise one of the 
+         *         system-wide error codes.
+         */
+        virtual TInt SetupEndpointZeroWrite(const TUint8* aBuffer, 
+                                            TInt aLength, 
+                                            TBool aZlpReqd = EFalse) = 0;
+        
+        /** 
+         * Sets up on Ep0 for the transmission of a single zero-length packet.
+         *
+         * @return KErrNone if ZLP successfully set up; otherwise one of the 
+         *         system-wide error codes.
+         */
+        virtual TInt SendEp0ZeroByteStatusPacket() = 0;
+        
+        /** 
+         * Stalls an endpoint (incl. Ep0).
+         *
+         * Not applicable to Isochronous endpoints.
+         *
+         * @param aRealEndpoint The number of the endpoint to be stalled.
+         *
+         * @return KErrNone if endpoint successfully stalled; KErrArgument if 
+         *         endpoint number is invalid; otherwise one of the system-wide 
+         *         error codes.
+         */
+        virtual TInt StallEndpoint(TInt aRealEndpoint) = 0;
+        
+        /** 
+         * Clears the stall condition on an endpoint (incl. Ep0).
+         *
+         * Not applicable to Isochronous endpoints.
+         *
+         * @param aRealEndpoint The number of the endpoint to be stalled.
+         *
+         * @return KErrNone if endpoint successfully de-stalled; KErrArgument if
+         *         endpoint number invalid; otherwise one of the system-wide 
+         *         error codes.
+         */
+        virtual TInt ClearStallEndpoint(TInt aRealEndpoint) = 0;
+        
+        /**
+         * Resets the data toggle bit for an endpoint (incl. Ep0).
+         *
+         * Isochronous endpoints don't use data toggles.
+         *
+         * @param aRealEndpoint The number of the endpoint to be used.
+         *
+         * @return KErrNone if data toggle successfully reset; KErrArgument if 
+         *         endpoint number invalid; otherwise one of the system-wide 
+         *         error codes.
+         */
+        virtual TInt ResetDataToggle(TInt aRealEndpoint) = 0;
+        
+        /** 
+         * Returns the frame number of the last received SOF packet.
+         *
+         * @return The (11-bit) frame number of the last received SOF packet.
+         *
+         */
+        virtual TInt SynchFrameNumber() const = 0;
+        
+        /** 
+         * Stores the (11-bit) frame number that should be sent in response to
+         * the next SYNCH_FRAME request(s).
+         *
+         * @param aFrameNumber The (11-bit) frame number to be set
+         */
+        virtual void SetSynchFrameNumber(TInt aFrameNumber) = 0;
+        
+        /** 
+         * Starts peripheral controller.
+         *
+         * This initializes the device controller hardware before any other 
+         * operation can be performed. 
+         * Tasks to be carried out here might include:
+         *     - resetting the whole peripheral controller design
+         *     - enabling the peripheral controller's clock
+         *     - binding & enabling the peripheral controller (primary) interrupt
+         *     - write meaningful values to some general controller registers
+         *     - enabling the USB Reset interrupt
+         *     - enabling the peripheral controller proper (for instance by 
+         *       setting an Enable bit).
+         *
+         * This function is also used in an OTG environment when the
+         * peripheral stack becomes enabled and the controller needs
+         * to be started and enabled for peripheral use. If the HW
+         * platform shares resources such as clocks and power between
+         * the host and peripheral HW, it is probably easiest for the
+         * PSL to handle the role switch based on the
+         * MOtgControllerIf::SetControllerRole() call to the OTG
+         * Controller interface.
+         *
+         * @return KErrNone if the controller was successfully started;
+         *         otherwise one of the system-wide error codes.
+         *
+         * @see usb_otg_shai.h, MOtgControllerIf::SetControllerRole()
+         */
+        virtual TInt StartPeripheralController() = 0;
+    
+        /** 
+         * Stops the peripheral controller.
+         *
+         * This basically makes undone what happened in StartPeripheralController(). 
+         * Tasks to be carried out here might include:
+         * - disabling peripheral controller proper.
+         * - disabling the USB Reset interrupt.
+         * - disabling & unbinding the peripheral controller (primary) interrupt.
+         * - disabling the peripheral controller's clock.
+         *
+         * This function is also used in an OTG environment when the peripheral 
+         * stack becomes disabled and the peripheral hardware resources can be 
+         * released. If the hardware platform shares resources such as clocks 
+         * and power between the host and peripheral hardware, it is probably 
+         * easiest for the PSL to handle the role switch based on the
+         * MOtgControllerIf::SetControllerRole() call to the OTG Controller 
+         * interface.
+         *
+         * @return KErrNone if peripheral controller successfully stopped;
+         *         otherwise one of the system-wide error codes.
+         *
+         * @see usb_otg_shai.h, MOtgControllerIf::SetControllerRole()
+         */         
+        virtual TInt StopPeripheralController() = 0;
+    
+        /** 
+         * This function is used to indicate that upper layers are ready to 
+         * start operating as peripheral and want to connect to the USB bus
+         * if possible.
+         *
+         * Since this functionality is not part of the USB specification it
+         * has to be explicitly supported, either by the peripheral controller
+         * itself or by the hardware platform.
+         *
+         * This call merely reports the upper layer readiness to connect, and
+         * it is the responsiblity of the PSL to assess when all prerequisites
+         * for connection are satisfied and physically connect when they are.
+         * These prerequisites include:
+         *
+         *  1. Upper layer readiness has been indicated by calling 
+         *     PeripheralConnect().
+         *
+         *  2. The peripheral controller has been started and enabled
+         *     by StartPeripheralController().
+         *
+         * The connection readiness assessment responsibility is delegated to the
+         * PSL because the physical connection may sometimes be handled by a HW
+         * state machine, thus making the correct SW-controlled connection time
+         * HW-specific.
+         *
+         * @return KErrNone if peripheral controller successfully connected;
+         *         otherwise one of the system-wide error codes.
+         */
+        virtual TInt PeripheralConnect() = 0;
+    
+        /** 
+         * Called to indicate that upper layers no longer want to operate as the
+         * peripheral and we must disconnect from the USB bus.
+         *
+         * Since this functionality is not part of the USB specification it
+         * has to be explicitly supported, either by the peripheral controller
+         * itself or by the hardware platform.
+         *
+         * @return KErrNone if controller is successfully disconnected;
+         *         otherwise one of the system-wide error codes.
+         */
+        virtual TInt PeripheralDisconnect() = 0;       
+        
+        /**
+         * Implements anything peripheral controller might required by following
+         * bus resume signal.
+         *
+         * This function gets called by PIL after it has been notified (by
+         * PSL) about the Suspend condition.
+         */
+        virtual void Suspend() = 0;
+        
+        /**
+         * Implements anything peripheral controller might required by following
+         * bus resume signal.
+         *
+         * This function gets called by PIL after it has been notified (by
+         * PSL) about the Resume event.
+         */
+        virtual void Resume() = 0;
+        
+        /**          
+         * Implements anything peripheral controller might required by following
+         * bus resume signal.
+         *
+         * This function gets called by PIL after it has been notified (by
+         * PSL) about the Reset event.
+         */
+        virtual void Reset() = 0;
+        
+        /** 
+         * PIL call this function to signal PSL that it has finished processing
+         * a received Setup packet (on Ep0) and that PSL can now prepare 
+         * itself for the next Ep0 reception.
+         *
+         * The reason for having this function is that the situation where no 
+         * Ep0 read has been set up by user and thus a received Setup packet
+         * cannot immediately be delivered to user. Once user however 
+         * sets up an Ep0 read, PIL then completes the request and eventually 
+         * calls this function. We can implement some sort of flow-control by
+         * this way.
+         */
+        virtual void Ep0ReadSetupPktProceed() = 0;
+        
+        /** 
+         * PIL call this function to signal PSL that it has finished processing 
+         * a received Ep0 data packet and that PSL can now prepare itself for 
+         * the next Ep0 reception.
+         *
+         * The reason for having this function is that the situation where no 
+         * Ep0 read has been set up by user and thus a received Setup packet
+         * cannot immediately be delivered to user. Once user however 
+         * sets up an Ep0 read, PIL then completes the request and eventually 
+         * calls this function. We can implement some sort of flow-control by
+         * this way.
+         */
+        virtual void Ep0ReadDataPktProceed() = 0;
+        
+        /** 
+         * Puts controller into a specific test mode (during HS operation only).
+         *
+         * 9.4.9 Set Feature: "The transition to test mode must be complete no
+         * later than 3 ms after the completion of the status stage of the 
+         * request." (The status stage will have been completed immediately 
+         * before this function gets called.)
+         *
+         * @param aTestSelector The specific test mode selector.
+         *
+         * @return KErrNone if the specified test mode was entered successfully;
+         *         otherwise one of the system-wide error codes.
+         */
+        virtual TInt EnterTestMode(TUsbTestModeSelector aTestSelector) = 0;
+        };
+
+   
+    /**
+     * This static class provides the interface which PSL implementation shall 
+     * use to register itself to PIL layer.
+     */
+    NONSHARABLE_CLASS(UsbPeripheralPil)
+        {
+        public:
+        /**
+         * Registration function to be used by a stand-alone (non-OTG
+         * port) Peripheral Controller PSL to register itself to the
+         * PIL layer. Peripheral Controllers that are part of an
+         * OTG-port are registered by the OTG Controller PSL (see
+         * usb_otg_shai.h, function UsbOtgPil::RegisterOtgController).
+         *
+         * The intended usage is that each stand-alone Peripheral
+         * Controller PSL is a kernel extension that registers itself
+         * to the USB Peripheral PIL layer by making this call from
+         * their own kernel extension entry point function (or an
+         * equivalent code that runs during bootup).
+         *
+         * When the PSL makes this call, PIL layer will call 
+         * SetPilCallbackInterface() function of the supplied Peripheral 
+         * Controller interface to supply the PSL a reference to PIL 
+         * callback interface to be used for reporting peripheral events.
+         *
+         * @param aPeripheralControllerIf Reference to the Peripheral
+         *   Controller interface implemented by the registering PSL.
+         *
+         * @param aProperties Reference to an object describing the
+         *   static properties of the Peripheral Controller. PIL
+         *   layer requires that the supplied reference remains valid
+         *   indefinitely, as a Peripheral Controller cannot unregister.
+         *
+         * @lib usbperipheralpil.lib
+         */
+        IMPORT_C static void RegisterPeripheralController(MPeripheralControllerIf& aPeripheralControllerIf, 
+                                                      const TPeripheralControllerProperties& aProperties );
+    
+        private:
+        /**
+         *  No instance of this class need to be created
+         */
+        UsbPeripheralPil();
+        };
+    };
+
+#include <usb/usb_peripheral_shai.inl>
+    
+#endif // USB_PERIPHERAL_SHAI_H
+
+// End of File