usb_plat/usb_shai_api/inc/usb_host_shai.h
author Dremov Kirill (Nokia-D-MSW/Tampere) <kirill.dremov@nokia.com>
Tue, 31 Aug 2010 17:01:47 +0300
branchRCL_3
changeset 15 f92a4f87e424
permissions -rw-r--r--
Revision: 201033 Kit: 201035

/*
* 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 Host SHAI header
    @version 0.2.0

    This header specifies the USB host SHAI.

    @publishedDeviceAbstraction
*/


#ifndef USB_HOST_SHAI_H
#define USB_HOST_SHAI_H

// System includes
#include <kern_priv.h>
#include <usb/usb_common_shai.h> // Common types shared between the USB SHAIs

/**
 * This macro specifies the version of the USB Host 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_HOST_SHAI_VERSION 0x020

// The namespace is documented in file usb_common_shai.h, so it is not
// repeated here
namespace UsbShai
    {
    // Forward declarations

    class MHostControllerIf;
    class MHostTransferCallbackIf;
    class MRootHubCallbackIf;
    class MRootHubIf;

    // Data types

    /**
     * An enumeration listing the host role electrical test modes
     * supported. These correspond to the test modes specified in
     * Section "6.4.1.1 Test Modes" of the "On-The-Go and Embedded
     * Host Supplement to the USB Revision 2.0 Specification" Revision
     * 2.0 (a.k.a. USB OTG 2.0).
     *
     * @see MHostControllerIf::EnterHostTestMode()
     */
    enum THostTestMode
        {
        /**
         * Drive SE0 until host controller is reset. The call returns
         * immediately after enabling the test mode.
         */
        ETestModeTestSE0NAK = 0,

        /**
         * Drive high-speed J until host controller is reset. The call
         * returns immediately after enabling the test mode.
         */
        ETestModeTestJ,

        /**
         * Drive high-speed K until host controller is reset. The call
         * returns immediately after enabling the test mode.
         */
        ETestModeTestK,

        /**
         * Send test packets until host controller is reset. The
         * format of the required test packet is specified in Section
         * "7.1.20 Test Mode Support" of the USB 2.0 specification.
         *
         * The call returns immediately after enabling the test
         * mode.
         */
        ETestModeTestPacket,

        /**
         * Suspend and resume the port with 15 second delays to allow
         * the operator to adjust test tool settings. The Host
         * Controller PSL must perform the following test steps:
         *
         * 1. Allow SOFs to continue for 15 seconds.
         *
         * 2. Suspend the port under test.
         *
         * 3. Wait for 15 seconds.
         *
         * 4. Resume the port under test.
         *
         * This test mode is synchronous, i.e. the call returns after
         * the test has been completed.
         */
        ETestModeHsHostPortSuspendResume,

        /**
         * Perform a single-step GetDescriptor(Device) transfer.  This
         * is called after the USB Host Stack has enumerated a device
         * with VID=0x1A0A and PID=0x0107. The Host Controller PSL
         * must perform the following test steps:
         *
         * 1. Allow SOFs to continue for 15 seconds.
         *
         * 2. Send a complete GetDescriptor(Device) transfer
         *
         * This test mode is synchronous, i.e. the call returns after
         * the test has been completed.
         */
        ETestModeSingleStepGetDeviceDescriptor,

        /**
         * Perform a single-step GetDescriptor(Device) transfer with a
         * delayed data phase. This is called after the USB Host Stack
         * has enumerated a device with VID=0x1A0A and PID=0x0108. The
         * Host Controller PSL must perform the following test steps:
         *
         * 1. Send the SETUP packet for GetDescriptor(Device). The
         *    device ACKs the packet as usual.
         *
         * 2. Allow SOFs to continue for 15 seconds.
         *
         * 3. Send the IN token for the data phase of
         *    GetDescriptor(Device). The device responds with
         *    the data.
         *
         * 4. Send the acknowledgement (zero-length OUT data) in
         *    response to the data.
         *
         * This test mode is synchronous, i.e. the call returns after
         * the test has been completed.
         */
        ETestModeSingleStepGetDeviceDescriptorData
        };


    // Class declaration

    /**
     * This class specifies a memory block that is used for USB
     * transfers. The memory pointers and the buffer length are filled
     * by the USB Host stack before issuing the transfer to the Host
     * Controller PSL.
     */
    NONSHARABLE_CLASS( TUsbMemoryBlock )
        {
        public:
        /**
         * Linear (virtual) start address of the memory buffer. This
         * address is always provided.
         */
        TLinAddr iLinAddr;

        /**
         * Physical start address of the memory buffer. This address
         * is always provided, but it is the responsibility of the
         * Host Controller PSL to guarantee that the memory is
         * physically contiguous, if contiguous memory is needed. The
         * PSL can guarantee this by implementing
         * MHostControllerIf::ChunkCreate() to allocate physically
         * contiguous memory.
         *
         * @see MHostControllerIf::ChunkCreate()
         */
        TPhysAddr iPhysAddr;

        /**
         * Pointer to an array of physical addresses each pointing to
         * one physical page of the memory block. This address is
         * always provided.
         *
         * The size of each page matches the size reported in
         * THostControllerProperties::iControllerPageSize by the Host
         * Controller PSL when it registered to the PIL.
         */
        TPhysAddr* iPhysPages;

        /** The length of the memory buffer in bytes */
        TUint iLength;
        };


    /**
     * This class specifies the enumerated types for different endpoint
     * configuration items and specifies the structure of the endpoint
     * configuration. Instances of this class are used to specify the
     * endpoint information when opening a pipe.
     *
     * @see MHostControllerIf::OpenPipe()
     */
    NONSHARABLE_CLASS( THostPipe )
        {
        public:
        // These are flag constants that specify the values that can
        // be bitwise OR'ed to the endpoint flags field iEndpointFlags
        // to indicate some boolean parameters of the endpoint

        /**
         * This flag specifies whether the targeted endpoint is behind
         * a hub that is performing transaction translation. This
         * occurs when the attached device is a low/full-speed device
         * attached to a high-speed hub.
         *
         * When this flag is set, the iHubAddr and iHubPort members
         * specify the hub address and the port to which the targeted
         * device is connected, and the iEndpointFlags flag
         * KHubHasMultipleTTs specifies whether the hub has been
         * configured to use multiple transaction translators.
         */
        static const TUint32 KHubTranslates = 0x00000001;

        /**
         * When the iEndpointFlags flag KHubTranslates is set, this
         * flag is set if the hub has multiple transaction
         * translators.
         */
        static const TUint32 KHubHasMultipleTTs = 0x00000002;

        public: // Data
        /**
         * The type of the endpoint (control, bulk, interrupt,
         * isochronous)
         */
        TEndpointType iType;

        /** Maximum packet size to be used on this endpoint */
        TUint iMaxPacketSize;

        /** Flags specifying some boolean parameters of the endpoint */
        TUint32 iEndpointFlags;

        /**
         * The speed (low, full, high) to use for this endpoint. This
         * may differ from the current speed of the local port if the
         * targeted device is a low-speed or full-speed device
         * connected to a high-speed hub.
         */
        TSpeed iSpeed;

        /**
         * The polling interval specified as number of frames or
         * microframes, depending on the speed. This is used for
         * interrupt and isochronous endpoints only.
         */
        TUint iPollingInterval;

        /**
         * The USB address of the remote device that we are
         * communicating with
         */
        TUint8 iRemoteAddr;

        /**
         * The remote endpoint number that we are communicating
         * with. This is the physical endpoint number in the USB 2.0
         * descriptor format, i.e. the most significant bit indicates
         * the direction (1 for IN, 0 for OUT), and the least
         * significant bits indicate the endpoint number.
         */
        TUint8 iRemoteEpNum;

        /**
         * For cases where the attached device is a low/full-speed
         * device attached to a high-speed hub that does the necessary
         * transaction translation, this member records the address of
         * the hub doing the translation.
         */
        TUint8 iHubAddr;

        /**
         * For cases where the attached device is a low/full-speed
         * device attached to a high-speed hub that does the necessary
         * transaction translation, this member records the number of
         * the port where the device is connected on the hub that does
         * the transaction translation.
         */
        TUint8 iHubPort;
        };


    /**
     * This class specifies the structure of the endpoint transfer
     * requests. The USB Host Stack passes the Host Controller PSL a
     * reference to an object of this class when setting up a new transfer
     * with MHostPipeIf::StartTransfer().
     */
    NONSHARABLE_CLASS( THostTransfer )
        {
        public:
        // These are public constants that specify the values that can
        // be bitwise OR'ed to the request flags field iRequestFlags
        // to indicate some boolean parameters of the transfer

        /**
         * When set, specifies that the transfer direction is IN,
         * i.e. the host is reading from the connected device. This is
         * needed for endpoint zero, which is bi-directional and
         * cannot implicitly know the direction of the transfer.
         *
         * This bit is set or cleared by the USB Host stack before
         * issuing a new transfer.
         */
        static const TUint32 KTransferDirIsIN = 0x00000001;

        /**
         * For OUT endpoint transfers, indicates whether the Host
         * Controller PSL is required to force a short packet at the
         * end of the transfer.
         *
         * When the bit is set, the Host Controller PSL must send a
         * ZLP (Zero-Length Packet) after the last packet of the
         * transfer, if and only if the last packet was a full packet,
         * i.e. had the same size as the maximum packet size for the
         * endpoint.
         *
         * This bit is set or cleared by the USB Host stack before
         * issuing a new transfer.
         */
        static const TUint32 KOutForceShortPacket = 0x00000002;

        /**
         * For IN endpoint transfers, indicates whether the transfer
         * was terminated with a ZLP (Zero-Length Packet).
         *
         * This bit is set by the Host Controller PSL before
         * completing the transfer if the transfer ended due to a
         * ZLP. Otherwise the bit is cleared by the Host Controller
         * PSL.
         */
        static const TUint32 KInZlpReceived = 0x00000004;

        /**
         * Enumeration specifying the packet status values to be used
         * for isochronous transfers.
         */
        enum TIsocPacketStatus
            {
            /** No error has occurred, transfer succesful */
            ESuccess = 0,

            /**
             * Data error has occurred in a data transfer, i.e. the
             * CRC did not match
             */
            EDataError,

            /** Overrun has occurred */
            EOverrun,

            /** Underrun has occurred */
            EUnderrun,
            };

        public: // Data
        /**
         * Pointer to the information of the pipe that this transfer
         * is being made on. This is the same information that was
         * used when opening the pipe that the transfer is being made
         * on.
         */
        THostPipe* iPipeInfo;

        /**
         * A pointer to the callback interface to be used for
         * indicating the completion of the transfer. This is set by
         * the USB Host Stack before making a transfer request.
         */
        MHostTransferCallbackIf* iTransferCbIf;

        /**
         * Request flags specifying some boolean parameters for the
         * transfer.
         */
        TUint32 iRequestFlags;

        /**
         * Memory block specifying the memory buffer used for the data
         * transfer. This is filled by the USB Host Stack before
         * making a transfer request.
         *
         * The memory block used here will be part of a chunk
         * previously created by a call to
         * MHostControllerIf::ChunkCreate() and the block will
         * fullfill the alignment requirements reported by the call to
         * MHostControllerIf::GetSizeAndAlignment().
         *
         * For control transfers, this specifies the buffer for the
         * data stage and has zero length and NULL pointers if the
         * transaction does not include a data stage.
         */
        TUsbMemoryBlock iDataBuffer;

        /**
         * For control transfers, this memory block specifies the
         * contents of the setup packet to be sent. For other than
         * control transfers, it is not used, and it has zero length
         * and NULL pointers.
         */
        TUsbMemoryBlock iSetupBuffer;

        /**
         * For isochronous transfers, this sets the number of
         * isochronous packets to send/receive. This is set by the
         * USB Host Stack before making a transfer request.
         */
        TInt iNumIsocPackets;

        /**
         * The number of bytes successfully transferred during the
         * data transfer. This is set by the Host Controller PSL
         * before completing the transfer.
         */
        TUint iTransferLength;

        /**
         * The status code of a completed transfer. This is set by the
         * Host Controller PSL before completing the request to the
         * transfer callback interface.
         */
        TInt iStatus;

        /**
         * For isochronous transfers, a pointer to an array of
         * iNumIsoPackets entries that specify the length of each
         * packet in the transfer. For OUT transfers, the array is
         * filled by the USB Host Stack and is read by the Host
         * Controller PSL to decide the length for each packet. For IN
         * transfers, the array is filled by the Host Controller PSL
         * to record to length of each received packet.
         */
        TUint16* iIsocPacketLengths;

        /**
         * For isochronous transfers, a pointer to an array of
         * iNumIsoPackets entries that specify the status of each
         * packet in the transfer. The array is filled by the Host
         * Controller PSL to record to success or failure of each
         * received packet.
         */
        TIsocPacketStatus* iIsocPacketStatuses;
        };


    /**
     * This class specifies the structure and contents of root hub
     * information that is filled by the adaptation to let the USB Host
     * Stack hub driver learn the capabilities of the root hub.
     *
     * @see MHostControllerIf::OpenRootHub
     */
    NONSHARABLE_CLASS( TRootHubInfo )
        {
        public: // Types and constants
        /**
         * A bitmask type used to indicate the static capabilities of
         * the root hub.
         */
        typedef TUint32 TRootHubCaps;

        /**
         * Capability bit to indicate whether the root hub supports
         * user-visible port indications such as LEDs.
         *
         * If the root hub supports this feature, the PSL shall set
         * the corresponding bit in iCapabilities (by bitwise OR'ing
         * this value). Otherwise the PSL shall clear the
         * corresponding bit in iCapabilities.
         */
        static const TRootHubCaps KRootHubCapPortIndication = 0x00000001;

        public: // Data
        /**
         * A bitmask specifying the static capabilities of this root
         * hub. The PSL fills this field by bitwise OR'ing the
         * TRootHubCaps capability bits corresponding to supported
         * features.
         */
        TRootHubCaps iCapabilities;

        /** Number of ports in this root hub */
        TUint iNumberOfPorts;

        /**
         * Maximum number of milliamps of current that this root hub
         * can supply to VBUS.
         */
        TUint iMaxSuppliedVbusCurrentMA;

        /**
         * Time taken by this root hub between starting to power up a
         * port and power being good on that port. This is expressed
         * in units of one millisecond.
         */
        TUint iTimePowerOnToPowerGoodMs;

        /**
         * The maximum speed supported by the root hub.
         */
        TSpeed iMaxSpeed;

        /** Pointer to the root hub interface */
        MRootHubIf* iRootHubIf;
        };


    /**
     * An interface class used by the USB Host Stack to perform data
     * transfers on a USB pipe. The Host Controller PSL must implement
     * this interface and provide a pointer to a pipe-specific
     * instance when the USB Host Stack creates the pipe by calling
     * MHostControllerIf::OpenPipe().
     *
     * The USB Host Stack will call the functions of this interface
     * from a DFC queued on the DFC queue supplied by the Host
     * Controller in THostControllerProperties::iControllerDfcQueue when the
     * Host Controller PSL registered.
     *
     * @see MHostControllerIf::OpenPipe()
     */
    NONSHARABLE_CLASS( MHostPipeIf )
        {
        public:
        /**
         * Close the USB pipe. This is called by the USB Host Stack
         * when the pipe is no longer used and the Host Controller PSL
         * may release any resources that were allocated for this
         * instance, including deleting the object itself.
         *
         * @param aPipeInfo Information describing the target endpoint
         *   of the pipe. This is the same information passed to
         *   MHostControllerIf::OpenPipe() when creating the
         *   pipe.
         *
         * @post After calling the function, the USB Host stack will
         *   consider the invoked instance to have been deleted and will
         *   no longer call any of the functions.
         */
        virtual void ClosePipeD( const THostPipe& aPipeInfo ) = 0;

        /**
         * Clear the data toggle bit of this pipe. This is used for
         * interrupt and bulk pipes when the host stack needs to
         * guarantee that the host controller will start the next
         * interrupt or bulk transfer with data toggle value zero.
         *
         * @param aPipeInfo Information describing the target endpoint
         *   of the pipe. This is the same information passed to
         *   MHostControllerIf::OpenPipe() when creating the
         *   pipe.
         */
        virtual void ClearDataToggle( const THostPipe& aPipeInfo ) = 0;

        /**
         * Start a transfer on this pipe.
         *
         * When the transfer is considered completed, the Host
         * Controller PSL must update the transfer information object
         * with the actual length and status of the transfer and then
         * complete it to the callback interface by calling
         * MHostTransferCallbackIf::CompleteTransfer(). The pointer to
         * the callback interface is provided in the member
         * THostTransfer::iTransferCbIf of the supplied aTransferInfo.
         *
         * The following rules shall be used by the Host Controller
         * PSL to assess the completeness of a transfer:
         *
         * 1. A read or write transfer on a control pipe is completed
         * when all the stages (two or three) of the control transfer
         * have been completed successfully, or when an error
         * occurs. It is the responsibility of the upper layers to
         * guarantee that there is sufficient buffer space for a read
         * request, so the buffer should not run out.
         *
         * 2. A read or write transfer on an isochronous pipe is
         * completed when the number of isochronous packets specified
         * in the member THostTransfer::iNumIsocPackets of the
         * supplied aTransferInfo have been sent or received
         * successfully, or if a fatal error occurs. It is the
         * responsibility of the upper layers to guarantee that there
         * is sufficient buffer space for a read request, so the
         * buffer should not run out.
         *
         * 3. A read transfer on a bulk or interrupt pipe is completed
         * when the buffer space is exhausted, a short packet (a
         * packet smaller than the maximum packet size of the pipe) is
         * received, or an error occurs.
         *
         * 4. A write transfer on a bulk or interrupt pipe is
         * completed when the requested buffer has been fully sent, or
         * an error occurs.
         *
         * @param aTransferInfo Information specifying the transfer to perform
         *
         * @return KErrNone if the transfer was started successfully,
         *   otherwise a system-wide error code
         */
        virtual TInt StartTransfer( THostTransfer& aTransferInfo ) = 0;

        /**
         * Cancel a transfer that was previously started with
         * StartTransfer(). The Host Controller PSL must flush any
         * pending data (either received or about to be sent) and
         * discard the transfer. The PSL must not attempt to complete
         * the canceled transfer by calling
         * MHostTransferCallbackIf::CompleteTransfer().
         *
         * @param aTransferInfo Information specifying the transfer to
         *   cancel. This is the same information passed to
         *   StartTransfer() when the transfer as started.
         */
        virtual void CancelTransfer( THostTransfer& aTransferInfo ) = 0;
        };


    /**
     * An interface class used by the USB Host Stack hub driver to
     * operate on the root hub ports. The Host Controller PSL must
     * implement this interface and provide a pointer when the USB
     * Host Stack opens the root hub by calling
     * MHostControllerIf::OpenRootHub().
     *
     * The USB Host Stack will call the functions of this interface
     * from a DFC queued on the DFC queue supplied by the Host
     * Controller in THostControllerProperties::iControllerDfcQueue
     * when the Host Controller PSL registered.
     *
     * @see MHostControllerIf::OpenRootHub()
     */
    NONSHARABLE_CLASS( MRootHubIf )
        {
        public:
        /**
         * Close the connection to the root hub. This is called by the
         * USB Host Stack when the Host Controller is about to be
         * deleted and the root hub is no longer used. The Host
         * Controller PSL may release any resources that were
         * allocated for this instance, including deleting the object
         * itself.
         *
         * @post After calling the function, the USB Host stack will
         *   consider the invoked instance to have been deleted and will
         *   no longer call any of the functions.
         */
        virtual void CloseRootHubD() = 0;

        /**
         * Enable the power supply, i.e. raise VBUS, on the specified
         * root hub port.
         *
         * If there are problems raising VBUS, the Host Controller PSL
         * must report a VBUS error by notifying the root hub callback
         * interface MRootHubCallbackIf of an over-current condition
         * on the port.
         *
         * @param aPort The number of the root hub port to operate
         *   on. For a root hub with N ports, the port numbers are in
         *   range [1..N].
         *
         * @see MRootHubCallbackIf::OverCurrentDetected()
         */
        virtual void PowerOnPort( TUint aPort ) = 0;

        /**
         * Stop session (A-device only).
         *
         * @param aPort The number of the root hub port to operate
         *   on. For a root hub with N ports, the port numbers are in
         *   range [1..N].
         */
        virtual void PowerOffPort( TUint aPort ) = 0;

        /**
         * Reset the specified root hub port. The total reset length
         * has to be at least 50 milliseconds and the reset signalling
         * must follow the requirements specified in USB 2.0
         * Specification Section 7.1.7.5 Reset Signaling.
         *
         * This function is synchronous and should return when the
         * reset signalling on the port has completed.
         *
         * @param aPort The number of the root hub port to operate
         *   on. For a root hub with N ports, the port numbers are in
         *   range [1..N].
         */
        virtual void ResetPort( TUint aPort ) = 0;

        /**
         * Place the specified root hub port to the USB suspend state
         * where it does not send SOF packets to the connected device.
         *
         * When all ports of the root hub have been suspended, the USB
         * Host Stack will suspend the entire host controller by
         * calling MHostControllerIf::SuspendController().
         *
         * When the root hub only has one port and SOFs cannot be
         * gated on the port without suspending the whole controller,
         * the Host Controller PSL should ignore the port-specific
         * suspend and resume calls and instead suspend/resume the
         * controller based on the controller-specific suspend and
         * resume calls in MHostControllerIf.
         *
         * @param aPort The number of the root hub port to operate
         *   on. For a root hub with N ports, the port numbers are in
         *   range [1..N].
         */
        virtual void SuspendPort( TUint aPort ) = 0;

        /**
         * Resume the specified root hub port from the USB suspend
         * state by driving the resume signalling on the port. The
         * signalling must last at least 20 milliseconds and follow
         * the requirements specified in USB 2.0 Specification Section
         * 7.1.7.7 Resume Signaling. After the resume signalling has
         * completed, the port must allow SOFs to be sent to the
         * connected device again.
         *
         * Before resuming the first port of a completely suspended
         * controller, the USB Host Stack will first resume the entire
         * host controller by calling
         * MHostControllerIf::ResumeController().
         *
         * When the root hub only has one port and SOFs cannot be
         * gated on the port without suspending the whole controller,
         * the Host Controller PSL should ignore the port-specific
         * suspend and resume calls and instead suspend/resume the
         * controller based on the controller-specific suspend and
         * resume calls in MHostControllerIf.
         *
         * @param aPort The number of the root hub port to operate
         *   on. For a root hub with N ports, the port numbers are in
         *   range [1..N].
         */
        virtual void ResumePort( TUint aPort ) = 0;

        /**
         * Query whether a device (a hub or a function) is currently
         * connected to the specified root hub port, and what speed it
         * is.
         *
         * @param aPort The number of the root hub port to check for a
         *   connected device on. For a root hub with N ports, the port
         *   numbers are in range [1..N].
         *
         * @param aSpeed Variable to fill with the speed, if connected
         *
         * @return ETrue if a device is currently connected and aSpeed
         *   has been set to the speed of the connected device. EFalse
         *   otherwise.
         */
        virtual TBool IsDeviceConnected( TUint   aPort,
                                         TSpeed& aSpeed ) = 0;
        };


    /**
     * An interface class that needs to be implemented by each Host
     * Controller PSL that registers to the USB stack.
     *
     * This interface is used by the USB Host Stack to do controller level
     * operations like suspending and resuming the host controller. It is
     * also used to open the root hub interface upon creating the SHAI
     * Host Controller, and to open USB pipes to connected devices.
     *
     * The USB Host Stack will call the functions of this interface
     * from a DFC queued on the DFC queue supplied by the Host
     * Controller in THostControllerProperties::iControllerDfcQueue when the
     * Host Controller PSL registered.
     */
    NONSHARABLE_CLASS( MHostControllerIf )
        {
        public:
        /**
         * Open a pipe to an endpoint on a remote USB peripheral.
         *
         * This function is called by the USB host stack when it wants
         * to communicate with a certain endpoint on a discovered USB
         * peripheral. The opened pipe is then used to read or write
         * from/to the peripheral until the pipe is later closed by
         * MHostPipeIf::ClosePipeD().
         *
         * @param aPipeInfo Information describing the target endpoint
         *   that the USB host stack wants to create a pipe to. The
         *   ownership of the info object remains with the USB host
         *   stack and the Host Controller PSL must not refer to data
         *   inside this after the function has returned. All
         *   MHostPipeIf functions that operate on the pipe will be
         *   passed the same pipe information so that the Host
         *   Controller PSL does not necessarily need to take a copy.
         *
         * @param aPipe Upon success, set by the Host Controller PSL
         *   to point to an instance that implements the SHAI pipe
         *   interface for the opened pipe. This interface will then be
         *   used by the USB Host Stack to perform transfers until the
         *   pipe is eventually closed by the USB Host Stack calling
         *   MHostPipeIf::ClosePipeD().
         *
         * @return KErrNone if successful, otherwise a system error code
         */
        virtual TInt OpenPipe( const THostPipe& aPipeInfo,
                               MHostPipeIf*&    aPipe ) = 0;

        /**
         * Open the root hub for the Host Controller.
         *
         * This is called by the USB Host Stack after creating the
         * Host Controller PSL to learn the capabilities of the
         * respective root hub and to establish the communication
         * between the hub driver in the USB Host Stack and the root
         * hub ports controlled by the Host Controller PSL.
         *
         * @param aRootHubInfo Reference to a root hub information
         *   object to be filled by the adaptation.
         *
         * @param aRootHubCbIf Reference to the callback interface of
         *   the root hub driver in the USB stack. The root hub
         *   implementation of the Host Controller PSL shall use this
         *   interface to report events of this root hub.
         *
         * @return KErrNone if successful, otherwise a system error code
         */
        virtual TInt OpenRootHub( TRootHubInfo&       aRootHubInfo,
                                  MRootHubCallbackIf& aRootHubCbIf ) = 0;

        /**
         * Start and enable the host controller. This is called prior
         * to powering up any port of the root hub to allow to Host
         * Controller PSL to perform any preparation that may be
         * necessary to activate the controller. This may include
         * actions such as enabling clocks or power to the host
         * controller HW.
         *
         * This function is also used in an OTG environment when the
         * host stack becomes enabled and the controller needs to be
         * started and enabled for host 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 host controller was successfully started,
         *         otherwise a system-wide error code.
         *
         * @see usb_otg_shai.h, MOtgControllerIf::SetControllerRole()
         */
        virtual TInt StartHostController() = 0;

        /**
         * Disable and stop the host controller. This is called after
         * powering down all ports of the root hub to allow to Host
         * Controller PSL to release any HW resources needed by the
         * controller. This may include actions such as disabling
         * clocks or power to the host controller HW.
         *
         * This function is also used in an OTG environment when the
         * host stack becomes disabled and the host HW resources can
         * be released. 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 host controller was successfully started,
         *         otherwise a system-wide error code.
         *
         * @see usb_otg_shai.h, MOtgControllerIf::SetControllerRole()
         */
        virtual TInt StopHostController() = 0;
        
        /**
         * Place the host controller to the USB suspend state where it
         * does not send SOF packets.
         */
        virtual void SuspendController() = 0;

        /**
         * Resume the host controller from the USB suspend state by
         * driving the resume signalling towards the root hub. The
         * signalling must last at least 20 milliseconds and follow
         * the requirements specified in USB 2.0 Specification Section
         * 7.1.7.7 Resume Signaling. After the resume signalling has
         * completed, the controller must allow SOFs to be sent to the
         * connected device again.
         */
        virtual void ResumeController() = 0;

        /**
         * Force the controller into a specific high-speed host test
         * mode. This function needs to be implemented only by Host
         * Controller PSLs for high-speed capable controllers. The
         * function will only be called when the controller is
         * operating in high-speed mode and a special test device has
         * been enumerated.
         *
         * When called, the Host Controller PSL shall synchronously
         * run the selected test as specified for each tests in the
         * documentation of THostTestMode.
         *
         * @param aTestMode Specifies the test mode to enter
         *
         * @param aDefaultPipe Information of the default pipe (the
         *   control pipe to endpoint zero) of the connected test
         *   device.
         *
         * @return KErrNone if the specified test mode was entered
         *   successfully, otherwise a system-wide error
         */
        virtual TInt EnterHostTestMode( THostTestMode    aTestMode,
                                        const THostPipe& aDefaultPipe ) = 0;

        /**
         * Get the size and alignment requirements for the Host
         * Controller. The reference parameters are both input and
         * output. Upon input, they describe the values requested by
         * the client, but they may be increased by this function if
         * the Host Controller requires additional memory or has some
         * alignment requirements.
         *
         * @param aType The type of the endpoint that the memory will
         *   be used for.
         *
         * @param aAlignment Output for required alignment in bytes
         *
         * @param aSize Input/output for buffer size (may be increased
         *   in this function)
         *
         * @param aMaxPackets Input/output for maximum number of
         *   packets in the transfer (may be increased in this function)
         *
         * @return KErrNone if successful, otherwise a system-wide
         *   error code
         */
        virtual TInt GetSizeAndAlignment( TEndpointType aType,
                                          TUint&        aAlignment,
                                          TInt&         aSize,
                                          TInt&         aMaxPackets ) = 0;

        /**
         * Creates a shared chunk and commits memory to it. The memory
         * allocated with this function will later be used when making
         * data transfers with this Host Controller (see
         * THostTransfer::iDataBuffer).
         *
         * The adaptation shall create a chunk by calling
         * Kern::ChunkCreate(), and then commit memory to it with one
         * of the Commit functions Kern::ChunkCommit(),
         * Kern::ChunkCommitContiguous(), and Kern::ChunkCommitPhysical().
         *
         * This task is delegated to the adaptation so that it can
         * allocate the correct type of memory. For example, if the
         * Host Controller requires the memory to be physically
         * contiguous, the implementation of this function must commit
         * contiguous memory to the chunk.
         *
         * @param aChunk Output handle to the chunk that was created.
         *   The adaptation must pass this value as the aChunk argument
         *   to the Kern::ChunkCreate() call.
         *
         * @param aOffset The offset (in bytes) from start of chunk,
         *   which indicates the start of the memory region to be
         *   committed. This will be a multiple of the MMU page
         *   size. The adaptation must pass this value as the aOffset
         *   argument to the used Commit call.
         *
         * @param aSize Number of bytes to commit. This will be a
         *   multiple of the MMU page size. The adaptation must pass
         *   this value as the aSize argument to the used Commit call.
         *
         * @param aInfo At input, specifies the chunk properties
         *   requested by the upper layers. The adaptation is allowed
         *   to change the attributes in aInfo.iMapAttr to match the
         *   requirements of the Host Controller. The adaptation must
         *   pass this value as the aInfo argument to the
         *   Kern::ChunkCreate() call. If the adaptation commits
         *   cached memory, it is the responsibility of the adaptation
         *   to deal with cache synchronization when making data
         *   transfers. If the adaptation needs special cleanup when
         *   the chunk is deleted, the adaptation can set a cleanup
         *   DFC pointer in aInfo.iDestroyedDfc.
         *
         * @param aPhysicalAddress On success, will be set to the
         *   physical address of the chunk as referenced by the HC
         *
         * @return KErrNone if successful, otherwise a system-wide
         *   error code
         *
         * @see System documentation for Kern::ChunkCreate(),
         *   Kern::ChunkCommit(), Kern::ChunkCommitContiguous(), and
         *   Kern::ChunkCommitPhysical()
         */
        virtual TInt ChunkCreate( DChunk*&          aChunk,
                                  TUint             aOffset,
                                  TUint             aSize,
                                  TChunkCreateInfo& aInfo,
                                  TPhysAddr&        aPhysicalAddress ) = 0;

        /**
         * Maps virtual to physical addresses. If the memory addresses
         * used by the host controller are different to the ones of
         * the main memory bus (e.g. due to memory mapping or use of
         * different address spaces), this method is used to translate
         * from kernel physical addresses to host controller physical
         * addresses.
         *
         * @param aPhysicalAddressList On entering, the list of
         *   physical addresses as used kernel-side, on successful
         *   return it contains the list of physical addresses as
         *   referenced by the HC
         *
         * @param aPhysicalAddressListSize Number of elements in
         *   aPhysicalAddressList
         *
         * @return KErrNone if successful, otherwise a system-wide
         *   error code
         */
        virtual TInt MapPhysicalAddresses( TPhysAddr*& aPhysicalAddressList, 
                                           TInt        aPhysicalAddressListSize ) = 0;
        };


    /**
     * An interface class implemented by the USB stack to allow the
     * host controller to report events to the root hub. This includes
     * notifications of a device being connected or disconnected on a
     * port, and other port conditions such as seeing a remote wakeup
     * signalling, an error on the port (such as babble from a
     * peripheral), or VBUS over-current.
     *
     * It is required that the Host Controller PSL calls these
     * functions in the context of the DFC queue supplied by the Host
     * Controller PSL in
     * THostControllerProperties::iControllerDfcQueue when the Host
     * Controller PSL registered.
     */
    NONSHARABLE_CLASS( MRootHubCallbackIf )
        {
        public:
        /**
         * A constant to specify an unknown port. In those port
         * notifications where this is explicitly specified to be OK,
         * this value is allowed to be used as the port number where
         * the real port number is unknown.
         */
        static const TUint KPortUnknown = 0;

        /**
         * Informs the root hub that a device (a hub or function) has
         * been connected to the specified root hub port.
         *
         * The Host Controller PSL uses this function to inform device
         * connection also during HNP role switch when the remote
         * device connects in peripheral role.
         *
         * @param aPort The number of the root hub port that the event
         *   occurred on. For a root hub with N ports, the port numbers
         *   are in range [1..N].
         */
        virtual void DeviceConnected( TUint aPort ) = 0;

        /**
         * Informs the root hub that a device (a hub or function) has
         * been disconnected from the specified root hub port.
         *
         * The Host Controller PSL uses this function to inform device
         * disconnection also during HNP role switch when the remote
         * peripheral disconnects to start the role switch.
         *
         * The Host Controller PSL must report device disconnection by
         * calling this function even if the port is currently
         * suspended. A disconnection that is part of an HNP role
         * switch will always occur in suspended state, and even a
         * normal peripheral may be physically disconnected at any
         * time.
         *
         * @param aPort The number of the root hub port that the event
         *   occurred on. For a root hub with N ports, the port numbers
         *   are in range [1..N].
         */
        virtual void DeviceDisconnected( TUint aPort ) = 0;

        /**
         * Informs the root hub that a device connected to the
         * specified root hub port has requested remote wakeup.
         *
         * @param aPort The number of the root hub port that the event
         *   occurred on. For a root hub with N ports, the port numbers
         *   are in range [1..N].
         */
        virtual void RemoteWakeupRequested( TUint aPort ) = 0;

        /**
         * Informs the root hub that a port error (such as babble) has
         * been detected on the specified root hub port. The
         * adaptation is expected to disable the port that has caused
         * the error condition.
         *
         * @param aPort The number of the root hub port that the event
         *   occurred on. For a root hub with N ports, the port numbers
         *   are in range [1..N].
         */
        virtual void PortErrorDetected( TUint aPort ) = 0;

        /**
         * Informs the root hub that an over-current condition has
         * been detected on the specified port.
         *
         * It may not always be possible to see which port out of
         * several caused the overcurrent. In this case the Host
         * Controller PSL may use the port number
         * MRootHubCallbackIf::KPortUnknown.
         *
         * @param aPort The number of the root hub port that the event
         *   occurred on, if known. For a root hub with N ports, the
         *   port numbers are in range [1..N]. If the exact port is
         *   not known, the Host Controller PSL root hub may report
         *   the port number MRootHubCallbackIf::KPortUnknown.
         */
        virtual void OverCurrentDetected( TUint aPort ) = 0;
        };


    /**
     * An interface class implemented by the USB Host Stack to allow the
     * host controller to complete transfers to the USB Host Stack.
     *
     * It is required that the Host Controller PSL calls these
     * functions in the context of the DFC queue supplied by the Host
     * Controller PSL in THostControllerProperties::iControllerDfcQueue when
     * the Host Controller PSL registered.
     */
    NONSHARABLE_CLASS( MHostTransferCallbackIf )
        {
        public:
        /**
         * Complete a transfer request that had been set up with
         * MHostPipeIf::StartTransfer().
         *
         * @param aTransferInfo The transfer information that
         *   identifies the transfer that has completed
         */
        virtual void CompleteTransfer( const THostTransfer& aTransferInfo ) = 0;
        };


    /**
     * This class specifies the static information provided by a Host
     * Controller PSL when registering to the USB Host stack.
     *
     * The PSL should prepare for the possibility that members may be
     * added to the end of this class in later SHAI versions if new
     * information is needed to support new features. The PSL should
     * not use this class as a direct member in an object that is not
     * allowed to grow in size due to binary compatibility reasons.
     *
     * @see UsbHostPil::RegisterHostController()
     */
    NONSHARABLE_CLASS( THostControllerProperties )
        {
        public: // Types and constants
        /**
         * A bitmask type used to indicate the static capabilities of
         * the Host Controller.
         */
        typedef TUint32 THostCaps;

        public:
        /**
         * Inline constructor for the Host Controller properties
         * object. This is inline rather than an exported function to
         * prevent a binary break in a case where an older PSL binary
         * might provide the constructor a smaller object due to the
         * PSL being compiled against an older version of the SHAI
         * header. When it's inline, the function is always in sync
         * with the object size.
         *
         * We slightly violate the coding conventions which say that
         * inline functions should be in their own file. We don't want
         * to double the number of USB SHAI headers just for sake of a
         * trivial constructor.
         */
        inline THostControllerProperties() :
            iCapabilities(0),
            iControllerDfcQueue(NULL),
            iControllerPageSize(0)
            {
            };

        public: // Data
        /**
         * A bitmask specifying the static capabilities of this Host
         * Controller. No capabilities are specified at the moment and
         * the PSL shall fill this field with a zero value.
         *
         * The field is added for sake of future proofing the binary
         * compatibility of the Host SHAI. By having a field reserved
         * for capability bits, we can later specify bits to indicate
         * added virtual functions or extension to this controller
         * properties structure. The PIL layer can then at runtime
         * confirm the existence of the new functions or fields and
         * safely support an older binary, if we choose to.
         */
        THostCaps iCapabilities;

        /**
         * Pointer to a DFC queue that will be used for DFCs of this
         * controller.
         *
         * A stand-alone (one not associated with an OTG-port) Host
         * Controller PSL 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 Host Controller 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* iControllerDfcQueue;

        /**
         * The page size used by this Host Controller. The host stack
         * will fill scatter-gather lists with pages of this size. If
         * the Host Controller does not have specific page
         * requirements itself, the registering Host Controller PSL
         * must supply here the CPU MMU page size that can be obtained
         * by the call Kern::RoundToPageSize(1).
         */
        TInt iControllerPageSize;
        };


    /**
     * A static class implemented by the USB Host PIL layer to allow
     * the host controller PSL to register to the PIL layer.
     */
    NONSHARABLE_CLASS( UsbHostPil )
        {
        public:
        /**
         * Registration function to be used by a stand-alone (non-OTG
         * port) Host Controller PSL to register itself to the PIL
         * layer. Host 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 Host Controller
         * PSL is a kernel extension that registers itself to the USB
         * Host PIL layer by making this call from their own kernel
         * extension entry point function (or an equivalent code that
         * runs during bootup).
         *
         * @param aHostControllerIf Reference to the Host Controller
         *   interface implemented by the registering PSL.
         *
         * @param aProperties Reference to an object describing the
         *   static properties of the Host Controller. The PIL layer
         *   requires that the supplied reference remains valid
         *   indefinitely, as a Host Controller cannot unregister.
         *
         * @lib usbotghostpil.lib
         */
        IMPORT_C static void RegisterHostController(
            MHostControllerIf&               aHostControllerIf,
            const THostControllerProperties& aProperties );
        };
    };

#endif // USB_HOST_SHAI_H

/* End of File */