diff -r d3e8e7d462dd -r f92a4f87e424 usb_plat/usb_shai_api/inc/usb_peripheral_shai.h --- /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 +#include // Common types shared between the USB SHAIs +#include // 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 + +#endif // USB_PERIPHERAL_SHAI_H + +// End of File