usbdrv/peripheral/pdd/pil/src/ps_usbc.cpp
author hgs
Mon, 06 Sep 2010 11:27:08 +0800
changeset 48 21625e5de155
parent 33 089413cdde3c
child 59 bbdce6bffaad
permissions -rw-r--r--
201035_01
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
33
089413cdde3c 201028_02
hgs
parents:
diff changeset
     1
// Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
089413cdde3c 201028_02
hgs
parents:
diff changeset
     2
// All rights reserved.
089413cdde3c 201028_02
hgs
parents:
diff changeset
     3
// This component and the accompanying materials are made available
089413cdde3c 201028_02
hgs
parents:
diff changeset
     4
// under the terms of the License "Eclipse Public License v1.0"
089413cdde3c 201028_02
hgs
parents:
diff changeset
     5
// which accompanies this distribution, and is available
089413cdde3c 201028_02
hgs
parents:
diff changeset
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
089413cdde3c 201028_02
hgs
parents:
diff changeset
     7
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
     8
// Initial Contributors:
089413cdde3c 201028_02
hgs
parents:
diff changeset
     9
// Nokia Corporation - initial contribution.
089413cdde3c 201028_02
hgs
parents:
diff changeset
    10
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
    11
// Contributors:
089413cdde3c 201028_02
hgs
parents:
diff changeset
    12
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
    13
// Description:
089413cdde3c 201028_02
hgs
parents:
diff changeset
    14
// e32/drivers/usbcc/ps_usbc.cpp
089413cdde3c 201028_02
hgs
parents:
diff changeset
    15
// Platform independent layer (PIL) of the USB Device controller driver (PDD).
089413cdde3c 201028_02
hgs
parents:
diff changeset
    16
// Interface to the USB LDD.
089413cdde3c 201028_02
hgs
parents:
diff changeset
    17
// 
089413cdde3c 201028_02
hgs
parents:
diff changeset
    18
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
    19
089413cdde3c 201028_02
hgs
parents:
diff changeset
    20
/**
089413cdde3c 201028_02
hgs
parents:
diff changeset
    21
 @file ps_usbc.cpp
089413cdde3c 201028_02
hgs
parents:
diff changeset
    22
 @internalTechnology
089413cdde3c 201028_02
hgs
parents:
diff changeset
    23
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
    24
//#include <drivers/usbc.h>
089413cdde3c 201028_02
hgs
parents:
diff changeset
    25
#include <usb/usbc.h>
089413cdde3c 201028_02
hgs
parents:
diff changeset
    26
089413cdde3c 201028_02
hgs
parents:
diff changeset
    27
#include "controltransfersm.h"
089413cdde3c 201028_02
hgs
parents:
diff changeset
    28
/**
089413cdde3c 201028_02
hgs
parents:
diff changeset
    29
    TUsbcInterfaceSet and TUsbcInterface
089413cdde3c 201028_02
hgs
parents:
diff changeset
    30
    ====================================
089413cdde3c 201028_02
hgs
parents:
diff changeset
    31
089413cdde3c 201028_02
hgs
parents:
diff changeset
    32
    TUsbcInterfaceSet represents a 'USB Interface' and TUsbcInterface
089413cdde3c 201028_02
hgs
parents:
diff changeset
    33
    represents an 'Alternate Setting of a USB Interface'.
089413cdde3c 201028_02
hgs
parents:
diff changeset
    34
089413cdde3c 201028_02
hgs
parents:
diff changeset
    35
    Since every LDD governs exactly one interface, the above distinction is
089413cdde3c 201028_02
hgs
parents:
diff changeset
    36
    made only within the USB implementation. At the LDD API, there is/are
089413cdde3c 201028_02
hgs
parents:
diff changeset
    37
    simply one or more settings for this single interface, numbered from '0'
089413cdde3c 201028_02
hgs
parents:
diff changeset
    38
    (the default) to 'n', and specified by the parameter 'TInt aInterfaceNum'.
089413cdde3c 201028_02
hgs
parents:
diff changeset
    39
089413cdde3c 201028_02
hgs
parents:
diff changeset
    40
    Within the PDD implementation, for a TUsbcInterfaceSet number the parameter
089413cdde3c 201028_02
hgs
parents:
diff changeset
    41
    'TInt aIfcSet' is used (local variable ifcset); for a TUsbcInterface number
089413cdde3c 201028_02
hgs
parents:
diff changeset
    42
    the parameter 'TInt aIfc' is used (local variable ifc).
089413cdde3c 201028_02
hgs
parents:
diff changeset
    43
089413cdde3c 201028_02
hgs
parents:
diff changeset
    44
089413cdde3c 201028_02
hgs
parents:
diff changeset
    45
    iConfigs[0] and CurrentConfig()
089413cdde3c 201028_02
hgs
parents:
diff changeset
    46
    ===============================
089413cdde3c 201028_02
hgs
parents:
diff changeset
    47
089413cdde3c 201028_02
hgs
parents:
diff changeset
    48
    One problem with this file is that it always uses iConfigs[0] and not
089413cdde3c 201028_02
hgs
parents:
diff changeset
    49
    CurrentConfig(). This is mainly because the API to the LDD doesn't know
089413cdde3c 201028_02
hgs
parents:
diff changeset
    50
    about the concept of multiple configurations, and thus always assumes one
089413cdde3c 201028_02
hgs
parents:
diff changeset
    51
    single configuration (which is also always active: a further problem).
089413cdde3c 201028_02
hgs
parents:
diff changeset
    52
089413cdde3c 201028_02
hgs
parents:
diff changeset
    53
    In the file chapter9.cpp this issue doesn't exist, since there we always
089413cdde3c 201028_02
hgs
parents:
diff changeset
    54
    have to obey the USB protocol, and in this way will use the configuration
089413cdde3c 201028_02
hgs
parents:
diff changeset
    55
    which is selected by the host (which will then again currently always be
089413cdde3c 201028_02
hgs
parents:
diff changeset
    56
    iConfigs[0].)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    57
089413cdde3c 201028_02
hgs
parents:
diff changeset
    58
    iEp0ClientId
089413cdde3c 201028_02
hgs
parents:
diff changeset
    59
    ==================================
089413cdde3c 201028_02
hgs
parents:
diff changeset
    60
089413cdde3c 201028_02
hgs
parents:
diff changeset
    61
    The purpose of these two members of class DUsbClientController is the
089413cdde3c 201028_02
hgs
parents:
diff changeset
    62
    following.
089413cdde3c 201028_02
hgs
parents:
diff changeset
    63
089413cdde3c 201028_02
hgs
parents:
diff changeset
    64
    They are used only during Ep0 control transactions which have an OUT (Rx)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    65
    data stage. We cannot deduce from the received data itself to whom
089413cdde3c 201028_02
hgs
parents:
diff changeset
    66
    it is addressed (that's because of the shared nature of Ep0).
089413cdde3c 201028_02
hgs
parents:
diff changeset
    67
089413cdde3c 201028_02
hgs
parents:
diff changeset
    68
    In order to be able to tell whether received Ep0 data is to be processed by
089413cdde3c 201028_02
hgs
parents:
diff changeset
    69
    the PIL or a LDD, we use iEp0ClientId. iEp0ClientId is usually NULL, which
089413cdde3c 201028_02
hgs
parents:
diff changeset
    70
    means it is our data. However it is set to the client ID of an LDD in case
089413cdde3c 201028_02
hgs
parents:
diff changeset
    71
    2) above. That way we can subsequently hand over received data to the
089413cdde3c 201028_02
hgs
parents:
diff changeset
    72
    correct client LDD.
089413cdde3c 201028_02
hgs
parents:
diff changeset
    73
089413cdde3c 201028_02
hgs
parents:
diff changeset
    74
    iEp0DataReceived tracks the amount of data already received - it is used to
089413cdde3c 201028_02
hgs
parents:
diff changeset
    75
    determine the end of the DATA_OUT phase, irrespective of the owner of the
089413cdde3c 201028_02
hgs
parents:
diff changeset
    76
    data. The total amount that is to be received can be obtained via
089413cdde3c 201028_02
hgs
parents:
diff changeset
    77
    iConTransferMgr->PktParser().Length(). (iConTransferMgr->PktParser() holds in 
089413cdde3c 201028_02
hgs
parents:
diff changeset
    78
    that case the Setup packet of the current Control transfer.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    79
089413cdde3c 201028_02
hgs
parents:
diff changeset
    80
    iEp0ClientDataTransmitting is only set to TRUE if a client sets up an Ep0
089413cdde3c 201028_02
hgs
parents:
diff changeset
    81
    write. After that transmission has completed we use this value to decide
089413cdde3c 201028_02
hgs
parents:
diff changeset
    82
    whether we have to report the completion to a client or not. (If this
089413cdde3c 201028_02
hgs
parents:
diff changeset
    83
    variable is FALSE, we did set up the write and thus no client notification
089413cdde3c 201028_02
hgs
parents:
diff changeset
    84
    is necessary.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    85
089413cdde3c 201028_02
hgs
parents:
diff changeset
    86
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
    87
089413cdde3c 201028_02
hgs
parents:
diff changeset
    88
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
    89
// === Global and Local Variables ==================================================================
089413cdde3c 201028_02
hgs
parents:
diff changeset
    90
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
    91
089413cdde3c 201028_02
hgs
parents:
diff changeset
    92
// Currently we support at most 2 peripheral stack
089413cdde3c 201028_02
hgs
parents:
diff changeset
    93
GLDEF_D DUsbClientController* DUsbClientController::UsbClientController[] = {NULL, NULL};
089413cdde3c 201028_02
hgs
parents:
diff changeset
    94
089413cdde3c 201028_02
hgs
parents:
diff changeset
    95
static const TInt KUsbReconnectDelay   = 500;                // milliseconds
089413cdde3c 201028_02
hgs
parents:
diff changeset
    96
089413cdde3c 201028_02
hgs
parents:
diff changeset
    97
// Charger detector is the guy(PSL) who can detect the charger type and report 
089413cdde3c 201028_02
hgs
parents:
diff changeset
    98
// it via a charger type observer
089413cdde3c 201028_02
hgs
parents:
diff changeset
    99
static UsbShai::MChargerDetectorIf* gChargerDetector = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   100
089413cdde3c 201028_02
hgs
parents:
diff changeset
   101
// Charger observer is the guy who want to monitor the chager type event.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   102
static UsbShai::MChargerDetectorObserverIf* gChargerObsever = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   103
48
21625e5de155 201035_01
hgs
parents: 33
diff changeset
   104
static UsbShai::TChargerDetectorProperties gChargerDetectorProperties;
21625e5de155 201035_01
hgs
parents: 33
diff changeset
   105
33
089413cdde3c 201028_02
hgs
parents:
diff changeset
   106
089413cdde3c 201028_02
hgs
parents:
diff changeset
   107
// Those const variables are used to construct the default 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   108
// Usb descriptors, Upper layer can change them later.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   109
/** Default vendor ID to set in device descriptor */
089413cdde3c 201028_02
hgs
parents:
diff changeset
   110
static const TUint16 KUsbVendorId   = KUsbVendorId_Symbian;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   111
/** Default product ID to set in device descriptor */
089413cdde3c 201028_02
hgs
parents:
diff changeset
   112
static const TUint16 KUsbProductId  = 0x1111;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   113
/** Default language ID (US English) to set in device descriptor */
089413cdde3c 201028_02
hgs
parents:
diff changeset
   114
static const TUint16 KUsbLangId     = 0x0409;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   115
static const TUint8 KUsbNumberOfConfiguration = 0x01;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   116
/** Default manufacturer string */
089413cdde3c 201028_02
hgs
parents:
diff changeset
   117
static const wchar_t KStringManufacturer[] = L"Nokia Corporation";
089413cdde3c 201028_02
hgs
parents:
diff changeset
   118
/** Default product name string */
089413cdde3c 201028_02
hgs
parents:
diff changeset
   119
static const wchar_t KStringProduct[]      = L"Nokia USB Driver";
089413cdde3c 201028_02
hgs
parents:
diff changeset
   120
/** Default configuration name string */
089413cdde3c 201028_02
hgs
parents:
diff changeset
   121
static const wchar_t KStringConfig[]       = L"Bulk transfer method configuration";
089413cdde3c 201028_02
hgs
parents:
diff changeset
   122
/** Default configuration name string */
089413cdde3c 201028_02
hgs
parents:
diff changeset
   123
static const wchar_t KStringSerial[]       = L"Serial Not defined";
089413cdde3c 201028_02
hgs
parents:
diff changeset
   124
089413cdde3c 201028_02
hgs
parents:
diff changeset
   125
089413cdde3c 201028_02
hgs
parents:
diff changeset
   126
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
   127
// === USB Controller member function implementations - LDD API (public) ===========================
089413cdde3c 201028_02
hgs
parents:
diff changeset
   128
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
   129
089413cdde3c 201028_02
hgs
parents:
diff changeset
   130
DECLARE_STANDARD_EXTENSION()//lint !e1717 !e960 defined by symbian
089413cdde3c 201028_02
hgs
parents:
diff changeset
   131
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   132
    __KTRACE_OPT(KUSB, Kern::Printf("> Peripheral PIL Extension entry"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   133
    // Don't need to do anything here, using extension just to make sure
089413cdde3c 201028_02
hgs
parents:
diff changeset
   134
    // we're loaded when peripheral PSL trying to register itself to us.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   135
    __KTRACE_OPT(KUSB, Kern::Printf("< Peripheral PIL Extension exit"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   136
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   137
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   138
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   139
/** The class destructor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   140
089413cdde3c 201028_02
hgs
parents:
diff changeset
   141
    This rarely gets called, except, for example when something goes
089413cdde3c 201028_02
hgs
parents:
diff changeset
   142
    wrong during construction.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   143
089413cdde3c 201028_02
hgs
parents:
diff changeset
   144
    It's not exported because it is virtual.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   145
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   146
DUsbClientController::~DUsbClientController()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   147
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   148
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::~DUsbClientController()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   149
    if (iPowerHandler)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   150
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   151
        iPowerHandler->Remove();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   152
        delete iPowerHandler;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   153
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   154
089413cdde3c 201028_02
hgs
parents:
diff changeset
   155
    // ResetAndDestroy() will call for every array element the destructor of the pointed-to object,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   156
    // before deleting the element itself, and closing the array.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   157
    iConfigs.ResetAndDestroy();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   158
    __KTRACE_OPT(KUSB, Kern::Printf("< DUsbClientController::~DUsbClientController(): Done."));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   159
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   160
089413cdde3c 201028_02
hgs
parents:
diff changeset
   161
EXPORT_C DUsbClientController* DUsbClientController::Create(UsbShai::MPeripheralControllerIf&               aPeripheralControllerIf, 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   162
                                                            const UsbShai::TPeripheralControllerProperties& aProperties,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   163
                                                            TBool                                  aIsOtgPort)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   164
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   165
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::Create"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   166
        // Attempt to create the object
089413cdde3c 201028_02
hgs
parents:
diff changeset
   167
    DUsbClientController* usbcc = new DUsbClientController(aPeripheralControllerIf, 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   168
                                                           aProperties,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   169
                                                           aIsOtgPort);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   170
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   171
    __ASSERT_DEBUG( (usbcc != NULL), Kern::Fault( "  USB PSL Out of memory, DUsbClientController", __LINE__ ) );
089413cdde3c 201028_02
hgs
parents:
diff changeset
   172
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   173
    if (usbcc != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   174
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   175
        // Second phase constructor
089413cdde3c 201028_02
hgs
parents:
diff changeset
   176
        TInt err = usbcc->Construct();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   177
        __ASSERT_DEBUG( (err == KErrNone), Kern::Fault( "DUsbClientController::Construct failed", err) );
089413cdde3c 201028_02
hgs
parents:
diff changeset
   178
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
   179
        if (err != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   180
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   181
            delete usbcc;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   182
            usbcc = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   183
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   184
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   185
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   186
    __KTRACE_OPT(KUSB, Kern::Printf("< DUsbClientController::Create instance = %d",usbcc));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   187
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   188
    return usbcc;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   189
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   190
089413cdde3c 201028_02
hgs
parents:
diff changeset
   191
/**
089413cdde3c 201028_02
hgs
parents:
diff changeset
   192
 * FIXME: This function used to be called by the dummy DCD to disable
089413cdde3c 201028_02
hgs
parents:
diff changeset
   193
 * the peripheral stack. It has been deprecated and we currently use
089413cdde3c 201028_02
hgs
parents:
diff changeset
   194
 * DisablePeripheralStack() to achieve the same effect.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   195
 */
089413cdde3c 201028_02
hgs
parents:
diff changeset
   196
EXPORT_C void DUsbClientController::DisableClientStack()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   197
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   198
    __KTRACE_OPT(KUSB, Kern::Printf("CALL TO OBSOLETE FUNCTION: DUsbClientController::DisableClientStack()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   199
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   200
089413cdde3c 201028_02
hgs
parents:
diff changeset
   201
089413cdde3c 201028_02
hgs
parents:
diff changeset
   202
/**
089413cdde3c 201028_02
hgs
parents:
diff changeset
   203
 * FIXME: This function used to be called by the dummy DCD to enable
089413cdde3c 201028_02
hgs
parents:
diff changeset
   204
 * the peripheral stack. It has been deprecated and we currently use
089413cdde3c 201028_02
hgs
parents:
diff changeset
   205
 * EnablePeripheralStack() to achieve the same effect.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   206
 */
089413cdde3c 201028_02
hgs
parents:
diff changeset
   207
EXPORT_C void DUsbClientController::EnableClientStack()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   208
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   209
    __KTRACE_OPT(KUSB, Kern::Printf("CALL TO OBSOLETE FUNCTION: DUsbClientController::EnableClientStack()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   210
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   211
089413cdde3c 201028_02
hgs
parents:
diff changeset
   212
089413cdde3c 201028_02
hgs
parents:
diff changeset
   213
/** Called by LDD to see if controller is usable.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   214
089413cdde3c 201028_02
hgs
parents:
diff changeset
   215
    @return ETrue if controller is in normal state, EFalse if it is disabled.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   216
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   217
EXPORT_C TBool DUsbClientController::IsActive()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   218
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   219
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::IsActive = %d",iStackIsActive));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   220
    return iStackIsActive;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   221
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   222
089413cdde3c 201028_02
hgs
parents:
diff changeset
   223
089413cdde3c 201028_02
hgs
parents:
diff changeset
   224
/** Called by LDD to register client callbacks.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   225
089413cdde3c 201028_02
hgs
parents:
diff changeset
   226
    @return KErrNone if successful, KErrAlreadyExists callback exists.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   227
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   228
EXPORT_C TInt DUsbClientController::RegisterClientCallback(TUsbcClientCallback& aCallback)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   229
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   230
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::RegisterClientCallback()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   231
    if (iClientCallbacks.Elements() == KUsbcMaxListLength)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   232
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   233
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Maximum list length reached: %d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   234
                                          KUsbcMaxListLength));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   235
        return KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   236
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   237
    TSglQueIter<TUsbcClientCallback> iter(iClientCallbacks);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   238
    TUsbcClientCallback* p;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   239
    while ((p = iter++) != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   240
        if (p == &aCallback)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   241
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   242
            __KTRACE_OPT(KUSB, Kern::Printf("     Error: ClientCallback @ 0x%x already registered", &aCallback));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   243
            return KErrAlreadyExists;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   244
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   245
    iClientCallbacks.AddLast(aCallback);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   246
    __KTRACE_OPT(KUSB, Kern::Printf("< DUsbClientController::RegisterClientCallback()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   247
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   248
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   249
089413cdde3c 201028_02
hgs
parents:
diff changeset
   250
089413cdde3c 201028_02
hgs
parents:
diff changeset
   251
/** Returns a pointer to the USB client controller object.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   252
089413cdde3c 201028_02
hgs
parents:
diff changeset
   253
    This function is static.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   254
089413cdde3c 201028_02
hgs
parents:
diff changeset
   255
    @param aUdc The number of the UDC (0..n) for which the pointer is to be returned.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   256
089413cdde3c 201028_02
hgs
parents:
diff changeset
   257
    @return A pointer to the USB client controller object.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   258
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   259
EXPORT_C DUsbClientController* DUsbClientController::UsbcControllerPointer(TInt aUdc)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   260
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   261
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::UsbcControllerPointer()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   262
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   263
    if (aUdc < 0 || aUdc > 1)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   264
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   265
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: aUdc out of range (%d)", aUdc));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   266
        return NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   267
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   268
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
   269
    __KTRACE_OPT(KUSB, Kern::Printf("< DUsbClientController::UsbcControllerPointer()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   270
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   271
    return UsbClientController[aUdc];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   272
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   273
089413cdde3c 201028_02
hgs
parents:
diff changeset
   274
089413cdde3c 201028_02
hgs
parents:
diff changeset
   275
/** Fills the buffer passed in as an argument with endpoint capability information.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   276
089413cdde3c 201028_02
hgs
parents:
diff changeset
   277
     @see DUsbClientController::DeviceCaps()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   278
    @see TUsbcEndpointData
089413cdde3c 201028_02
hgs
parents:
diff changeset
   279
    @see TUsbDeviceCaps
089413cdde3c 201028_02
hgs
parents:
diff changeset
   280
089413cdde3c 201028_02
hgs
parents:
diff changeset
   281
    @param aClientId A pointer to the LDD making the enquiry.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   282
    @param aCapsBuf A reference to a descriptor buffer, which, on return, contains an array of
089413cdde3c 201028_02
hgs
parents:
diff changeset
   283
    TUsbcEndpointData elements; there are TUsbDeviceCaps::iTotalEndpoints elements in the array;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   284
    call DeviceCaps() to get the number of elements required.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   285
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   286
EXPORT_C void DUsbClientController::EndpointCaps(const DBase* aClientId, TDes8& aCapsBuf) const
089413cdde3c 201028_02
hgs
parents:
diff changeset
   287
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   288
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::EndpointCaps()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   289
    // Here we do not simply call DUsbClientController::DeviceEndpointCaps(),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   290
    // because that function fills an array which comprises of _all_ endpoints,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   291
    // whereas this function omits ep0 and all unusable endpoints.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   292
    // Apart from that, we have to fill an array of TUsbcEndpointData, not TUsbcEndpointCaps.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   293
    TUsbcEndpointData data[KUsbcMaxEndpoints];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   294
    const TInt ifcset_num = ClientId2InterfaceNumber(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   295
    for (TInt i = 2, j = 0; i < iDeviceTotalEndpoints; ++i)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   296
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   297
        __KTRACE_OPT(KUSB, Kern::Printf("  DUsbClientController::Caps: RealEndpoint #%d", i));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   298
        if (iRealEndpoints[i].iCaps.iTypesAndDir != UsbShai::KUsbEpNotAvailable)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   299
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   300
            __KTRACE_OPT(KUSB, Kern::Printf("  DUsbClientController::Caps: --> UsableEndpoint #%d", j));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   301
089413cdde3c 201028_02
hgs
parents:
diff changeset
   302
            data[j].iCaps.iSizes = iRealEndpoints[i].iCaps.iSizes;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   303
            data[j].iCaps.iTypesAndDir = iRealEndpoints[i].iCaps.iTypesAndDir;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   304
            data[j].iCaps.iHighBandwidth = iRealEndpoints[i].iCaps.iHighBandwidth;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   305
            data[j].iCaps.iReserved[0] = iRealEndpoints[i].iCaps.iReserved[0];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   306
            data[j].iCaps.iReserved[1] = iRealEndpoints[i].iCaps.iReserved[1];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   307
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
   308
            if (ifcset_num < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   309
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   310
                // If this LDD doesn't own an interface, but the Ep points to one,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   311
                // then that must be the interface of a different LDD. Hence the Ep
089413cdde3c 201028_02
hgs
parents:
diff changeset
   312
                // is not available for this LDD.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   313
                data[j].iInUse = (iRealEndpoints[i].iIfcNumber != NULL);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   314
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   315
            else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   316
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   317
                // If this LDD does already own an interface, and the Ep also points to one,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   318
                // then the Ep is not available for this LDD only if that interface is owned
089413cdde3c 201028_02
hgs
parents:
diff changeset
   319
                // by a different LDD (i.e. if the interface number is different).
089413cdde3c 201028_02
hgs
parents:
diff changeset
   320
                // Reason: Even though the endpoint might already be part of an interface setting,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   321
                // it is still available for a different alternate setting of the same interface.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   322
                data[j].iInUse = ((iRealEndpoints[i].iIfcNumber != NULL) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
   323
                                  (*(iRealEndpoints[i].iIfcNumber) != ifcset_num));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   324
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   325
089413cdde3c 201028_02
hgs
parents:
diff changeset
   326
            j++;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   327
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   328
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   329
    // aCapsBuf resides in userland
089413cdde3c 201028_02
hgs
parents:
diff changeset
   330
    TPtrC8 des((TUint8*)data, sizeof(data));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   331
    const TInt r = Kern::ThreadDesWrite((reinterpret_cast<const DLddUsbcChannel*>(aClientId))->Client(),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   332
                                        &aCapsBuf, des, 0, KChunkShiftBy0, NULL);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   333
    if (r != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   334
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   335
        Kern::ThreadKill((reinterpret_cast<const DLddUsbcChannel*>(aClientId))->Client(),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   336
                         EExitPanic, r, KUsbPILKillCat);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   337
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   338
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
   339
    __KTRACE_OPT(KUSB, Kern::Printf("< DUsbClientController::EndpointCaps()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   340
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   341
089413cdde3c 201028_02
hgs
parents:
diff changeset
   342
089413cdde3c 201028_02
hgs
parents:
diff changeset
   343
/** Fills the buffer passed in as an argument with device capability information.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   344
089413cdde3c 201028_02
hgs
parents:
diff changeset
   345
    @see TUsbDeviceCaps
089413cdde3c 201028_02
hgs
parents:
diff changeset
   346
    @see TUsbDeviceCapsV01
089413cdde3c 201028_02
hgs
parents:
diff changeset
   347
089413cdde3c 201028_02
hgs
parents:
diff changeset
   348
    @param aClientId A pointer to the LDD making the enquiry.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   349
    @param aCapsBuf A reference to a descriptor buffer which, on return, contains
089413cdde3c 201028_02
hgs
parents:
diff changeset
   350
    a TUsbDeviceCaps structure.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   351
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   352
EXPORT_C void DUsbClientController::DeviceCaps(const DBase* aClientId, TDes8& aCapsBuf) const
089413cdde3c 201028_02
hgs
parents:
diff changeset
   353
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   354
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::DeviceCaps()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   355
    TUsbDeviceCaps caps;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   356
    caps().iTotalEndpoints = iDeviceUsableEndpoints;        // not DeviceTotalEndpoints()!
48
21625e5de155 201035_01
hgs
parents: 33
diff changeset
   357
21625e5de155 201035_01
hgs
parents: 33
diff changeset
   358
    // In the SHAI API, all PSLs are required to support soft connection
21625e5de155 201035_01
hgs
parents: 33
diff changeset
   359
    caps().iConnect = ETrue;
33
089413cdde3c 201028_02
hgs
parents:
diff changeset
   360
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   361
    caps().iSelfPowered = iSelfPowered;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   362
    caps().iRemoteWakeup = iRemoteWakeup;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   363
    caps().iHighSpeed = (iControllerProperties.iControllerCaps & UsbShai::KDevCapHighSpeed)?ETrue:EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   364
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   365
    // PIL always assume controller support this caps, see explaination in peripheral shai header
089413cdde3c 201028_02
hgs
parents:
diff changeset
   366
    caps().iFeatureWord1 = caps().iFeatureWord1 | KUsbDevCapsFeatureWord1_CableDetectWithoutPower;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   367
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   368
    caps().iFeatureWord1 = caps().iFeatureWord1 | KUsbDevCapsFeatureWord1_EndpointResourceAllocV2;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   369
    caps().iReserved = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   370
089413cdde3c 201028_02
hgs
parents:
diff changeset
   371
    // aCapsBuf resides in userland
089413cdde3c 201028_02
hgs
parents:
diff changeset
   372
    const TInt r = Kern::ThreadDesWrite((reinterpret_cast<const DLddUsbcChannel*>(aClientId))->Client(),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   373
                                        &aCapsBuf, caps, 0, KChunkShiftBy0, NULL);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   374
    if (r != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   375
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   376
        Kern::ThreadKill((reinterpret_cast<const DLddUsbcChannel*>(aClientId))->Client(),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   377
                         EExitPanic, r, KUsbPILKillCat);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   378
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   379
    __KTRACE_OPT(KUSB, Kern::Printf("< DUsbClientController::DeviceCaps()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   380
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   381
089413cdde3c 201028_02
hgs
parents:
diff changeset
   382
089413cdde3c 201028_02
hgs
parents:
diff changeset
   383
TUsbcEndpointInfoArray::TUsbcEndpointInfoArray(const TUsbcEndpointInfo* aData, TInt aDataSize)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   384
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   385
    iType = EUsbcEndpointInfo;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   386
    iData = (TUint8*) aData;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   387
    if (aDataSize > 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   388
        iDataSize = aDataSize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   389
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   390
        iDataSize = sizeof(TUsbcEndpointInfo);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   391
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   392
089413cdde3c 201028_02
hgs
parents:
diff changeset
   393
089413cdde3c 201028_02
hgs
parents:
diff changeset
   394
inline TUsbcEndpointInfo& TUsbcEndpointInfoArray::operator[](TInt aIndex) const
089413cdde3c 201028_02
hgs
parents:
diff changeset
   395
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   396
    return *(TUsbcEndpointInfo*) &iData[aIndex * iDataSize];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   397
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   398
089413cdde3c 201028_02
hgs
parents:
diff changeset
   399
089413cdde3c 201028_02
hgs
parents:
diff changeset
   400
EXPORT_C TInt DUsbClientController::SetInterface(const DBase* aClientId, DThread* aThread,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   401
                                                 TInt aInterfaceNum, TUsbcClassInfo& aClass,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   402
                                                 TDesC8* aString, TInt aTotalEndpointsUsed,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   403
                                                 const TUsbcEndpointInfo aEndpointData[],
089413cdde3c 201028_02
hgs
parents:
diff changeset
   404
                                                 TInt (*aRealEpNumbers)[6], TUint32 aFeatureWord)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   405
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   406
    TUsbcEndpointInfoArray endpointData = TUsbcEndpointInfoArray(aEndpointData);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   407
    return SetInterface(aClientId, aThread, aInterfaceNum, aClass, aString, aTotalEndpointsUsed,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   408
                        endpointData, (TInt*) aRealEpNumbers, aFeatureWord);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   409
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   410
089413cdde3c 201028_02
hgs
parents:
diff changeset
   411
48
21625e5de155 201035_01
hgs
parents: 33
diff changeset
   412
21625e5de155 201035_01
hgs
parents: 33
diff changeset
   413
EXPORT_C void DUsbClientController::ChargerDetectorCaps(UsbShai::TChargerDetectorProperties& aProperties)
21625e5de155 201035_01
hgs
parents: 33
diff changeset
   414
    {
21625e5de155 201035_01
hgs
parents: 33
diff changeset
   415
    aProperties = gChargerDetectorProperties;
21625e5de155 201035_01
hgs
parents: 33
diff changeset
   416
    }
21625e5de155 201035_01
hgs
parents: 33
diff changeset
   417
21625e5de155 201035_01
hgs
parents: 33
diff changeset
   418
21625e5de155 201035_01
hgs
parents: 33
diff changeset
   419
33
089413cdde3c 201028_02
hgs
parents:
diff changeset
   420
/** Creates a new USB interface (one setting), complete with endpoints, descriptors, etc.,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   421
    and chains it into the internal device configuration tree.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   422
089413cdde3c 201028_02
hgs
parents:
diff changeset
   423
    @param aClientId A pointer to the LDD owning the new interface.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   424
    @param aThread A pointer to the thread the owning LDD is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   425
    @param aInterfaceNum The interface setting number of the new interface setting. This must be 0
089413cdde3c 201028_02
hgs
parents:
diff changeset
   426
    if it is the first setting of the interface that gets created, or 1 more than the last setting
089413cdde3c 201028_02
hgs
parents:
diff changeset
   427
    that was created for this interface.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   428
    @param aClass Contains information about the device class this interface might belong to.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   429
    @param aString A pointer to a string that is used for the string descriptor of this interface.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   430
    @param aTotalEndpointsUsed The number of endpoints used by this interface (and also the number of
089413cdde3c 201028_02
hgs
parents:
diff changeset
   431
    elements of the following array).
089413cdde3c 201028_02
hgs
parents:
diff changeset
   432
    @param aEndpointData An array with aTotalEndpointsUsed elements, containing information about the
089413cdde3c 201028_02
hgs
parents:
diff changeset
   433
    endpoints of this interface.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   434
089413cdde3c 201028_02
hgs
parents:
diff changeset
   435
    @return KErrNotSupported if Control endpoints are requested by the LDD but aren't supported by the PIL,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   436
    KErrInUse if at least one requested endpoint is - temporarily or permanently - not available for use,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   437
    KErrNoMemory if (endpoint, interface, string) descriptor allocation fails, KErrGeneral if something else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   438
    goes wrong during endpoint or interface or descriptor creation, KErrNone if interface successfully set up.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   439
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   440
EXPORT_C TInt DUsbClientController::SetInterface(const DBase* aClientId, DThread* aThread,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   441
                                                 TInt aInterfaceNum, TUsbcClassInfo& aClass,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   442
                                                 TDesC8* aString, TInt aTotalEndpointsUsed,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   443
                                                 const TUsbcEndpointInfoArray aEndpointData,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   444
                                                 TInt aRealEpNumbers[], TUint32 aFeatureWord)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   445
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   446
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::SetInterface()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   447
    if (aInterfaceNum != 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   448
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   449
        __KTRACE_OPT(KUSB, Kern::Printf("  alternate interface setting request: #%d", aInterfaceNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   450
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   451
089413cdde3c 201028_02
hgs
parents:
diff changeset
   452
#ifndef USB_SUPPORTS_CONTROLENDPOINTS
089413cdde3c 201028_02
hgs
parents:
diff changeset
   453
    for (TInt i = 0; i < aTotalEndpointsUsed; ++i)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   454
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   455
        if (aEndpointData[i].iType == UsbShai::KUsbEpTypeControl)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   456
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   457
            __KTRACE_OPT(KPANIC, Kern::Printf("  Error: control endpoints not supported"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   458
            return KErrNotSupported;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   459
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   460
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   461
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   462
089413cdde3c 201028_02
hgs
parents:
diff changeset
   463
    // Check for endpoint availability & check those endpoint's capabilities
089413cdde3c 201028_02
hgs
parents:
diff changeset
   464
    const TInt ifcset_num = ClientId2InterfaceNumber(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   465
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   466
    // The passed-in ifcset_num may be -1 now, but that's intended.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   467
    if (!CheckEpAvailability(aTotalEndpointsUsed, aEndpointData, ifcset_num))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   468
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   469
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: endpoints not (all) available"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   470
        return KErrInUse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   471
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   472
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   473
    // Create & setup new interface
089413cdde3c 201028_02
hgs
parents:
diff changeset
   474
    TUsbcInterface* ifc = CreateInterface(aClientId, aInterfaceNum, aFeatureWord);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   475
    if (ifc == NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   476
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   477
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: ifc == NULL"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   478
        return KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   479
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   480
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   481
    // Create logical endpoints
089413cdde3c 201028_02
hgs
parents:
diff changeset
   482
    TInt r = CreateEndpoints(ifc, aTotalEndpointsUsed, aEndpointData, aRealEpNumbers);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   483
    if (r != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   484
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   485
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: CreateEndpoints() err = %d ",r));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   486
        DeleteInterface(ifc->iInterfaceSet->iInterfaceNumber, aInterfaceNum);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   487
        return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   488
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   489
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   490
    // Create & setup interface, string, and endpoint descriptors
089413cdde3c 201028_02
hgs
parents:
diff changeset
   491
    r = SetupIfcDescriptor(ifc, aClass, aThread, aString, aEndpointData);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   492
    if (r != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   493
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   494
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: SetupIfcDescriptor() err = %d",r));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   495
        return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   496
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   497
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   498
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::SetInterface()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   499
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   500
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   501
089413cdde3c 201028_02
hgs
parents:
diff changeset
   502
089413cdde3c 201028_02
hgs
parents:
diff changeset
   503
/** Releases an existing USB interface (one setting), complete with endpoints, descriptors, etc.,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   504
    and removes it from the internal device configuration tree.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   505
089413cdde3c 201028_02
hgs
parents:
diff changeset
   506
    @param aClientId A pointer to the LDD owning the interface.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   507
    @param aInterfaceNum The setting number of the interface setting to be deleted. This must be
089413cdde3c 201028_02
hgs
parents:
diff changeset
   508
    the highest numbered (or 'last') setting for this interface.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   509
089413cdde3c 201028_02
hgs
parents:
diff changeset
   510
    @return KErrNotFound if interface (not setting) for some reason cannot be found, KErrArgument if an
089413cdde3c 201028_02
hgs
parents:
diff changeset
   511
    invalid interface setting number is specified (not existing or existing but too small), KErrNone if
089413cdde3c 201028_02
hgs
parents:
diff changeset
   512
    interface successfully released or if this client doesn't own any interface.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   513
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   514
EXPORT_C TInt DUsbClientController::ReleaseInterface(const DBase* aClientId, TInt aInterfaceNum)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   515
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   516
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::ReleaseInterface(..., %d)", aInterfaceNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   517
    const TInt ifcset = ClientId2InterfaceNumber(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   518
    if (ifcset < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   519
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   520
        __KTRACE_OPT(KUSB, Kern::Printf("  interface not found")); // no error
089413cdde3c 201028_02
hgs
parents:
diff changeset
   521
        return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   522
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   523
    TUsbcInterfaceSet* const ifcset_ptr = InterfaceNumber2InterfacePointer(ifcset);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   524
    if (!ifcset_ptr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   525
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   526
        __KTRACE_OPT(KUSB, Kern::Printf("  Error: interface number %d doesn't exist", ifcset));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   527
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   528
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   529
    const TInt setting_count = ifcset_ptr->iInterfaces.Count();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   530
    if ((setting_count - 1) != aInterfaceNum)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   531
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   532
        __KTRACE_OPT(KUSB,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   533
                     Kern::Printf("  Error: interface settings must be released in descending order:\n\r"
089413cdde3c 201028_02
hgs
parents:
diff changeset
   534
                                  "   %d setting(s) exist, #%d was requested to be released.\n\r"
089413cdde3c 201028_02
hgs
parents:
diff changeset
   535
                                  "   (#%d has to be released first)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   536
                                  setting_count, aInterfaceNum, setting_count - 1));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   537
        return KErrArgument;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   538
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   539
    // Tear down current setting (invalidate configured state)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   540
    __KTRACE_OPT(KUSB, Kern::Printf("  tearing down InterfaceSet %d", ifcset));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   541
    // Cancel all transfers on the current setting of this interface and deconfigure all its endpoints.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   542
    InterfaceSetTeardown(ifcset_ptr);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   543
    // 'Setting 0' means: delete all existing settings.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   544
    if (aInterfaceNum == 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   545
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   546
        TInt m = ifcset_ptr->iInterfaces.Count();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   547
        while (m > 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   548
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   549
            m--;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   550
            // Ground the physical endpoints' logical_endpoint_pointers
089413cdde3c 201028_02
hgs
parents:
diff changeset
   551
            const TInt n = ifcset_ptr->iInterfaces[m]->iEndpoints.Count();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   552
            for (TInt i = 0; i < n; ++i)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   553
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   554
                TUsbcPhysicalEndpoint* ptr = const_cast<TUsbcPhysicalEndpoint*>
089413cdde3c 201028_02
hgs
parents:
diff changeset
   555
                    (ifcset_ptr->iInterfaces[m]->iEndpoints[i]->iPEndpoint);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   556
                ptr->iLEndpoint = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   557
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   558
            // Delete the setting itself + its ifc & ep descriptors
089413cdde3c 201028_02
hgs
parents:
diff changeset
   559
            DeleteInterface(ifcset, m);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   560
            iDescriptors.DeleteIfcDescriptor(ifcset, m);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   561
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   562
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   563
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   564
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   565
        // Ground the physical endpoints' logical_endpoint_pointers
089413cdde3c 201028_02
hgs
parents:
diff changeset
   566
        const TInt n = ifcset_ptr->iInterfaces[aInterfaceNum]->iEndpoints.Count();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   567
        for (TInt i = 0; i < n; ++i)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   568
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   569
            TUsbcPhysicalEndpoint* ptr = const_cast<TUsbcPhysicalEndpoint*>
089413cdde3c 201028_02
hgs
parents:
diff changeset
   570
                (ifcset_ptr->iInterfaces[aInterfaceNum]->iEndpoints[i]->iPEndpoint);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   571
            ptr->iLEndpoint = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   572
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   573
        // Delete the setting itself + its ifc & ep descriptors
089413cdde3c 201028_02
hgs
parents:
diff changeset
   574
        DeleteInterface(ifcset, aInterfaceNum);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   575
        iDescriptors.DeleteIfcDescriptor(ifcset, aInterfaceNum);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   576
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   577
    // Delete the whole interface if all settings are gone
089413cdde3c 201028_02
hgs
parents:
diff changeset
   578
    if (ifcset_ptr->iInterfaces.Count() == 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   579
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   580
        DeleteInterfaceSet(ifcset);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   581
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   582
    // We now no longer have a valid current configuration
089413cdde3c 201028_02
hgs
parents:
diff changeset
   583
    iCurrentConfig = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   584
    if (iDeviceState == UsbShai::EUsbPeripheralStateConfigured)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   585
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   586
        NextDeviceState(UsbShai::EUsbPeripheralStateAddress);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   587
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   588
    // If it was the last interface(set)...
089413cdde3c 201028_02
hgs
parents:
diff changeset
   589
    if (iConfigs[0]->iInterfaceSets.Count() == 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   590
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   591
        __KTRACE_OPT(KUSB, Kern::Printf("  No ifc left -> turning off UDC"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   592
        // First disconnect the device from the bus
089413cdde3c 201028_02
hgs
parents:
diff changeset
   593
        UsbDisconnect();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   594
        DeActivateHardwareController();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   595
        // (this also disables endpoint zero; we cannot have a USB device w/o interface, see 9.6.3)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   596
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   597
    __KTRACE_OPT(KUSB, Kern::Printf("< DUsbClientController::ReleaseInterface"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   598
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   599
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   600
089413cdde3c 201028_02
hgs
parents:
diff changeset
   601
089413cdde3c 201028_02
hgs
parents:
diff changeset
   602
/** Enforces a USB re-enumeration by disconnecting the UDC from the bus (if it is currently connected) and
089413cdde3c 201028_02
hgs
parents:
diff changeset
   603
    re-connecting it.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   604
089413cdde3c 201028_02
hgs
parents:
diff changeset
   605
    This only works if the PSL supports it, i.e. if SoftConnectCaps() returns ETrue.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   606
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   607
EXPORT_C TInt DUsbClientController::ReEnumerate()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   608
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   609
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::ReEnumerate()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   610
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   611
    // ReEnumerate is possible only when stack is enabled
089413cdde3c 201028_02
hgs
parents:
diff changeset
   612
    if (!iStackIsActive)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   613
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   614
        __KTRACE_OPT(KUSB, Kern::Printf("  Client stack disabled -> returning here"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   615
        return KErrNotReady;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   616
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   617
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   618
    // If no interfaces setup, there is no point to reenumerate
089413cdde3c 201028_02
hgs
parents:
diff changeset
   619
    if (iConfigs[0]->iInterfaceSets.Count() == 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   620
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   621
        __KTRACE_OPT(KUSB, Kern::Printf("  > No interface registered -> no need to re-enumerate"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   622
        return KErrNone;;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   623
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   624
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   625
    if (!iHardwareActivated)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   626
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   627
        // If the UDC is still off, we switch it on here.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   628
        const TInt r = ActivateHardwareController();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   629
        if (r != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   630
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   631
                __KTRACE_OPT(KPANIC, Kern::Printf("  Error: ActivateHardwareController() failed: %d", r));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   632
                return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   633
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   634
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
   635
        // Finally connect the device to the bus
089413cdde3c 201028_02
hgs
parents:
diff changeset
   636
        UsbConnect();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   637
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   638
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   639
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   640
        UsbDisconnect();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   641
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
   642
        // Now we have to wait a certain amount of time, in order to give the host the opportunity
089413cdde3c 201028_02
hgs
parents:
diff changeset
   643
        // to come to terms with the new situation.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   644
        // (The ETrue parameter makes the callback get called in DFC instead of in ISR context.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   645
        iReconnectTimer.OneShot(KUsbReconnectDelay, ETrue);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   646
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   647
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
   648
    __KTRACE_OPT(KUSB, Kern::Printf("< DUsbClientController::ReEnumerate()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   649
    return KErrNone;;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   650
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   651
089413cdde3c 201028_02
hgs
parents:
diff changeset
   652
089413cdde3c 201028_02
hgs
parents:
diff changeset
   653
/** Powers up the UDC if one or more interfaces exist.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   654
089413cdde3c 201028_02
hgs
parents:
diff changeset
   655
    @return KErrNone if UDC successfully powered up, KErrNotReady if no
089413cdde3c 201028_02
hgs
parents:
diff changeset
   656
    interfaces have been registered yet, KErrHardwareNotAvailable if UDC
089413cdde3c 201028_02
hgs
parents:
diff changeset
   657
    couldn't be activated.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   658
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   659
EXPORT_C TInt DUsbClientController::PowerUpUdc()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   660
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   661
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::PowerUpUdc()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   662
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   663
    // we need to check whether Stack is activate or not(can be done by otg sw in otg setup
089413cdde3c 201028_02
hgs
parents:
diff changeset
   664
    // or by vBus risen/fallen event in a non-otg env)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   665
    if (!iStackIsActive)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   666
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   667
        __KTRACE_OPT(KUSB, Kern::Printf("  Client stack disabled -> returning here"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   668
        return KErrNotReady;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   669
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   670
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   671
    if (iConfigs[0]->iInterfaceSets.Count() == 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   672
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   673
        __KTRACE_OPT(KUSB, Kern::Printf("  No interface registered -> won't power up UDC"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   674
        return KErrNotReady;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   675
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   676
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   677
    // If the UDC is still off, we switch it on here.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   678
    const TInt r = ActivateHardwareController();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   679
    if (r != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   680
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   681
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: ActivateHardwareController() failed: %d", r));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   682
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   683
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   684
    __KTRACE_OPT(KUSB, Kern::Printf("< DUsbClientController::PowerUpUdc() returns %d",r));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   685
    return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   686
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   687
089413cdde3c 201028_02
hgs
parents:
diff changeset
   688
089413cdde3c 201028_02
hgs
parents:
diff changeset
   689
/** Connects the UDC to the bus.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   690
089413cdde3c 201028_02
hgs
parents:
diff changeset
   691
    @return KErrNone if UDC successfully connected, 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   692
            KErrNotSupported if KDevCapSoftConnect not supported
089413cdde3c 201028_02
hgs
parents:
diff changeset
   693
            KErrGeneral if there was an error.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   694
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
   695
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   696
EXPORT_C TInt DUsbClientController::UsbConnect()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   697
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   698
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::UsbConnect()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   699
    iClientSupportReady = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   700
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   701
    // If a deferred reset is pending, service it now
089413cdde3c 201028_02
hgs
parents:
diff changeset
   702
    const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   703
    if (iUsbResetDeferred)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   704
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   705
        __KTRACE_OPT(KUSB, Kern::Printf("  Resetting USB Reset 'defer' flag"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   706
        iUsbResetDeferred = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   707
        (void) ProcessResetEvent(EFalse);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   708
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   709
    __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   710
089413cdde3c 201028_02
hgs
parents:
diff changeset
   711
    // Indicate readiness to connect to the PSL
089413cdde3c 201028_02
hgs
parents:
diff changeset
   712
    const TInt r = iController.PeripheralConnect();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   713
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   714
    // Check whether Stack is activated by OTG controller
089413cdde3c 201028_02
hgs
parents:
diff changeset
   715
    // or Vbus Risen had been detected.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   716
    // If either of them is true and HW is not activated yet, do it here.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   717
    if (iStackIsActive &&  !iHardwareActivated )
089413cdde3c 201028_02
hgs
parents:
diff changeset
   718
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   719
        // PowerUpUdc only do Activating Hardware when there are at least 1
089413cdde3c 201028_02
hgs
parents:
diff changeset
   720
        // Iterface registered            
089413cdde3c 201028_02
hgs
parents:
diff changeset
   721
        PowerUpUdc();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   722
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   723
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   724
    __KTRACE_OPT(KUSB, Kern::Printf("< DUsbClientController::UsbConnect()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   725
    return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   726
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   727
089413cdde3c 201028_02
hgs
parents:
diff changeset
   728
089413cdde3c 201028_02
hgs
parents:
diff changeset
   729
/** Disconnects the UDC from the bus.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   730
089413cdde3c 201028_02
hgs
parents:
diff changeset
   731
    This only works if the PSL supports it, i.e. if SoftConnectCaps() returns ETrue.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   732
089413cdde3c 201028_02
hgs
parents:
diff changeset
   733
    @return KErrNone if UDC successfully disconnected, KErrGeneral if there was an error.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   734
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   735
EXPORT_C TInt DUsbClientController::UsbDisconnect()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   736
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   737
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::UsbDisconnect()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   738
    iClientSupportReady = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   739
089413cdde3c 201028_02
hgs
parents:
diff changeset
   740
    // Indicate to PSL that we are no longer ready to connect
089413cdde3c 201028_02
hgs
parents:
diff changeset
   741
    const TInt r = iController.PeripheralDisconnect();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   742
089413cdde3c 201028_02
hgs
parents:
diff changeset
   743
    // There won't be any notification by the PSL about this,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   744
    // so we have to notify the LDD/user ourselves:
089413cdde3c 201028_02
hgs
parents:
diff changeset
   745
    if ((r == KErrNone) && (iDeviceState != UsbShai::EUsbPeripheralStateUndefined))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   746
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   747
        // Not being in state UNDEFINED implies that the cable is inserted.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   748
        if (iHardwareActivated)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   749
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   750
            NextDeviceState(UsbShai::EUsbPeripheralStatePowered);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   751
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   752
        // (If the hardware is NOT activated at this point, we can only be in
089413cdde3c 201028_02
hgs
parents:
diff changeset
   753
        //    state UsbShai::EUsbPeripheralStateAttached, so we don't have to move to it.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   754
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   755
    return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   756
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   757
089413cdde3c 201028_02
hgs
parents:
diff changeset
   758
089413cdde3c 201028_02
hgs
parents:
diff changeset
   759
/** Registers a notification callback for changes of the USB device state.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   760
089413cdde3c 201028_02
hgs
parents:
diff changeset
   761
    In the event of a device state change, the callback's state member gets updated (using SetState) with a
089413cdde3c 201028_02
hgs
parents:
diff changeset
   762
    new UsbShai::TUsbPeripheralState value, and then the callback is executed (DoCallback). 'USB device state' here refers
089413cdde3c 201028_02
hgs
parents:
diff changeset
   763
    to the Visible Device States as defined in chapter 9 of the USB specification.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   764
089413cdde3c 201028_02
hgs
parents:
diff changeset
   765
    @param aCallback A reference to a properly filled in status callback structure.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   766
089413cdde3c 201028_02
hgs
parents:
diff changeset
   767
    @return KErrNone if callback successfully registered, KErrGeneral if this callback is already registered
089413cdde3c 201028_02
hgs
parents:
diff changeset
   768
    (it won't be registered twice).
089413cdde3c 201028_02
hgs
parents:
diff changeset
   769
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   770
EXPORT_C TInt DUsbClientController::RegisterForStatusChange(TUsbcStatusCallback& aCallback)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   771
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   772
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::RegisterForStatusChange()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   773
    if (iStatusCallbacks.Elements() == KUsbcMaxListLength)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   774
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   775
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Maximum list length reached: %d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   776
                                          KUsbcMaxListLength));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   777
        return KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   778
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   779
    if (IsInTheStatusList(aCallback))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   780
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   781
        __KTRACE_OPT(KUSB, Kern::Printf("  Error: StatusCallback @ 0x%x already registered", &aCallback));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   782
        return KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   783
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   784
    const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   785
    iStatusCallbacks.AddLast(aCallback);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   786
    __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   787
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   788
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   789
089413cdde3c 201028_02
hgs
parents:
diff changeset
   790
089413cdde3c 201028_02
hgs
parents:
diff changeset
   791
/** De-registers (removes from the list of pending requests) a notification callback for the USB device
089413cdde3c 201028_02
hgs
parents:
diff changeset
   792
    status.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   793
089413cdde3c 201028_02
hgs
parents:
diff changeset
   794
    @param aClientId A pointer to the LDD owning the status change callback.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   795
089413cdde3c 201028_02
hgs
parents:
diff changeset
   796
    @return KErrNone if callback successfully unregistered, KErrNotFound if the callback couldn't be found.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   797
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   798
EXPORT_C TInt DUsbClientController::DeRegisterForStatusChange(const DBase* aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   799
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   800
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeRegisterForStatusChange()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   801
    __ASSERT_DEBUG((aClientId != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   802
    const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   803
    TSglQueIter<TUsbcStatusCallback> iter(iStatusCallbacks);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   804
    TUsbcStatusCallback* p;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   805
    while ((p = iter++) != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   806
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   807
        if (p->Owner() == aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   808
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   809
            __KTRACE_OPT(KUSB, Kern::Printf("  removing StatusCallback @ 0x%x", p));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   810
            iStatusCallbacks.Remove(*p);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   811
            __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   812
            return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   813
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   814
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   815
    __KTRACE_OPT(KUSB, Kern::Printf("  client not found"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   816
    __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   817
    return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   818
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   819
089413cdde3c 201028_02
hgs
parents:
diff changeset
   820
089413cdde3c 201028_02
hgs
parents:
diff changeset
   821
/** Registers a notification callback for changes of the state of endpoints.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   822
089413cdde3c 201028_02
hgs
parents:
diff changeset
   823
    In the event of a state change of an endpoint that is spart of an interface which is owned by the LDD
089413cdde3c 201028_02
hgs
parents:
diff changeset
   824
    specified in the callback structure, the callback's state member gets updated (using SetState) with a new
089413cdde3c 201028_02
hgs
parents:
diff changeset
   825
    value, and the callback is executed (DoCallback). 'Endpoint state' here refers to the state of the
089413cdde3c 201028_02
hgs
parents:
diff changeset
   826
    ENDPOINT_HALT feature of an endpoint as described in chapter 9 of the USB specification. The contents of
089413cdde3c 201028_02
hgs
parents:
diff changeset
   827
    the state variable reflects the state of the halt features for all endpoints of the current interface
089413cdde3c 201028_02
hgs
parents:
diff changeset
   828
    setting: bit 0 represents endpoint 1, bit 1 endpoint 2, etc. A set bit means 'endpoint halted', a cleared
089413cdde3c 201028_02
hgs
parents:
diff changeset
   829
    bit 'endpoint not halted'.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   830
089413cdde3c 201028_02
hgs
parents:
diff changeset
   831
    @param aCallback A reference to a properly filled in endpoint status callback structure.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   832
089413cdde3c 201028_02
hgs
parents:
diff changeset
   833
    @return KErrNone if callback successfully registered, KErrGeneral if this callback is already registered
089413cdde3c 201028_02
hgs
parents:
diff changeset
   834
    (it won't be registered twice).
089413cdde3c 201028_02
hgs
parents:
diff changeset
   835
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   836
EXPORT_C TInt DUsbClientController::RegisterForEndpointStatusChange(TUsbcEndpointStatusCallback& aCallback)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   837
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   838
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::RegisterForEndpointStatusChange()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   839
    if (iEpStatusCallbacks.Elements() == KUsbcMaxListLength)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   840
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   841
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Maximum list length reached: %d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   842
                                          KUsbcMaxListLength));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   843
        return KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   844
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   845
    if (IsInTheEpStatusList(aCallback))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   846
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   847
        __KTRACE_OPT(KUSB, Kern::Printf("  Error: EpStatusCallback @ 0x%x already registered", &aCallback));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   848
        return KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   849
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   850
    const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   851
    iEpStatusCallbacks.AddLast(aCallback);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   852
    __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   853
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   854
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   855
089413cdde3c 201028_02
hgs
parents:
diff changeset
   856
089413cdde3c 201028_02
hgs
parents:
diff changeset
   857
/** De-registers (removes from the list of pending requests) a notification callback for changes of the state
089413cdde3c 201028_02
hgs
parents:
diff changeset
   858
    of endpoints.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   859
089413cdde3c 201028_02
hgs
parents:
diff changeset
   860
    @param aClientId A pointer to the LDD owning the endpoint status change callback.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   861
089413cdde3c 201028_02
hgs
parents:
diff changeset
   862
    @return KErrNone if callback successfully unregistered, KErrNotFound if the callback couldn't be found.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   863
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   864
EXPORT_C TInt DUsbClientController::DeRegisterForEndpointStatusChange(const DBase* aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   865
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   866
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeRegisterForEndpointStatusChange()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   867
    __ASSERT_DEBUG((aClientId != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   868
    const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   869
    TSglQueIter<TUsbcEndpointStatusCallback> iter(iEpStatusCallbacks);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   870
    TUsbcEndpointStatusCallback* p;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   871
    while ((p = iter++) != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   872
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   873
        if (p->Owner() == aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   874
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   875
            __KTRACE_OPT(KUSB, Kern::Printf("  removing EpStatusCallback @ 0x%x", p));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   876
            iEpStatusCallbacks.Remove(*p);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   877
            __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   878
            return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   879
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   880
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   881
    __KTRACE_OPT(KUSB, Kern::Printf("  client not found"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   882
    __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   883
    return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   884
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   885
089413cdde3c 201028_02
hgs
parents:
diff changeset
   886
089413cdde3c 201028_02
hgs
parents:
diff changeset
   887
/** Returns the number of the currently active alternate interface setting for this interface.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   888
089413cdde3c 201028_02
hgs
parents:
diff changeset
   889
    @param aClientId A pointer to the LDD owning the interface.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   890
    @param aInterfaceNum Here the interface gets written to.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   891
089413cdde3c 201028_02
hgs
parents:
diff changeset
   892
    @return KErrNotFound if an interface for this client couldn't be found, KErrNone if setting value was
089413cdde3c 201028_02
hgs
parents:
diff changeset
   893
    successfully written.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   894
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   895
EXPORT_C TInt DUsbClientController::GetInterfaceNumber(const DBase* aClientId, TInt& aInterfaceNum) const
089413cdde3c 201028_02
hgs
parents:
diff changeset
   896
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   897
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetInterfaceNumber()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   898
    const TInt ifcset = ClientId2InterfaceNumber(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   899
    if (ifcset < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   900
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   901
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error (ifc < 0)"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   902
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   903
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   904
    const TUsbcInterfaceSet* const ifcset_ptr = InterfaceNumber2InterfacePointer(ifcset);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   905
    if (!ifcset_ptr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   906
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   907
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: interface number %d doesn't exist", ifcset));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   908
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   909
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   910
    aInterfaceNum = ifcset_ptr->iCurrentInterface;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   911
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   912
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   913
089413cdde3c 201028_02
hgs
parents:
diff changeset
   914
089413cdde3c 201028_02
hgs
parents:
diff changeset
   915
/** This is normally called once by an LDD's destructor, either after a Close() on the user side,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   916
    or during general cleanup.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   917
089413cdde3c 201028_02
hgs
parents:
diff changeset
   918
    It might also be called by the LDD when some internal unrecoverable error occurs.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   919
089413cdde3c 201028_02
hgs
parents:
diff changeset
   920
    This function
089413cdde3c 201028_02
hgs
parents:
diff changeset
   921
    - de-registers a possibly pending device state change notification request,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   922
    - de-registers a possibly pending endpoint state change notification request,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   923
    - releases all interfaces + settings owned by this LDD,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   924
    - cancels all remaining (if any) read/write requests.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   925
089413cdde3c 201028_02
hgs
parents:
diff changeset
   926
    @param aClientId A pointer to the LDD to be unregistered.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   927
089413cdde3c 201028_02
hgs
parents:
diff changeset
   928
    @return KErrNone.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   929
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   930
EXPORT_C TInt DUsbClientController::DeRegisterClient(const DBase* aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   931
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   932
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeRegisterClient(0x%x)", aClientId));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   933
    // Cancel all device state notification requests
089413cdde3c 201028_02
hgs
parents:
diff changeset
   934
    DeRegisterForStatusChange(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   935
    // Cancel all endpoint state notification requests
089413cdde3c 201028_02
hgs
parents:
diff changeset
   936
    DeRegisterForEndpointStatusChange(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   937
    DeRegisterForOtgFeatureChange(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   938
    DeRegisterClientCallback(aClientId);
48
21625e5de155 201035_01
hgs
parents: 33
diff changeset
   939
    DeRegisterChargingPortTypeNotify(aClientId);
33
089413cdde3c 201028_02
hgs
parents:
diff changeset
   940
    // Delete the interface including all its alternate settings which might exist.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   941
    // (If we release the default setting (0), all alternate settings are deleted as well.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   942
    const TInt r = ReleaseInterface(aClientId, 0);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   943
    // Cancel all remaining (if any) read/write requests
089413cdde3c 201028_02
hgs
parents:
diff changeset
   944
    DeleteRequestCallbacks(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   945
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeRegisterClient: Done."));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   946
    return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   947
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   948
089413cdde3c 201028_02
hgs
parents:
diff changeset
   949
089413cdde3c 201028_02
hgs
parents:
diff changeset
   950
/** Returns the currently used Ep0 max packet size.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   951
089413cdde3c 201028_02
hgs
parents:
diff changeset
   952
    @return The currently used Ep0 max packet size.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   953
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   954
EXPORT_C TInt DUsbClientController::Ep0PacketSize() const
089413cdde3c 201028_02
hgs
parents:
diff changeset
   955
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   956
    const TUsbcLogicalEndpoint* const ep = iRealEndpoints[0].iLEndpoint;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   957
    if (iHighSpeed)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   958
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   959
        __KTRACE_OPT(KUSB, Kern::Printf("  Ep0 size = %d (HS)", ep->iEpSize_Hs));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   960
        return ep->iEpSize_Hs;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   961
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   962
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   963
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   964
        __KTRACE_OPT(KUSB, Kern::Printf("  Ep0 size = %d (FS)", ep->iEpSize_Fs));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   965
        return ep->iEpSize_Fs;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   966
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   967
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   968
089413cdde3c 201028_02
hgs
parents:
diff changeset
   969
089413cdde3c 201028_02
hgs
parents:
diff changeset
   970
/** Stalls Ep0.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   971
089413cdde3c 201028_02
hgs
parents:
diff changeset
   972
    @param aClientId A pointer to the LDD wishing to stall Ep0 (this is for PIL internal purposes only).
089413cdde3c 201028_02
hgs
parents:
diff changeset
   973
089413cdde3c 201028_02
hgs
parents:
diff changeset
   974
    @return KErrNone if endpoint zero successfully stalled, KErrGeneral otherwise.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   975
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   976
EXPORT_C TInt DUsbClientController::Ep0Stall(const DBase* aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   977
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   978
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::Ep0Stall()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   979
    if (aClientId == iEp0ClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   980
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   981
        ResetEp0DataOutVars();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   982
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   983
    const TInt err = iConTransferMgr->StallEndpoint(KEp0_Out);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   984
    if (err < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   985
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   986
        return err;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   987
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   988
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   989
        return iConTransferMgr->StallEndpoint(KEp0_In);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   990
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   991
089413cdde3c 201028_02
hgs
parents:
diff changeset
   992
089413cdde3c 201028_02
hgs
parents:
diff changeset
   993
/** Sends a zero-byte status packet on Ep0.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   994
089413cdde3c 201028_02
hgs
parents:
diff changeset
   995
    @param aClientId A pointer to the LDD wishing to send the status packet (not used at present).
089413cdde3c 201028_02
hgs
parents:
diff changeset
   996
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   997
EXPORT_C void DUsbClientController::SendEp0StatusPacket(const DBase* /* aClientId */)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   998
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   999
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SendEp0StatusPacket()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1000
    iConTransferMgr->SendEp0ZeroByteStatusPacket();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1001
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1002
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1003
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1004
/** Returns the current USB device state.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1005
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1006
    'USB device state' here refers to the Visible Device States as defined in chapter 9 of the USB
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1007
    specification.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1008
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1009
    @return The current USB device state, or UsbShai::EUsbPeripheralStateUndefined
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1010
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1011
EXPORT_C UsbShai::TUsbPeripheralState DUsbClientController::GetDeviceStatus() const
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1012
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1013
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetDeviceStatus()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1014
    return iDeviceState;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1015
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1016
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1017
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1018
/** Returns the state of an endpoint.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1019
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1020
    'Endpoint state' here refers to the state of the ENDPOINT_HALT feature of
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1021
    an endpoint as described in chapter 9 of the USB specification.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1022
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1023
    @param aClientId A pointer to the LDD owning the interface which contains the endpoint to be queried.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1024
    @param aEndpointNum The number of the endpoint to be queried.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1025
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1026
    @return The current endpoint state, or EEndpointStateUnknown if the endpoint couldn't be found.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1027
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1028
EXPORT_C TEndpointState DUsbClientController::GetEndpointStatus(const DBase* aClientId, TInt aEndpointNum) const
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1029
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1030
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::GetEndpointStatus()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1031
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1032
    TEndpointState ret = (iRealEndpoints[aEndpointNum].iHalt)?EEndpointStateStalled : EEndpointStateNotStalled;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1033
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1034
    __KTRACE_OPT(KUSB, Kern::Printf("< DUsbClientController::GetEndpointStatus() %d",ret));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1035
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1036
    return  ret;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1037
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1038
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1039
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1040
/** Sets up a data read request for an endpoint.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1041
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1042
    @param aCallback A reference to a properly filled in data transfer request callback structure.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1043
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1044
    @return KErrNone if callback successfully registered or if this callback is already registered
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1045
    (but it won't be registered twice), KErrNotFound if the endpoint couldn't be found, KErrArgument if
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1046
    endpoint number invalid (PSL), KErrGeneral if something else goes wrong.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1047
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1048
EXPORT_C TInt DUsbClientController::SetupReadBuffer(TUsbcRequestCallback& aCallback)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1049
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1050
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetupReadBuffer()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1051
    const TInt ep = aCallback.iRealEpNum;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1052
    __KTRACE_OPT(KUSB, Kern::Printf("  logical ep: #%d", aCallback.iEndpointNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1053
    __KTRACE_OPT(KUSB, Kern::Printf("  real ep:    #%d", ep));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1054
    TInt err = KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1055
    if (ep != 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1056
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1057
        if (iRequestCallbacks[ep])
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1058
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1059
            __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: RequestCallback already registered for that ep"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1060
            if (iRequestCallbacks[ep] == &aCallback)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1061
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1062
                __KTRACE_OPT(KPANIC, Kern::Printf("  (this same RequestCallback @ 0x%x)", &aCallback));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1063
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1064
            else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1065
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1066
                __KTRACE_OPT(KPANIC, Kern::Printf("  (a different RequestCallback @ 0x%x)", &aCallback));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1067
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1068
            return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1069
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1070
        // This may seem awkward:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1071
        // First we add a callback, and then, in case of an error, we remove it again.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1072
        // However this is necessary because the transfer request might complete (through
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1073
        // an ISR) _before_ the SetupEndpointRead function returns. Since we don't know the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1074
        // outcome, we have to provide the callback before making the setup call.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1075
        //
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1076
        __KTRACE_OPT(KUSB, Kern::Printf("  adding RequestCallback[%d] @ 0x%x", ep, &aCallback));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1077
        iRequestCallbacks[ep] = &aCallback;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1078
        if ((err = iController.SetupEndpointRead(ep, aCallback)) != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1079
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1080
            __KTRACE_OPT(KPANIC, Kern::Printf("  removing RequestCallback @ 0x%x (due to error)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1081
                                              &aCallback));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1082
            iRequestCallbacks[ep] = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1083
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1084
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1085
    else                                                    // (ep == 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1086
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1087
        if (iEp0ReadRequestCallbacks.Elements() == KUsbcMaxListLength)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1088
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1089
            __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Maximum list length reached: %d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1090
                                              KUsbcMaxListLength));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1091
            return KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1092
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1093
        if (IsInTheRequestList(aCallback))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1094
            {       
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1095
            __KTRACE_OPT(KUSB, Kern::Printf("  RequestCallback @ 0x%x already registered", &aCallback));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1096
            return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1097
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1098
        // Ep0 reads don't need to be prepared - there's always one pending
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1099
        __KTRACE_OPT(KUSB, Kern::Printf("  adding RequestCallback @ 0x%x (ep0)", &aCallback));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1100
        const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1101
        iEp0ReadRequestCallbacks.AddLast(aCallback);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1102
        __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1103
        err = KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1104
        if (iEp0_RxExtraCount != 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1105
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1106
            __KTRACE_OPT(KUSB, Kern::Printf("  iEp0_RxExtraData: trying again..."));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1107
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1108
            const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1109
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1110
            // Extra data is either a setup packet or a data packet
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1111
            // They are not possible to be both
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1112
            // And, the error code must be KErrNone, otherwise, we can not arrive here
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1113
            if( iSetupPacketPending )
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1114
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1115
                ProcessSetupPacket(iEp0_RxExtraCount,KErrNone);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1116
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1117
            else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1118
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1119
                ProcessDataOutPacket(iEp0_RxExtraCount,KErrNone);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1120
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1121
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1122
            // clear it since already completed to client
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1123
            iEp0_RxExtraCount = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1124
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1125
            err = iLastError;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1126
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1127
            __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1128
            if (err == KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1129
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1130
                //iEp0_RxExtraData = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1131
                // Queue a new Ep0 read (because xxxProceed only re-enables the interrupt)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1132
                iConTransferMgr->SetupEndpointZeroRead();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1133
                if (iSetupPacketPending)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1134
                    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1135
                    iConTransferMgr->Ep0SetupPacketProceed();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1136
                    iSetupPacketPending = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1137
                    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1138
                else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1139
                    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1140
                    iConTransferMgr->Ep0DataPacketProceed();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1141
                    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1142
                
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1143
                __KTRACE_OPT(KUSB, Kern::Printf("  :-)"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1144
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1145
            else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1146
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1147
                __KTRACE_OPT(KPANIC, Kern::Printf("  Error: :-("));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1148
                err = KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1149
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1150
            return err;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1151
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1152
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1153
    return err;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1154
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1155
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1156
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1157
/** Sets up a data write request for an endpoint.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1158
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1159
    @param aCallback A reference to a properly filled in data transfer request callback structure.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1160
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1161
    @return KErrNone if callback successfully registered or if this callback is already registered
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1162
    (but it won't be registered twice), KErrNotFound if the endpoint couldn't be found, KErrArgument if
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1163
    endpoint number invalid (PSL), KErrGeneral if something else goes wrong.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1164
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1165
EXPORT_C TInt DUsbClientController::SetupWriteBuffer(TUsbcRequestCallback& aCallback)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1166
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1167
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetupWriteBuffer()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1168
    TInt ep = aCallback.iRealEpNum;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1169
    __KTRACE_OPT(KUSB, Kern::Printf("  logical ep: #%d", aCallback.iEndpointNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1170
    __KTRACE_OPT(KUSB, Kern::Printf("  real ep:       #%d", ep));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1171
    if (iRequestCallbacks[ep])
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1172
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1173
        __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: RequestCallback already registered for that ep"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1174
        if (iRequestCallbacks[ep] == &aCallback)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1175
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1176
            __KTRACE_OPT(KPANIC, Kern::Printf("  (this same RequestCallback @ 0x%x)", &aCallback));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1177
            return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1178
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1179
        else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1180
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1181
            __KTRACE_OPT(KPANIC, Kern::Printf("  (a different RequestCallback @ 0x%x - poss. error)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1182
                                              &aCallback));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1183
            return KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1184
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1185
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1186
    if (ep == 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1187
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1188
        if (iEp0_TxNonStdCount)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1189
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1190
            if (iEp0_TxNonStdCount > aCallback.iLength)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1191
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1192
                __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Ep0 is sending less data than requested"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1193
                if ((aCallback.iLength % iEp0MaxPacketSize == 0) && !aCallback.iZlpReqd)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1194
                    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1195
                    __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Zlp should probably be requested"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1196
                    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1197
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1198
            else if (iEp0_TxNonStdCount < aCallback.iLength)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1199
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1200
                __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Ep0 is sending more data than requested"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1201
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1202
            iEp0_TxNonStdCount = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1203
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1204
        // Ep0 IN needs to be adjusted: the LDD uses 0 for both Ep0 directions.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1205
        ep = KEp0_Tx;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1206
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1207
    // This may seem awkward:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1208
    // First we add a callback, and then, in case of an error, we remove it again.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1209
    // However this is necessary because the transfer request might complete (through
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1210
    // an ISR) _before_ the SetupEndpointWrite function returns. Since we don't know the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1211
    // outcome, we have to provide the callback before making the setup call.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1212
    //
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1213
    __KTRACE_OPT(KUSB, Kern::Printf("  adding RequestCallback[%d] @ 0x%x", ep, &aCallback));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1214
    iRequestCallbacks[ep] = &aCallback;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1215
    if (ep == KEp0_Tx)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1216
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1217
        iEp0ClientDataTransmitting = ETrue;             // this must be set before calling SetupEndpointZeroWrite
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1218
        TInt ret = iConTransferMgr->SetupEndpointZeroWrite(aCallback.iBufferStart, aCallback.iLength, aCallback.iZlpReqd);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1219
        if (ret != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1220
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1221
            __KTRACE_OPT(KPANIC, Kern::Printf("  removing RequestCallback @ 0x%x (due to error)", &aCallback));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1222
            iRequestCallbacks[ep] = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1223
            iEp0ClientDataTransmitting = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1224
            return ret;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1225
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1226
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1227
    else if (iController.SetupEndpointWrite(ep, aCallback) != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1228
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1229
        __KTRACE_OPT(KPANIC, Kern::Printf("  removing RequestCallback @ 0x%x (due to error)", &aCallback));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1230
        iRequestCallbacks[ep] = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1231
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1232
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1233
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1234
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1235
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1236
/** Cancels a data read request for an endpoint.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1237
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1238
    The request callback will be removed from the queue and the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1239
    callback function won't be executed.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1240
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1241
    @param aClientId A pointer to the LDD owning the interface which contains the endpoint.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1242
    @param aRealEndpoint The number of the endpoint for which the transfer request is to be cancelled.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1243
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1244
EXPORT_C void DUsbClientController::CancelReadBuffer(const DBase* aClientId, TInt aRealEndpoint)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1245
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1246
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::CancelReadBuffer(%d)", aRealEndpoint));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1247
    if (aRealEndpoint < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1248
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1249
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: ep # < 0: %d", aRealEndpoint));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1250
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1251
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1252
    // Note that we here don't cancel Ep0 read requests at the PSL level!
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1253
    if (aRealEndpoint > 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1254
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1255
        iController.CancelEndpointRead(aRealEndpoint);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1256
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1257
    DeleteRequestCallback(aClientId, aRealEndpoint, UsbShai::EControllerRead);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1258
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1259
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1260
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1261
/** Cancels a data write request for an endpoint.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1262
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1263
    It cannot be guaranteed that the data is not sent nonetheless, as some UDCs don't permit a flushing of a
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1264
    TX FIFO once it has been filled. The request callback will be removed from the queue in any case and the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1265
    callback function won't be executed.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1266
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1267
    @param aClientId A pointer to the LDD owning the interface which contains the endpoint.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1268
    @param aRealEndpoint The number of the endpoint for which the transfer request is to be cancelled.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1269
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1270
EXPORT_C void DUsbClientController::CancelWriteBuffer(const DBase* aClientId, TInt aRealEndpoint)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1271
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1272
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::CancelWriteBuffer(%d)", aRealEndpoint));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1273
    if (aRealEndpoint < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1274
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1275
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: ep # < 0: %d", aRealEndpoint));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1276
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1277
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1278
    if (aRealEndpoint == 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1279
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1280
        // Ep0 IN needs to be adjusted: the LDD uses 0 for both Ep0 directions.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1281
        aRealEndpoint = KEp0_Tx;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1282
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1283
    iController.CancelEndpointWrite(aRealEndpoint);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1284
    if (aRealEndpoint == KEp0_Tx)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1285
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1286
        // Since Ep0 is shared among clients, we don't have to care about the client id.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1287
        iEp0WritePending = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1288
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1289
    DeleteRequestCallback(aClientId, aRealEndpoint, UsbShai::EControllerWrite);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1290
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1291
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1292
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1293
/** Halts (stalls) an endpoint (but not Ep0).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1294
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1295
    @param aClientId A pointer to the LDD owning the interface which contains the endpoint to be stalled.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1296
    @param aEndpointNum The number of the endpoint.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1297
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1298
    @return KErrNotFound if endpoint couldn't be found (includes Ep0), KErrNone if endpoint successfully
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1299
    stalled, KErrGeneral otherwise.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1300
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1301
EXPORT_C TInt DUsbClientController::HaltEndpoint(const DBase* aClientId, TInt aEndpointNum)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1302
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1303
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::HaltEndpoint(%d)", aEndpointNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1304
    const TInt r = iController.StallEndpoint(aEndpointNum);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1305
    if (r == KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1306
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1307
        iRealEndpoints[aEndpointNum].iHalt = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1308
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1309
    else if (r == KErrArgument)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1310
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1311
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1312
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1313
    return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1314
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1315
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1316
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1317
/** Clears the halt condition of an endpoint (but not Ep0).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1318
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1319
    @param aClientId A pointer to the LDD owning the interface which contains the endpoint to be un-stalled.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1320
    @param aEndpointNum The number of the endpoint.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1321
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1322
    @return KErrNotFound if endpoint couldn't be found (includes Ep0), KErrNone if endpoint successfully
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1323
    stalled, KErrGeneral otherwise.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1324
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1325
EXPORT_C TInt DUsbClientController::ClearHaltEndpoint(const DBase* aClientId, TInt aEndpointNum)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1326
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1327
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ClearHaltEndpoint(%d)", aEndpointNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1328
    const TInt r = iController.ClearStallEndpoint(aEndpointNum);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1329
    if (r == KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1330
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1331
        iRealEndpoints[aEndpointNum].iHalt = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1332
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1333
    else if (r == KErrArgument)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1334
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1335
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1336
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1337
    return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1338
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1339
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1340
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1341
/** This function requests 'device control' for an LDD.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1342
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1343
    Class or vendor specific Ep0 requests addressed to the USB device as a whole (Recipient field in
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1344
    bmRequestType byte of a Setup packet set to zero) are delivered to the LDD that owns device control. For
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1345
    obvious reasons only one USB LDD can have device control at any given time.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1346
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1347
    @param aClientId A pointer to the LDD requesting device control.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1348
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1349
    @return KErrNone if device control successfully claimed or if this LDD already owns it, KErrGeneral if
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1350
    device control already owned by a different client.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1351
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1352
EXPORT_C TInt DUsbClientController::SetDeviceControl(const DBase* aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1353
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1354
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetDeviceControl()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1355
    if (iEp0DeviceControl)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1356
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1357
        if (iEp0DeviceControl == aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1358
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1359
            __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Device Control already owned by this client"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1360
            return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1361
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1362
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Device Control already claimed by a different client"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1363
        return KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1364
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1365
    iEp0DeviceControl = aClientId;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1366
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1367
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1368
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1369
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1370
/** This function releases device control for an LDD.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1371
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1372
    @see DUsbClientController::SetDeviceControl()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1373
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1374
    @param aClientId A pointer to the LDD releasing device control.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1375
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1376
    @return KErrNone if device control successfully released, KErrGeneral if device control owned by a
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1377
    different client or by no client at all.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1378
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1379
EXPORT_C TInt DUsbClientController::ReleaseDeviceControl(const DBase* aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1380
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1381
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ReleaseDeviceControl()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1382
    if (iEp0DeviceControl)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1383
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1384
        if (iEp0DeviceControl == aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1385
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1386
            __KTRACE_OPT(KUSB, Kern::Printf("  Releasing Device Control"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1387
            iEp0DeviceControl = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1388
            return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1389
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1390
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Device Control owned by a different client"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1391
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1392
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1393
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1394
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Device Control not owned by any client"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1395
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1396
    return KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1397
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1398
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1399
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1400
/** Returns all available (configurable) max packet sizes for Ep0.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1401
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1402
    The information is coded as bitwise OR'ed values of KUsbEpSizeXXX constants (the bitmap format used for
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1403
    TUsbcEndpointCaps.iSupportedSizes).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1404
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1405
    @return All available (configurable) max packet sizes for Ep0.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1406
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1407
EXPORT_C TUint DUsbClientController::EndpointZeroMaxPacketSizes() const
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1408
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1409
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::EndpointZeroMaxPacketSizes()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1410
    return iRealEndpoints[0].iCaps.iSizes;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1411
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1412
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1413
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1414
/** Sets (configures) the max packet size for Ep0.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1415
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1416
    For available sizes as returned by DUsbClientController::EndpointZeroMaxPacketSizes()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1417
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1418
    Note that for HS operation the Ep0 size cannot be chosen, but is fixed at 64 bytes.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1419
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1420
    @return KErrNotSupported if invalid size specified, KErrNone if new max packet size successfully set or
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1421
    requested size was already set.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1422
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1423
EXPORT_C TInt DUsbClientController::SetEndpointZeroMaxPacketSize(TInt aMaxPacketSize)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1424
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1425
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetEndpointZeroMaxPacketSize(%d)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1426
                                    aMaxPacketSize));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1427
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1428
    if (iControllerProperties.iControllerCaps & UsbShai::KDevCapHighSpeed)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1429
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1430
        // We're not going to mess with this on a HS device.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1431
        return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1432
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1433
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1434
    if (!(iRealEndpoints[0].iCaps.iSizes & PacketSize2Mask(aMaxPacketSize)))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1435
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1436
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: invalid size"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1437
        return KErrNotSupported;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1438
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1439
    if (iRealEndpoints[0].iLEndpoint->iEpSize_Fs == aMaxPacketSize)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1440
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1441
        __KTRACE_OPT(KUSB, Kern::Printf("  this packet size already set -> returning"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1442
        return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1443
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1444
    const TUsbcLogicalEndpoint* const ep0_0 = iRealEndpoints[0].iLEndpoint;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1445
    const TUsbcLogicalEndpoint* const ep0_1 = iRealEndpoints[1].iLEndpoint;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1446
    const_cast<TUsbcLogicalEndpoint*>(ep0_0)->iEpSize_Fs = aMaxPacketSize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1447
    const_cast<TUsbcLogicalEndpoint*>(ep0_1)->iEpSize_Fs = aMaxPacketSize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1448
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1449
    // @@@ We should probably modify the device descriptor here as well...
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1450
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1451
    if (iHardwareActivated)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1452
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1453
        // De-configure endpoint zero
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1454
        iController.DeConfigureEndpoint(KEp0_Out);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1455
        iController.DeConfigureEndpoint(KEp0_In);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1456
        // Re-configure endpoint zero
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1457
        const_cast<TUsbcLogicalEndpoint*>(ep0_0)->iInfo.iSize = ep0_0->iEpSize_Fs;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1458
        const_cast<TUsbcLogicalEndpoint*>(ep0_1)->iInfo.iSize = ep0_1->iEpSize_Fs;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1459
        iController.ConfigureEndpoint(0, ep0_0->iInfo);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1460
        iController.ConfigureEndpoint(1, ep0_1->iInfo);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1461
        iEp0MaxPacketSize = ep0_0->iInfo.iSize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1462
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1463
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1464
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1465
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1466
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1467
/** Returns the current USB Device descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1468
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1469
    @param aThread A pointer to the thread the LDD requesting the descriptor is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1470
    @param aDeviceDescriptor A reference to a buffer into which the requested descriptor should be written
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1471
    (most likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1472
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1473
    @return The return value of the thread write operation, Kern::ThreadWrite(), when writing to the target
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1474
    buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1475
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1476
EXPORT_C TInt DUsbClientController::GetDeviceDescriptor(DThread* aThread, TDes8& aDeviceDescriptor)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1477
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1478
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetDeviceDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1479
    return iDescriptors.GetDeviceDescriptorTC(aThread, aDeviceDescriptor);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1480
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1481
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1482
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1483
/** Sets a new USB Device descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1484
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1485
    @param aThread A pointer to the thread the LDD requesting the setting of the descriptor is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1486
    @param aDeviceDescriptor A reference to a buffer which contains the descriptor to be set (most likely
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1487
    located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1488
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1489
    @return The return value of the thread read operation, Kern::ThreadRead(), when reading from the source
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1490
    buffer in case of a failure, KErrNone if the new descriptor was successfully set.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1491
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1492
EXPORT_C TInt DUsbClientController::SetDeviceDescriptor(DThread* aThread, const TDes8& aDeviceDescriptor)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1493
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1494
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetDeviceDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1495
    return iDescriptors.SetDeviceDescriptorTC(aThread, aDeviceDescriptor);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1496
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1497
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1498
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1499
/** Returns the current USB Device descriptor size.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1500
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1501
    @param aThread A pointer to the thread the LDD requesting the descriptor size is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1502
    @param aSize A reference to a buffer into which the requested descriptor size should be written
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1503
    (most likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1504
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1505
    @return The return value of the thread write operation, Kern::ThreadWrite(), when writing to the target
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1506
    buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1507
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1508
EXPORT_C TInt DUsbClientController::GetDeviceDescriptorSize(DThread* aThread, TDes8& aSize)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1509
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1510
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetDeviceDescriptorSize()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1511
    // We do not really enquire here....
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1512
    const TPtrC8 size(reinterpret_cast<const TUint8*>(&KUsbDescSize_Device), sizeof(KUsbDescSize_Device));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1513
    return Kern::ThreadDesWrite(aThread, &aSize, size, 0);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1514
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1515
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1516
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1517
/** Returns the current USB configuration descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1518
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1519
    @param aThread A pointer to the thread the LDD requesting the descriptor is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1520
    @param aConfigurationDescriptor A reference to a buffer into which the requested descriptor should be
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1521
    written (most likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1522
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1523
    @return The return value of the thread write operation, Kern::ThreadWrite(), when writing to the target
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1524
    buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1525
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1526
EXPORT_C TInt DUsbClientController::GetConfigurationDescriptor(DThread* aThread, TDes8& aConfigurationDescriptor)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1527
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1528
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetConfigurationDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1529
    return iDescriptors.GetConfigurationDescriptorTC(aThread, aConfigurationDescriptor);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1530
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1531
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1532
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1533
/** Sets a new USB configuration descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1534
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1535
    @param aThread A pointer to the thread the LDD requesting the setting of the descriptor is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1536
    @param aConfigurationDescriptor A reference to a buffer which contains the descriptor to be set (most
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1537
    likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1538
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1539
    @return The return value of the thread read operation, Kern::ThreadRead() when reading from the source
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1540
    buffer in case of a failure, KErrNone if the new descriptor was successfully set.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1541
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1542
EXPORT_C TInt DUsbClientController::SetConfigurationDescriptor(DThread* aThread,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1543
                                                               const TDes8& aConfigurationDescriptor)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1544
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1545
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetConfigurationDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1546
    return iDescriptors.SetConfigurationDescriptorTC(aThread, aConfigurationDescriptor);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1547
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1548
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1549
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1550
/** Returns the current USB configuration descriptor size.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1551
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1552
    @param aThread A pointer to the thread the LDD requesting the descriptor size is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1553
    @param aSize A reference to a buffer into which the requested descriptor size should be written
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1554
    (most likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1555
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1556
    @return The return value of the thread write operation, Kern::ThreadWrite(), when writing to the target
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1557
    buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1558
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1559
EXPORT_C TInt DUsbClientController::GetConfigurationDescriptorSize(DThread* aThread, TDes8& aSize)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1560
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1561
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetConfigurationDescriptorSize()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1562
    // We do not really enquire here....
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1563
    const TPtrC8 size(reinterpret_cast<const TUint8*>(&KUsbDescSize_Config), sizeof(KUsbDescSize_Config));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1564
    return Kern::ThreadDesWrite(aThread, &aSize, size, 0);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1565
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1566
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1567
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1568
/** Returns the current USB OTG descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1569
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1570
    @param aThread A pointer to the thread the LDD requesting the descriptor size is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1571
    @param aOtgDesc A reference to a buffer into which the requested descriptor should be
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1572
    written (most likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1573
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1574
    @return KErrNotSupported or the return value of the thread write operation, Kern::ThreadDesWrite(),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1575
    when writing to the target buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1576
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1577
EXPORT_C TInt DUsbClientController::GetOtgDescriptor(DThread* aThread, TDes8& aOtgDesc) const
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1578
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1579
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetOtgDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1580
    if (!iOtgSupport)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1581
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1582
        return KErrNotSupported;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1583
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1584
    return iDescriptors.GetOtgDescriptorTC(aThread, aOtgDesc);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1585
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1586
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1587
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1588
/** Sets a new OTG descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1589
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1590
    @param aThread A pointer to the thread the LDD requesting the descriptor size is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1591
    @param aOtgDesc A reference to a buffer which contains new OTG descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1592
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1593
    @return KErrNotSupported or the return value of the thread read operation, Kern::ThreadDesRead().
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1594
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1595
EXPORT_C TInt DUsbClientController::SetOtgDescriptor(DThread* aThread, const TDesC8& aOtgDesc)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1596
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1597
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetOtgDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1598
    if (!iOtgSupport)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1599
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1600
        return KErrNotSupported;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1601
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1602
    TBuf8<KUsbDescSize_Otg> otg;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1603
    const TInt r = Kern::ThreadDesRead(aThread, &aOtgDesc, otg, 0);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1604
    if (r != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1605
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1606
        return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1607
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1608
    // Check descriptor validity
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1609
    if (otg[0] != KUsbDescSize_Otg || otg[1] != KUsbDescType_Otg || otg[2] > 3)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1610
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1611
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Invalid OTG descriptor"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1612
        return KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1613
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1614
    __KTRACE_OPT(KUSB, Kern::Printf("  iOtgFuncMap before: 0x%x", iOtgFuncMap));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1615
    // Update value in controller as well
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1616
    const TUint8 hnp = otg[2] & KUsbOtgAttr_HnpSupp;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1617
    const TUint8 srp = otg[2] & KUsbOtgAttr_SrpSupp;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1618
    if (hnp && !srp)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1619
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1620
        __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Invalid OTG attribute combination (HNP && !SRP"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1621
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1622
    if (hnp && !(iOtgFuncMap & KUsbOtgAttr_HnpSupp))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1623
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1624
        __KTRACE_OPT(KUSB, Kern::Printf("  Setting attribute KUsbOtgAttr_HnpSupp"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1625
        iOtgFuncMap |= KUsbOtgAttr_HnpSupp;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1626
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1627
    else if (!hnp && (iOtgFuncMap & KUsbOtgAttr_HnpSupp))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1628
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1629
        __KTRACE_OPT(KUSB, Kern::Printf("  Removing attribute KUsbOtgAttr_HnpSupp"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1630
        iOtgFuncMap &= ~KUsbOtgAttr_HnpSupp;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1631
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1632
    if (srp && !(iOtgFuncMap & KUsbOtgAttr_SrpSupp))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1633
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1634
        __KTRACE_OPT(KUSB, Kern::Printf("  Setting attribute KUsbOtgAttr_SrpSupp"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1635
        iOtgFuncMap |= KUsbOtgAttr_SrpSupp;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1636
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1637
    else if (!srp && (iOtgFuncMap & KUsbOtgAttr_SrpSupp))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1638
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1639
        __KTRACE_OPT(KUSB, Kern::Printf("  Removing attribute KUsbOtgAttr_SrpSupp"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1640
        iOtgFuncMap &= ~KUsbOtgAttr_SrpSupp;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1641
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1642
    __KTRACE_OPT(KUSB, Kern::Printf("  iOtgFuncMap after:  0x%x", iOtgFuncMap));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1643
    return iDescriptors.SetOtgDescriptor(otg);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1644
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1645
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1646
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1647
/** Returns current OTG features of USB device.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1648
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1649
    @param aThread A pointer to the thread the LDD requesting the descriptor size is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1650
    @param aFeatures A reference to a buffer into which the requested OTG features should be written.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1651
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1652
    @return KErrNotSupported or the return value of the thread write operation, Kern::ThreadDesWrite().
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1653
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1654
EXPORT_C TInt DUsbClientController::GetOtgFeatures(DThread* aThread, TDes8& aFeatures) const
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1655
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1656
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetOtgFeatures()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1657
    if (!iOtgSupport)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1658
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1659
        return KErrNotSupported;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1660
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1661
    TBuf8<1> features(1);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1662
    features[0] = iOtgFuncMap & 0x1C;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1663
    return Kern::ThreadDesWrite(aThread, &aFeatures, features, 0);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1664
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1665
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1666
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1667
/** Returns current OTG features of USB device. This function is intended to be
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1668
    called only from kernel side.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1669
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1670
    @param aFeatures The reference to which the current features should be set at.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1671
    @return KErrNone if successful, KErrNotSupported if OTG is unavailable.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1672
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1673
EXPORT_C TInt DUsbClientController::GetCurrentOtgFeatures(TUint8& aFeatures) const
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1674
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1675
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetCurrentOtgFeatures()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1676
    if (!iOtgSupport)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1677
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1678
        return KErrNotSupported;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1679
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1680
    aFeatures = iOtgFuncMap & 0x1C;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1681
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1682
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1683
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1684
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1685
/** Registers client request for OTG feature change. Client is notified when any OTG
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1686
    feature is changed.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1687
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1688
    @see KUsbOtgAttr_B_HnpEnable, KUsbOtgAttr_A_HnpSupport, KUsbOtgAttr_A_AltHnpSupport
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1689
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1690
    @param aCallback Callback function. Gets called when OTG features change
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1691
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1692
    @return KErrNone if successful, KErrAlreadyExists if aCallback is already in the queue.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1693
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1694
EXPORT_C TInt DUsbClientController::RegisterForOtgFeatureChange(TUsbcOtgFeatureCallback& aCallback)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1695
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1696
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::RegisterForOtgFeatureChange()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1697
    if (iOtgCallbacks.Elements() == KUsbcMaxListLength)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1698
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1699
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Maximum list length reached: %d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1700
                                          KUsbcMaxListLength));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1701
        return KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1702
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1703
    if (IsInTheOtgFeatureList(aCallback))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1704
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1705
        __KTRACE_OPT(KUSB, Kern::Printf("  Error: OtgFeatureCallback @ 0x%x already registered", &aCallback));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1706
        return KErrAlreadyExists;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1707
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1708
    const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1709
    iOtgCallbacks.AddLast(aCallback);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1710
    __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1711
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1712
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1713
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1714
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1715
/** De-registers (removes from the list of pending requests) a notification callback for
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1716
    OTG feature change.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1717
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1718
    @param aClientId A pointer to the LDD owning the endpoint status change callback.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1719
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1720
    @return KErrNone if callback successfully unregistered, KErrNotFound if the callback couldn't be found.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1721
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1722
EXPORT_C TInt DUsbClientController::DeRegisterForOtgFeatureChange(const DBase* aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1723
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1724
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeRegisterForOtgFeatureChange()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1725
    __ASSERT_DEBUG((aClientId != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1726
    const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1727
    TSglQueIter<TUsbcOtgFeatureCallback> iter(iOtgCallbacks);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1728
    TUsbcOtgFeatureCallback* p;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1729
    while ((p = iter++) != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1730
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1731
        if (!aClientId || p->Owner() == aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1732
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1733
            __KTRACE_OPT(KUSB, Kern::Printf("  removing OtgFeatureCallback @ 0x%x", p));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1734
            iOtgCallbacks.Remove(*p);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1735
            __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1736
            return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1737
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1738
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1739
    __KTRACE_OPT(KUSB, Kern::Printf("  client not found"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1740
    __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1741
    return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1742
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1743
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1744
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1745
/** Returns a specific standard USB interface descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1746
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1747
    @param aThread A pointer to the thread the LDD requesting the descriptor is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1748
    @param aClientId A pointer to the LDD requesting the descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1749
    @param aSettingNum The setting number of the interface for which the descriptor is requested.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1750
    @param aInterfaceDescriptor A reference to a buffer into which the requested descriptor should be written
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1751
    (most likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1752
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1753
    @return KErrNotFound if the specified interface couldn't be found, otherwise the return value of the thread
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1754
    write operation, Kern::ThreadWrite(), when writing to the target buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1755
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1756
EXPORT_C TInt DUsbClientController::GetInterfaceDescriptor(DThread* aThread, const DBase* aClientId,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1757
                                                           TInt aSettingNum, TDes8& aInterfaceDescriptor)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1758
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1759
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetInterfaceDescriptor(x, 0x%08x, %d, y)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1760
                                    aClientId, aSettingNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1761
    const TInt ifcset = ClientId2InterfaceNumber(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1762
    if (ifcset < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1763
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1764
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Interface not found from client ID"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1765
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1766
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1767
    return iDescriptors.GetInterfaceDescriptorTC(aThread, aInterfaceDescriptor, ifcset, aSettingNum);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1768
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1769
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1770
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1771
/** Sets a new standard USB interface descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1772
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1773
    This function can also be used, by the user, and under certain conditions, to change an interface's number
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1774
    (reported as bInterfaceNumber in the descriptor). The conditions are: 1) We cannot accept a number that is
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1775
    already used by another interface, 2) We allow the interface number to be changed only when it's still the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1776
    only setting, and 3) We allow the interface number to be changed only for the default setting (0). (All
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1777
    alternate settings created for that interface thereafter will inherit the new, changed number.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1778
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1779
    @param aThread A pointer to the thread the LDD requesting the setting of the descriptor is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1780
    @param aClientId A pointer to the LDD requesting the setting of the descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1781
    @param aSettingNum The setting number of the interface for which the descriptor is to be set.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1782
    @param aInterfaceDescriptor A reference to a buffer which contains the descriptor to be set (most
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1783
    likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1784
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1785
    @return KErrNotFound if the specified interface couldn't be found, the return value of the thread read
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1786
    operation, Kern::ThreadRead(), when reading from the source buffer in case of a failure, KErrArgument if the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1787
    interface  number is to be changed (via bInterfaceNumber in the descriptor) and either the requested
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1788
    interface number is already used by another interface or the interface has more than one setting. KErrNone
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1789
    if the new descriptor was successfully set.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1790
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1791
EXPORT_C TInt DUsbClientController::SetInterfaceDescriptor(DThread* aThread, const DBase* aClientId,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1792
                                                           TInt aSettingNum, const TDes8& aInterfaceDescriptor)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1793
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1794
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetInterfaceDescriptor(x, 0x%08x, %d, y)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1795
                                    aClientId, aSettingNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1796
    const TInt ifcset = ClientId2InterfaceNumber(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1797
    if (ifcset < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1798
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1799
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Interface not found from client ID"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1800
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1801
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1802
    TBuf8<KUsbDescSize_Interface> new_ifc;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1803
    TInt r = Kern::ThreadDesRead(aThread, &aInterfaceDescriptor, new_ifc, 0);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1804
    if (r != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1805
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1806
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Copying interface descriptor buffer failed (%d)", r));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1807
        return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1808
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1809
    const TInt ifcset_new = new_ifc[2];
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1810
    const TBool ifc_num_changes = (ifcset != ifcset_new);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1811
    TUsbcInterfaceSet* const ifcset_ptr = InterfaceNumber2InterfacePointer(ifcset);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1812
    if (!ifcset_ptr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1813
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1814
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: interface number %d doesn't exist", ifcset));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1815
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1816
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1817
    if (ifc_num_changes)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1818
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1819
        // If the user wants to change the interface number, we need to do some sanity checks:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1820
        if (InterfaceExists(ifcset_new))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1821
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1822
            // Obviously we cannot accept a number that is already used by another interface.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1823
            __KTRACE_OPT(KPANIC, Kern::Printf("  Error: interface number %d already in use", ifcset_new));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1824
            return KErrArgument;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1825
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1826
        if (ifcset_ptr->iInterfaces.Count() > 1)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1827
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1828
            // We allow the interface number to be changed only when it's the only setting.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1829
            __KTRACE_OPT(KPANIC, Kern::Printf("  Error: interface has more than one alternate setting"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1830
            return KErrArgument;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1831
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1832
        if (aSettingNum != 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1833
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1834
            // We allow the interface number to be changed only when it's the default setting.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1835
            __KTRACE_OPT(KPANIC, Kern::Printf("  Error: interface number can only be changed for setting 0"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1836
            return KErrArgument;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1837
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1838
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1839
    if ((r = iDescriptors.SetInterfaceDescriptor(new_ifc, ifcset, aSettingNum)) != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1840
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1841
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: iDescriptors.SetInterfaceDescriptorfailed"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1842
        return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1843
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1844
    if (ifc_num_changes)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1845
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1846
        // Alright then, let's do it...
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1847
        __KTRACE_OPT(KUSB, Kern::Printf("  about to change interface number from %d to %d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1848
                                        ifcset, ifcset_new));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1849
        ifcset_ptr->iInterfaceNumber = ifcset_new;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1850
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1851
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1852
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1853
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1854
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1855
/** Returns the size of a specific standard USB interface descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1856
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1857
    @param aThread A pointer to the thread the LDD requesting the descriptor size is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1858
    @param aClientId A pointer to the LDD requesting the descriptor size.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1859
    @param aSettingNum The setting number of the interface for which the descriptor size is requested.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1860
    @param aSize A reference to a buffer into which the requested descriptor size should be written (most
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1861
    likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1862
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1863
    @return KErrNotFound if the specified interface couldn't be found, otherwise the return value of the thread
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1864
    write operation, Kern::ThreadWrite(), when writing to the target buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1865
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1866
EXPORT_C TInt DUsbClientController::GetInterfaceDescriptorSize(DThread* aThread, const DBase* aClientId,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1867
                                                               TInt /*aSettingNum*/, TDes8& aSize)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1868
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1869
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetInterfaceDescriptorSize()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1870
    const TInt ifcset = ClientId2InterfaceNumber(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1871
    if (ifcset < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1872
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1873
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Interface not found from client ID"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1874
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1875
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1876
    // Actually, we do not really enquire here....
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1877
    const TPtrC8 size(reinterpret_cast<const TUint8*>(&KUsbDescSize_Interface), sizeof(KUsbDescSize_Interface));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1878
    Kern::ThreadDesWrite(aThread, &aSize, size, 0);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1879
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1880
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1881
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1882
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1883
/** Returns a specific standard USB endpoint descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1884
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1885
    @param aThread A pointer to the thread the LDD requesting the descriptor is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1886
    @param aClientId A pointer to the LDD requesting the descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1887
    @param aSettingNum The setting number of the interface that contains the endpoint for which the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1888
    descriptor is requested.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1889
    @param aEndpointNum The endpoint for which the descriptor is requested.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1890
    @param aEndpointDescriptor A reference to a buffer into which the requested descriptor should be written
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1891
    (most likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1892
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1893
    @return KErrNotFound if the specified interface or endpoint couldn't be found, otherwise the return value
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1894
    of the thread write operation, Kern::ThreadWrite(), when writing to the target buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1895
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1896
EXPORT_C TInt DUsbClientController::GetEndpointDescriptor(DThread* aThread, const DBase* aClientId,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1897
                                                          TInt aSettingNum, TInt aEndpointNum,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1898
                                                          TDes8& aEndpointDescriptor)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1899
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1900
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetEndpointDescriptor(x, 0x%08x, %d, %d, y)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1901
                                    aClientId, aSettingNum, aEndpointNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1902
    const TInt ifcset = ClientId2InterfaceNumber(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1903
    if (ifcset < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1904
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1905
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Interface not found from client ID"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1906
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1907
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1908
    return iDescriptors.GetEndpointDescriptorTC(aThread, aEndpointDescriptor, ifcset,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1909
                                                aSettingNum, EpIdx2Addr(aEndpointNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1910
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1911
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1912
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1913
/** Sets a new standard USB endpoint descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1914
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1915
    @param aThread A pointer to the thread the LDD requesting the setting of the descriptor is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1916
    @param aClientId A pointer to the LDD requesting the setting of the descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1917
    @param aSettingNum The setting number of the interface that contains the endpoint for which the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1918
    descriptor is to be set.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1919
    @param aEndpointNum The endpoint for which the descriptor is to be set.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1920
    @param aEndpointDescriptor A reference to a buffer which contains the descriptor to be set (most
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1921
    likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1922
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1923
    @return KErrNotFound if the specified interface or endpoint couldn't be found, the return value of the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1924
    thread read operation, Kern::ThreadRead(), when reading from the source buffer in case of a read failure,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1925
    KErrNone if the new descriptor was successfully set.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1926
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1927
EXPORT_C TInt DUsbClientController::SetEndpointDescriptor(DThread* aThread, const DBase* aClientId,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1928
                                                          TInt aSettingNum, TInt aEndpointNum,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1929
                                                          const TDes8& aEndpointDescriptor)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1930
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1931
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetEndpointDescriptor(x, 0x%08x, %d, %d, y)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1932
                                    aClientId, aSettingNum, aEndpointNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1933
    const TInt ifcset = ClientId2InterfaceNumber(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1934
    if (ifcset < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1935
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1936
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Interface not found from client ID"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1937
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1938
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1939
    return iDescriptors.SetEndpointDescriptorTC(aThread, aEndpointDescriptor, ifcset,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1940
                                                aSettingNum, EpIdx2Addr(aEndpointNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1941
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1942
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1943
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1944
/** Returns the size of a specific standard USB endpoint descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1945
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1946
    @param aThread A pointer to the thread the LDD requesting the descriptor size is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1947
    @param aClientId A pointer to the LDD requesting the descriptor size.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1948
    @param aSettingNum The setting number of the interface that contains the endpoint for which the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1949
    descriptor size is requested.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1950
    @param aEndpointNum The endpoint for which the descriptor size is requested.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1951
    @param aEndpointDescriptor A reference to a buffer into which the requested descriptor size should be
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1952
    written (most likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1953
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1954
    @return KErrNotFound if the specified interface or endpoint couldn't be found, otherwise the return value
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1955
    of the thread write operation, kern::ThreadWrite(), when writing to the target buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1956
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1957
EXPORT_C TInt DUsbClientController::GetEndpointDescriptorSize(DThread* aThread, const DBase* aClientId,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1958
                                                              TInt aSettingNum, TInt aEndpointNum,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1959
                                                              TDes8& aSize)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1960
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1961
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetEndpointDescriptorSize(x, 0x%08x, %d, %d, y)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1962
                                    aClientId, aSettingNum, aEndpointNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1963
    const TInt ifcset = ClientId2InterfaceNumber(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1964
    if (ifcset < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1965
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1966
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Interface not found from client ID"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1967
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1968
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1969
    TInt s;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1970
    TInt r = iDescriptors.GetEndpointDescriptorSize(ifcset, aSettingNum,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1971
                                                    EpIdx2Addr(aEndpointNum), s);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1972
    if (r == KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1973
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1974
        TPtrC8 size(reinterpret_cast<const TUint8*>(&s), sizeof(s));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1975
        r = Kern::ThreadDesWrite(aThread, &aSize, size, 0);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1976
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1977
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1978
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1979
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: endpoint descriptor not found"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1980
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1981
    return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1982
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1983
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1984
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1985
/** Returns the current Device_Qualifier descriptor. On a USB device which doesn't support high-speed
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1986
    operation this function will return an error. Note that the contents of the descriptor depend on
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1987
    the current device speed (full-speed or high-speed).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1988
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1989
    @param aThread A pointer to the thread the LDD requesting the descriptor is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1990
    @param aDeviceQualifierDescriptor A reference to a buffer into which the requested descriptor
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1991
    should be written (most likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1992
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1993
    @return KErrNotSupported if this descriptor is not supported, otherwise the return value of the thread
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1994
    write operation, Kern::ThreadWrite(), when writing to the target buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1995
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1996
EXPORT_C TInt DUsbClientController::GetDeviceQualifierDescriptor(DThread* aThread,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1997
                                                                 TDes8& aDeviceQualifierDescriptor)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1998
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  1999
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetDeviceQualifierDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2000
    return iDescriptors.GetDeviceQualifierDescriptorTC(aThread, aDeviceQualifierDescriptor);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2001
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2002
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2003
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2004
/** Sets a new Device_Qualifier descriptor. On a USB device which doesn't support high-speed
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2005
    operation this function will return an error. Note that the contents of the descriptor should take
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2006
    into account the current device speed (full-speed or high-speed) as it is dependent on it.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2007
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2008
    @param aThread A pointer to the thread the LDD requesting the setting of the descriptor is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2009
    @param aDeviceQualifierDescriptor A reference to a buffer which contains the descriptor to be set (most
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2010
    likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2011
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2012
    @return KErrNotSupported if this descriptor is not supported, otherwise the return value of the thread
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2013
    read operation, Kern::ThreadRead(), when reading from the source buffer in case of a failure, KErrNone if
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2014
    the new descriptor was successfully set.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2015
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2016
EXPORT_C TInt DUsbClientController::SetDeviceQualifierDescriptor(DThread* aThread,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2017
                                                                 const TDes8& aDeviceQualifierDescriptor)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2018
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2019
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetDeviceQualifierDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2020
    return iDescriptors.SetDeviceQualifierDescriptorTC(aThread, aDeviceQualifierDescriptor);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2021
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2022
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2023
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2024
/** Returns the current Other_Speed_Configuration descriptor. On a USB device which doesn't support high-speed
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2025
    operation this function will return an error. Note that the contents of the descriptor depend on the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2026
    current device speed (full-speed or high-speed).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2027
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2028
    @param aThread A pointer to the thread the LDD requesting the descriptor is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2029
    @param aConfigurationDescriptor A reference to a buffer into which the requested descriptor
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2030
    should be written (most likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2031
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2032
    @return KErrNotSupported if this descriptor is not supported, otherwise the return value of the thread
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2033
    write operation, Kern::ThreadWrite(), when writing to the target buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2034
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2035
EXPORT_C TInt DUsbClientController::GetOtherSpeedConfigurationDescriptor(DThread* aThread,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2036
                                                                         TDes8& aConfigurationDescriptor)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2037
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2038
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetOtherSpeedConfigurationDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2039
    return iDescriptors.GetOtherSpeedConfigurationDescriptorTC(aThread, aConfigurationDescriptor);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2040
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2041
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2042
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2043
/** Sets a new Other_Speed_Configuration descriptor. On a USB device which doesn't support high-speed
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2044
    operation this function will return an error. Note that the contents of the descriptor should take
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2045
    into account the current device speed (full-speed or high-speed) as it is dependent on it.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2046
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2047
    @param aThread A pointer to the thread the LDD requesting the setting of the descriptor is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2048
    @param aConfigurationDescriptor A reference to a buffer which contains the descriptor to be set (most
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2049
    likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2050
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2051
    @return KErrNotSupported if this descriptor is not supported, otherwise the return value of the thread
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2052
    read operation, Kern::ThreadRead(), when reading from the source buffer in case of a failure, KErrNone if
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2053
    the new descriptor was successfully set.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2054
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2055
EXPORT_C TInt DUsbClientController::SetOtherSpeedConfigurationDescriptor(DThread* aThread,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2056
                                                                         const TDes8& aConfigurationDescriptor)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2057
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2058
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetOtherSpeedConfigurationDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2059
    return iDescriptors.SetOtherSpeedConfigurationDescriptorTC(aThread, aConfigurationDescriptor);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2060
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2061
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2062
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2063
/** Returns a block of all available non-standard (class-specific) interface descriptors for a specific
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2064
    interface.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2065
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2066
    @param aThread A pointer to the thread the LDD requesting the descriptor block is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2067
    @param aClientId A pointer to the LDD requesting the descriptor block.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2068
    @param aSettingNum The setting number of the interface for which the descriptor block is requested.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2069
    @param aInterfaceDescriptor A reference to a buffer into which the requested descriptor(s) should be
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2070
    written (most likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2071
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2072
    @return KErrNotFound if the specified interface couldn't be found, otherwise the return value of the thread
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2073
    write operation, Kern::ThreadWrite(), when writing to the target buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2074
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2075
EXPORT_C TInt DUsbClientController::GetCSInterfaceDescriptorBlock(DThread* aThread, const DBase* aClientId,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2076
                                                                  TInt aSettingNum,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2077
                                                                  TDes8& aInterfaceDescriptor)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2078
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2079
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetCSInterfaceDescriptorBlock(x, 0x%08x, %d, y)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2080
                                    aClientId, aSettingNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2081
    const TInt ifcset = ClientId2InterfaceNumber(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2082
    if (ifcset < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2083
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2084
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Interface not found from client ID"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2085
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2086
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2087
    return iDescriptors.GetCSInterfaceDescriptorTC(aThread, aInterfaceDescriptor, ifcset, aSettingNum);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2088
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2089
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2090
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2091
/** Sets a block of (i.e. one or more) non-standard (class-specific) interface descriptors for a specific
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2092
    interface.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2093
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2094
    @param aThread A pointer to the thread the LDD requesting the setting of the descriptor block is running
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2095
    in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2096
    @param aClientId A pointer to the LDD requesting the setting of the descriptor block.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2097
    @param aSettingNum The setting number of the interface for which the setting of the descriptor block is
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2098
    requested.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2099
    @param aInterfaceDescriptor A reference to a buffer which contains the descriptor block to be set (most
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2100
    likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2101
    @param aSize The size of the descriptor block to be set.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2102
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2103
    @return KErrNotFound if the specified interface couldn't be found, KErrArgument if aSize is less than 2,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2104
    KErrNoMemory if enough memory for the new descriptor(s) couldn't be allocated, otherwise the return value
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2105
    of the thread read operation, Kern::ThreadRead(), when reading from the source buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2106
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2107
EXPORT_C TInt DUsbClientController::SetCSInterfaceDescriptorBlock(DThread* aThread, const DBase* aClientId,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2108
                                                                  TInt aSettingNum,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2109
                                                                  const TDes8& aInterfaceDescriptor, TInt aSize)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2110
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2111
    __KTRACE_OPT(KUSB,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2112
                 Kern::Printf("DUsbClientController::SetCSInterfaceDescriptorBlock(x, 0x%08x, %d, y, %d)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2113
                              aClientId, aSettingNum, aSize));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2114
    const TInt ifcset = ClientId2InterfaceNumber(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2115
    if (ifcset < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2116
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2117
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Interface not found from client ID"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2118
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2119
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2120
    if (aSize < 2)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2121
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2122
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: aSize < 2 (%d)", aSize));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2123
        return KErrArgument;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2124
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2125
    return iDescriptors.SetCSInterfaceDescriptorTC(aThread, aInterfaceDescriptor, ifcset, aSettingNum, aSize);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2126
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2127
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2128
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2129
/** Returns the total size all non-standard (class-specific) interface descriptors for a specific interface.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2130
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2131
    @param aThread A pointer to the thread the LDD requesting the descriptor block size is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2132
    @param aClientId A pointer to the LDD requesting the descriptor block size.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2133
    @param aSettingNum The setting number of the interface for which the descriptor block size is
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2134
    requested.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2135
    @param aSize A reference to a buffer into which the requested descriptor block size should be written (most
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2136
    likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2137
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2138
    @return KErrNotFound if the specified interface couldn't be found, otherwise the return value of the thread
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2139
    write operation, Kern::ThreadWrite(), when writing to the target buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2140
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2141
EXPORT_C TInt DUsbClientController::GetCSInterfaceDescriptorBlockSize(DThread* aThread, const DBase* aClientId,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2142
                                                                      TInt aSettingNum, TDes8& aSize)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2143
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2144
    __KTRACE_OPT(KUSB,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2145
                 Kern::Printf("DUsbClientController::GetCSInterfaceDescriptorBlockSize(x, 0x%08x, %d, y)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2146
                              aClientId, aSettingNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2147
    const TInt ifcset = ClientId2InterfaceNumber(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2148
    if (ifcset < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2149
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2150
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Interface not found from client ID"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2151
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2152
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2153
    TInt s;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2154
    const TInt r = iDescriptors.GetCSInterfaceDescriptorSize(ifcset, aSettingNum, s);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2155
    if (r == KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2156
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2157
        const TPtrC8 size(reinterpret_cast<const TUint8*>(&s), sizeof(s));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2158
        Kern::ThreadDesWrite(aThread, &aSize, size, 0);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2159
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2160
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2161
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2162
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: cs interface descriptor not found"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2163
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2164
    return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2165
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2166
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2167
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2168
/** Returns a block of all available non-standard (class-specific) endpoint descriptors for a specific endpoint.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2169
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2170
    @param aThread A pointer to the thread the LDD requesting the descriptor block is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2171
    @param aClientId A pointer to the LDD requesting the descriptor block.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2172
    @param aSettingNum The setting number of the interface that contains the endpoint for which the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2173
    descriptor block is requested.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2174
    @param aEndpointNum The endpoint for which the descriptor block is requested.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2175
    @param aEndpointDescriptor A reference to a buffer into which the requested descriptor(s) should be written
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2176
    (most likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2177
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2178
    @return KErrNotFound if the specified interface or endpoint couldn't be found, otherwise the return value
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2179
    of the thread write operation, Kern::ThreadWrite(), when writing to the target buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2180
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2181
EXPORT_C TInt DUsbClientController::GetCSEndpointDescriptorBlock(DThread* aThread, const DBase* aClientId,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2182
                                                                 TInt aSettingNum, TInt aEndpointNum,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2183
                                                                 TDes8& aEndpointDescriptor)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2184
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2185
    __KTRACE_OPT(KUSB,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2186
                 Kern::Printf("DUsbClientController::GetCSEndpointDescriptorBlock(x, 0x%08x, %d, %d, y)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2187
                              aClientId, aSettingNum, aEndpointNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2188
    const TInt ifcset = ClientId2InterfaceNumber(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2189
    if (ifcset < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2190
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2191
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Interface not found from client ID"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2192
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2193
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2194
    return iDescriptors.GetCSEndpointDescriptorTC(aThread, aEndpointDescriptor, ifcset,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2195
                                                  aSettingNum, EpIdx2Addr(aEndpointNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2196
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2197
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2198
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2199
/** Sets a block of (i.e. one or more) non-standard (class-specific) endpoint descriptors for a specific
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2200
    endpoint.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2201
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2202
    @param aThread A pointer to the thread the LDD requesting the setting of the descriptor block is running
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2203
    in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2204
    @param aClientId A pointer to the LDD requesting the setting of the descriptor block.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2205
    @param aSettingNum The setting number of the interface that contains the endpoint for which the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2206
    descriptor block is to be set.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2207
    @param aEndpointNum The endpoint for which the descriptor block is to be set.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2208
    @param aEndpointDescriptor A reference to a buffer which contains the descriptor block to be set (most
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2209
    likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2210
    @param aSize The size of the descriptor block to be set.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2211
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2212
    @return KErrNotFound if the specified interface or endpoint couldn't be found, KErrArgument if aSize is
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2213
    less than 2, KErrNoMemory if enough memory for the new descriptor(s) couldn't be allocated, otherwise the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2214
    return value of the thread read operation, Kern::ThreadRead(), when reading from the source buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2215
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2216
EXPORT_C TInt DUsbClientController::SetCSEndpointDescriptorBlock(DThread* aThread, const DBase* aClientId,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2217
                                                                 TInt aSettingNum, TInt aEndpointNum,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2218
                                                                 const TDes8& aEndpointDescriptor, TInt aSize)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2219
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2220
    __KTRACE_OPT(KUSB,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2221
                 Kern::Printf("DUsbClientController::SetCSEndpointDescriptorBlock(x, 0x%08x, %d, %d, y)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2222
                              aClientId, aSettingNum, aEndpointNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2223
    const TInt ifcset = ClientId2InterfaceNumber(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2224
    if (ifcset < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2225
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2226
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Interface not found from client ID"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2227
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2228
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2229
    if (aSize < 2)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2230
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2231
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: aSize < 2 (%d)", aSize));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2232
        return KErrArgument;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2233
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2234
    return iDescriptors.SetCSEndpointDescriptorTC(aThread, aEndpointDescriptor, ifcset,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2235
                                                  aSettingNum, EpIdx2Addr(aEndpointNum), aSize);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2236
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2237
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2238
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2239
/** Returns the total size all non-standard (class-specific) endpoint descriptors for a specific endpoint.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2240
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2241
    @param aThread A pointer to the thread the LDD requesting the descriptor block size is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2242
    @param aClientId A pointer to the LDD requesting the descriptor block size.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2243
    @param aSettingNum The setting number of the interface for which the descriptor block size is
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2244
    requested.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2245
    @param aEndpointNum The endpoint for which the descriptor block size is requested.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2246
    @param aSize A reference to a buffer into which the requested descriptor block size should be written (most
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2247
    likely located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2248
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2249
    @return KErrNotFound if the specified interface or endpoint couldn't be found, otherwise the return value
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2250
    of the thread write operation, Kern::ThreadWrite(), when writing to the target buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2251
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2252
EXPORT_C TInt DUsbClientController::GetCSEndpointDescriptorBlockSize(DThread* aThread, const DBase* aClientId,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2253
                                                                     TInt aSettingNum, TInt aEndpointNum,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2254
                                                                     TDes8& aSize)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2255
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2256
    __KTRACE_OPT(KUSB,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2257
                 Kern::Printf("DUsbClientController::GetCSEndpointDescriptorBlockSize(x, 0x%08x, %d, %d, y)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2258
                              aClientId, aSettingNum, aEndpointNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2259
    const TInt ifcset = ClientId2InterfaceNumber(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2260
    if (ifcset < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2261
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2262
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Interface not found from client ID"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2263
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2264
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2265
    TInt s;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2266
    const TInt r = iDescriptors.GetCSEndpointDescriptorSize(ifcset, aSettingNum,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2267
                                                            EpIdx2Addr(aEndpointNum), s);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2268
    if (r == KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2269
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2270
        const TPtrC8 size(reinterpret_cast<const TUint8*>(&s), sizeof(s));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2271
        Kern::ThreadDesWrite(aThread, &aSize, size, 0);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2272
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2273
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2274
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2275
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: cs endpoint descriptor not found"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2276
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2277
    return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2278
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2279
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2280
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2281
/** Returns the currently set string descriptor language ID (LANGID) code.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2282
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2283
    @param aThread A pointer to the thread the LDD requesting the LANGID is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2284
    @param aLangId A reference to a buffer into which the requested code should be written (most likely
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2285
    located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2286
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2287
    @return The return value of the thread write operation, Kern::ThreadDesWrite(),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2288
    when writing to the target buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2289
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2290
EXPORT_C TInt DUsbClientController::GetStringDescriptorLangId(DThread* aThread, TDes8& aLangId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2291
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2292
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetStringDescriptorLangId()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2293
    return iDescriptors.GetStringDescriptorLangIdTC(aThread, aLangId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2294
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2295
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2296
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2297
/** Sets the string descriptor language ID (LANGID) code.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2298
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2299
    @param aLangId The langauge ID code to be written.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2300
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2301
    @return KErrNone.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2302
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2303
EXPORT_C TInt DUsbClientController::SetStringDescriptorLangId(TUint16 aLangId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2304
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2305
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetStringDescriptorLangId()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2306
    return iDescriptors.SetStringDescriptorLangId(aLangId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2307
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2308
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2309
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2310
/** Returns the currently set Manufacturer string (which is referenced by the iManufacturer field in the device
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2311
    descriptor).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2312
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2313
    (Thus, the function should actually be called either 'GetManufacturerString'
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2314
    or 'GetManufacturerStringDescriptorString'.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2315
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2316
    @param aThread A pointer to the thread the LDD requesting the string is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2317
    @param aString A reference to a buffer into which the requested string should be written (most likely
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2318
    located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2319
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2320
    @return KErrNotFound if the string descriptor couldn't be found (PIL internal error), otherwise the return
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2321
    value of the thread write operation, Kern::ThreadWrite(), when writing to the target buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2322
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2323
EXPORT_C TInt DUsbClientController::GetManufacturerStringDescriptor(DThread* aThread, TDes8& aString)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2324
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2325
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetManufacturerStringDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2326
    return iDescriptors.GetManufacturerStringDescriptorTC(aThread, aString);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2327
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2328
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2329
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2330
/** Sets a new Manufacturer string in the Manufacturer string descriptor (which is referenced by the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2331
    iManufacturer field in the device descriptor).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2332
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2333
    (Thus, the function should actually be called either
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2334
    'SetManufacturerString' or 'SetManufacturerStringDescriptorString'.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2335
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2336
    @param aThread A pointer to the thread the LDD requesting the setting of the string is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2337
    @param aString A reference to a buffer which contains the string to be set (most likely located
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2338
    user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2339
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2340
    @return KErrNoMemory if not enough memory for the new descriptor or the string could be allocated, the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2341
    return value of the thread read operation, Kern::ThreadRead(), if reading from the source buffer goes wrong,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2342
    KErrNone if new string descriptor successfully set.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2343
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2344
EXPORT_C TInt DUsbClientController::SetManufacturerStringDescriptor(DThread* aThread, const TDes8& aString)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2345
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2346
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetManufacturerStringDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2347
    return iDescriptors.SetManufacturerStringDescriptorTC(aThread, aString);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2348
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2349
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2350
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2351
/** Removes (deletes) the Manufacturer string descriptor (which is referenced by the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2352
    iManufacturer field in the device descriptor).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2353
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2354
    @return KErrNone if successful, KErrNotFound if the string descriptor couldn't be found
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2355
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2356
EXPORT_C TInt DUsbClientController::RemoveManufacturerStringDescriptor()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2357
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2358
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::RemoveManufacturerStringDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2359
    return iDescriptors.RemoveManufacturerStringDescriptor();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2360
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2361
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2362
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2363
/** Returns the currently set Product string (which is referenced by the iProduct field in the device
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2364
    descriptor).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2365
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2366
    (Thus, the function should actually be called either 'GetProductString' or
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2367
    'GetProductStringDescriptorString'.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2368
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2369
    @param aThread A pointer to the thread the LDD requesting the string is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2370
    @param aString A reference to a buffer into which the requested string should be written (most likely
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2371
    located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2372
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2373
    @return KErrNotFound if the string descriptor couldn't be found (PIL internal error), otherwise the return
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2374
    value of the thread write operation, Kern::ThreadWrite(), when writing to the target buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2375
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2376
EXPORT_C TInt DUsbClientController::GetProductStringDescriptor(DThread* aThread, TDes8& aString)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2377
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2378
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetProductStringDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2379
    return iDescriptors.GetProductStringDescriptorTC(aThread, aString);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2380
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2381
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2382
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2383
/** Sets a new Product string in the Product string descriptor (which is referenced by the iProduct field in
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2384
    the device descriptor).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2385
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2386
    (Thus, the function should actually be called either 'SetProductString' or
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2387
    'SetProductStringDescriptorString'.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2388
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2389
    @param aThread A pointer to the thread the LDD requesting the setting of the string is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2390
    @param aString A reference to a buffer which contains the string to be set (most likely located
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2391
    user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2392
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2393
    @return KErrNoMemory if not enough memory for the new descriptor or the string could be allocated, the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2394
    return value of the thread read operation, Kern::ThreadRead(), if reading from the source buffer goes wrong,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2395
    KErrNone if new string descriptor successfully set.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2396
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2397
EXPORT_C TInt DUsbClientController::SetProductStringDescriptor(DThread* aThread, const TDes8& aString)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2398
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2399
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetProductStringDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2400
    return iDescriptors.SetProductStringDescriptorTC(aThread, aString);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2401
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2402
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2403
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2404
/** Removes (deletes) the Product string descriptor (which is referenced by the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2405
    iProduct field in the device descriptor).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2406
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2407
    @return KErrNone if successful, KErrNotFound if the string descriptor couldn't be found
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2408
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2409
EXPORT_C TInt DUsbClientController::RemoveProductStringDescriptor()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2410
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2411
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::RemoveProductStringDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2412
    return iDescriptors.RemoveProductStringDescriptor();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2413
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2414
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2415
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2416
/** Returns the currently set SerialNumber string (which is referenced by the iSerialNumber field in the device
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2417
    descriptor).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2418
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2419
    (Thus, the function should actually be called either 'GetSerialNumberString' or
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2420
    'GetSerialNumberStringDescriptorString'.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2421
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2422
    @param aThread A pointer to the thread the LDD requesting the string is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2423
    @param aString A reference to a buffer into which the requested string should be written (most likely
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2424
    located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2425
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2426
    @return KErrNotFound if the string descriptor couldn't be found (PIL internal error), otherwise the return
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2427
    value of the thread write operation, Kern::ThreadWrite(), when writing to the target buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2428
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2429
EXPORT_C TInt DUsbClientController::GetSerialNumberStringDescriptor(DThread* aThread, TDes8& aString)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2430
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2431
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetSerialNumberStringDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2432
    return iDescriptors.GetSerialNumberStringDescriptorTC(aThread, aString);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2433
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2434
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2435
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2436
/** Sets a new SerialNumber string in the SerialNumber string descriptor (which is referenced by the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2437
    iSerialNumber field in the device descriptor).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2438
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2439
    (Thus, the function should actually be called either
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2440
    'SetSerialNumberString' or 'SetSerialNumberStringDescriptorString'.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2441
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2442
    @param aThread A pointer to the thread the LDD requesting the setting of the string is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2443
    @param aString A reference to a buffer which contains the string to be set (most likely located
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2444
    user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2445
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2446
    @return KErrNoMemory if not enough memory for the new descriptor or the string could be allocated, the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2447
    return value of the thread read operation, Kern::ThreadRead(), if reading from the source buffer goes wrong,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2448
    KErrNone if new string descriptor successfully set.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2449
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2450
EXPORT_C TInt DUsbClientController::SetSerialNumberStringDescriptor(DThread* aThread, const TDes8& aString)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2451
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2452
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetSerialNumberStringDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2453
    return iDescriptors.SetSerialNumberStringDescriptorTC(aThread, aString);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2454
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2455
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2456
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2457
/** Removes (deletes) the Serial Number string descriptor (which is referenced by the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2458
    iSerialNumber field in the device descriptor).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2459
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2460
    @return KErrNone if successful, KErrNotFound if the string descriptor couldn't be found
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2461
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2462
EXPORT_C TInt DUsbClientController::RemoveSerialNumberStringDescriptor()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2463
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2464
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::RemoveSerialNumberStringDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2465
    return iDescriptors.RemoveSerialNumberStringDescriptor();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2466
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2467
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2468
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2469
/** Returns the currently set Configuration string (which is referenced by the iConfiguration field in the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2470
    configuration descriptor).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2471
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2472
    (Thus, the function should actually be called either 'GetConfigurationString' or
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2473
    'GetConfigurationStringDescriptorString'.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2474
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2475
    @param aThread A pointer to the thread the LDD requesting the string is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2476
    @param aString A reference to a buffer into which the requested string should be written (most likely
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2477
    located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2478
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2479
    @return KErrNotFound if the string descriptor couldn't be found (PIL internal error), otherwise the return
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2480
    value of the thread write operation, Kern::ThreadWrite(), when writing to the target buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2481
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2482
EXPORT_C TInt DUsbClientController::GetConfigurationStringDescriptor(DThread* aThread, TDes8& aString)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2483
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2484
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetConfigurationStringDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2485
    return iDescriptors.GetConfigurationStringDescriptorTC(aThread, aString);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2486
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2487
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2488
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2489
/** Sets a new Configuration string in the Configuration string descriptor (which is referenced by the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2490
    iConfiguration field in the configuration descriptor).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2491
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2492
    (Thus, the function should actually be called either
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2493
    'SetConfigurationString' or 'SetConfigurationStringDescriptorString'.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2494
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2495
    @param aThread A pointer to the thread the LDD requesting the setting of the string is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2496
    @param aString A reference to a buffer which contains the string to be set (most likely located
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2497
    user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2498
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2499
    @return KErrNoMemory if not enough memory for the new descriptor or the string could be allocated, the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2500
    return value of the thread read operation, Kern::ThreadRead(), if reading from the source buffer goes wrong,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2501
    KErrNone if new string descriptor successfully set.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2502
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2503
EXPORT_C TInt DUsbClientController::SetConfigurationStringDescriptor(DThread* aThread, const TDes8& aString)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2504
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2505
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetConfigurationStringDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2506
    return iDescriptors.SetConfigurationStringDescriptorTC(aThread, aString);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2507
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2508
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2509
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2510
/** Removes (deletes) the Configuration string descriptor (which is referenced by the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2511
    iConfiguration field in the configuration descriptor).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2512
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2513
    @return KErrNone if successful, KErrNotFound if the string descriptor couldn't be found.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2514
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2515
EXPORT_C TInt DUsbClientController::RemoveConfigurationStringDescriptor()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2516
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2517
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::RemoveConfigurationStringDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2518
    return iDescriptors.RemoveConfigurationStringDescriptor();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2519
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2520
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2521
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2522
/** Copies the string descriptor at the specified index in the string descriptor array into
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2523
    the aString argument.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2524
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2525
    @param aIndex The position of the string descriptor in the string descriptor array.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2526
    @param aThread A pointer to the thread the LDD requesting the string is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2527
    @param aString A reference to a buffer into which the requested string should be written (most likely
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2528
    located user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2529
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2530
    @return KErrNone if successful, KErrNotFound if no string descriptor exists at the specified index, or the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2531
    return value of the thread write operation, Kern::ThreadWrite(), when writing to the target buffer.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2532
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2533
EXPORT_C TInt DUsbClientController::GetStringDescriptor(DThread* aThread, TUint8 aIndex, TDes8& aString)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2534
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2535
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::GetStringDescriptor(%d)", aIndex));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2536
    return iDescriptors.GetStringDescriptorTC(aThread, aIndex, aString);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2537
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2538
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2539
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2540
/** Sets the aString argument to be a string descriptor at the specified index in the string
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2541
    descriptor array. If a string descriptor already exists at that position then it will be replaced.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2542
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2543
    @param aIndex The position of the string descriptor in the string descriptor array.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2544
    @param aThread A pointer to the thread the LDD requesting the setting of the string is running in.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2545
    @param aString A reference to a buffer which contains the string to be set (most likely located
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2546
    user-side).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2547
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2548
    @return KErrNone if successful, KErrArgument if aIndex is invalid, KErrNoMemory if no memory is available
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2549
    to store the new string (an existing descriptor at that index will be preserved), or the return value of
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2550
    the thread read operation, Kern::ThreadRead(), if reading from the source buffer goes wrong.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2551
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2552
EXPORT_C TInt DUsbClientController::SetStringDescriptor(DThread* aThread, TUint8 aIndex, const TDes8& aString)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2553
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2554
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetStringDescriptor(%d)", aIndex));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2555
    return iDescriptors.SetStringDescriptorTC(aThread, aIndex, aString);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2556
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2557
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2558
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2559
/** Removes (deletes) the string descriptor at the specified index in the string descriptor array.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2560
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2561
    @param aIndex The position of the string descriptor in the string descriptor array.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2562
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2563
    @return KErrNone if successful, KErrNotFound if no string descriptor exists at the specified index.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2564
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2565
EXPORT_C TInt DUsbClientController::RemoveStringDescriptor(TUint8 aIndex)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2566
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2567
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::RemoveStringDescriptor(%d)", aIndex));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2568
    return iDescriptors.RemoveStringDescriptor(aIndex);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2569
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2570
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2571
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2572
/** Queries the use of and endpoint resource.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2573
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2574
    If the resource gets successfully allocated, it will be used from when the current bus transfer
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2575
    has been completed.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2576
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2577
    @param aClientId A pointer to the LDD querying the endpoint resource.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2578
    @param aEndpointNum The number of the endpoint.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2579
    @param aResource The endpoint resource to be queried.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2580
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2581
    @return ETrue if the specified resource is in use at the endpoint, EFalse if not or if there was any error
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2582
    during the execution of the function.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2583
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2584
EXPORT_C TBool DUsbClientController::QueryEndpointResource(const DBase* /*aClientId*/, TInt aEndpointNum,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2585
                                                           TUsbcEndpointResource aResource)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2586
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2587
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::QueryEndpointResource()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2588
    return iController.QueryEndpointResource(aEndpointNum, aResource);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2589
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2590
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2591
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2592
EXPORT_C TInt DUsbClientController::EndpointPacketSize(const DBase* aClientId, TInt aEndpointNum)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2593
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2594
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::EndpointPacketSize(0x%08x, %d)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2595
                                    aClientId, aEndpointNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2596
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2597
    const TUsbcInterfaceSet* const ifcset_ptr = ClientId2InterfacePointer(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2598
    if (!ifcset_ptr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2599
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2600
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: interface or clientid not found"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2601
        return -1;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2602
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2603
    const TUsbcInterface* const ifc_ptr = ifcset_ptr->iInterfaces[ifcset_ptr->iCurrentInterface];
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2604
    const RPointerArray<TUsbcLogicalEndpoint>& ep_array = ifc_ptr->iEndpoints;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2605
    const TInt n = ep_array.Count();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2606
    for (TInt i = 0; i < n; i++)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2607
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2608
        const TUsbcLogicalEndpoint* const ep = ep_array[i];
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2609
        if (EpAddr2Idx(ep->iPEndpoint->iEndpointAddr) == static_cast<TUint>(aEndpointNum))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2610
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2611
            __KTRACE_OPT(KUSB, Kern::Printf("  Endpoint packet sizes: FS = %d  HS = %d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2612
                                            ep->iEpSize_Fs, ep->iEpSize_Hs));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2613
            const TInt size = iHighSpeed ? ep->iEpSize_Hs : ep->iEpSize_Fs;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2614
            __KTRACE_OPT(KUSB, Kern::Printf("  Returning %d", size));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2615
            return size;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2616
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2617
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2618
    __KTRACE_OPT(KPANIC, Kern::Printf("  Error: endpoint not found"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2619
    return -1;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2620
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2621
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2622
EXPORT_C TDfcQue*  DUsbClientController::DfcQ(TInt /*aIndex*/)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2623
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2624
    return iControllerProperties.iDfcQueue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2625
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2626
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2627
EXPORT_C void DUsbClientController::DumpRegisters()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2628
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2629
    return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2630
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2631
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2632
EXPORT_C TInt DUsbClientController::SignalRemoteWakeup()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2633
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2634
    return iController.SignalRemoteWakeup();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2635
    }
48
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2636
/** Registers client request for USB charger type notification. Client is notified when USB device is
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2637
    attached to or detached from any USB charger, and the charger type is sent to client.
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2638
    
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2639
    @param aCallback A reference to a properly filled in charger type callback structure.
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2640
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2641
    @return KErrNone if callback successfully registered, KErrGeneral if this callback is already registered
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2642
    (it won't be registered twice).
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2643
*/
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2644
EXPORT_C TInt DUsbClientController::RegisterChargingPortTypeNotify(TUsbcChargerTypeCallback& aCallback)
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2645
    {
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2646
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::RegisterChargingPortTypeNotify()"));
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2647
    if (iChargerTypeCallbacks.Elements() == KUsbcMaxListLength)
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2648
        {
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2649
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: In charger type list, the maximum list length reached: %d",
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2650
                                          KUsbcMaxListLength));
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2651
        return KErrGeneral;
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2652
        }
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2653
    if (IsInTheChargerTypeList(aCallback))
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2654
        {
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2655
        __KTRACE_OPT(KUSB, Kern::Printf("  Error: UsbcChargerTypeCallback @ 0x%x already registered", &aCallback));
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2656
        return KErrGeneral;
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2657
        }
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2658
    const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2659
    iChargerTypeCallbacks.AddLast(aCallback);
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2660
    __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);    
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2661
    
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2662
    if(iCurrentChargerType !=  UsbShai::EPortTypeNone)
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2663
        {
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2664
        aCallback.SetChargerType(iCurrentChargerType);
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2665
        aCallback.SetPendingNotify(ETrue);
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2666
        }
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2667
    return KErrNone;
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2668
    }
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2669
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2670
/** De-registers (removes from the list of pending requests) a notification callback for
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2671
    USB charger type change.
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2672
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2673
    @param aClientId A pointer to the LDD owning the charger type callback.
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2674
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2675
    @return KErrNone if callback successfully unregistered, KErrNotFound if the callback couldn't be found.
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2676
*/
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2677
EXPORT_C TInt DUsbClientController::DeRegisterChargingPortTypeNotify(const DBase* aClientId)
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2678
    {
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2679
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeRegisterChargingPortTypeNotify()"));
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2680
    __ASSERT_DEBUG((aClientId != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2681
    const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2682
    TSglQueIter<TUsbcChargerTypeCallback> iter(iChargerTypeCallbacks);
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2683
    TUsbcChargerTypeCallback* p;
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2684
    while ((p = iter++) != NULL)
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2685
        {
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2686
        if (p->Owner() == aClientId)
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2687
            {
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2688
            __KTRACE_OPT(KUSB, Kern::Printf("  removing UsbcChargerTypeCallback @ 0x%x", p));
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2689
            iChargerTypeCallbacks.Remove(*p);
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2690
            __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2691
            return KErrNone;
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2692
            }
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2693
        }
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2694
    __KTRACE_OPT(KUSB, Kern::Printf("  client not found"));
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2695
    __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2696
    return KErrNotFound;
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2697
    }
33
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2698
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2699
EXPORT_C TBool DUsbClientController::CurrentlyUsingHighSpeed()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2700
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2701
    UsbShai::TSpeed speed = iController.DeviceOperatingSpeed();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2702
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2703
    return (speed == UsbShai::EHighSpeed)?ETrue:EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2704
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2705
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2706
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2707
// === USB Controller member function implementations - PSL API (public) ===========================
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2708
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2709
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2710
/** Gets called by the PSL to register a newly created derived class controller object.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2711
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2712
    @param aUdc The number of the new UDC. It should be 0 for the first (or only) UDC in the system, 1 for the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2713
    second one, and so forth. KUsbcMaxUdcs determines how many UDCs are supported.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2714
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2715
    @return A pointer to the controller if successfully registered, NULL if aUdc out of (static) range.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2716
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2717
    @publishedPartner @released
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2718
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2719
TInt DUsbClientController::RegisterUdc(TInt aUdc)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2720
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2721
    TInt err = KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2722
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2723
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::RegisterUdc()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2724
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2725
    if (aUdc < 0 || aUdc > (KUsbcMaxUdcs - 1))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2726
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2727
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: aUdc out of range (%d)", aUdc));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2728
        return KErrInUse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2729
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2730
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2731
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2732
        UsbClientController[aUdc] = this;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2733
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2734
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2735
    return err;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2736
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2737
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2738
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2739
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2740
// === USB Controller member function implementations - PSL API (protected) ========================
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2741
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2742
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2743
/** Initialises an instance of this class, which is the base class of the derived class (= PSL, which is
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2744
    supposed to call this function).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2745
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2746
    It does the following things:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2747
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2748
    - disconnects the UDC from the bus,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2749
    - initialises the USB descriptor pool, uses data from the PSL (see function argument list)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2750
    - creates and initialises the basic USB device configuration
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2751
    - initialises the array of physical endpoints
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2752
    - initialises Ep0 structures (but doesn't configure & enable Ep0 yet)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2753
    - creates and installs the USB power handler
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2754
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2755
    @param aDeviceDesc A pointer to a valid standard USB device descriptor or NULL. The values initially
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2756
    required in the descriptor follow from its constructor. The descriptor is not copied over, but rather this
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2757
    pointer is queued directly into the descriptor pool. Must be writable memory.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2758
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2759
    @param aConfigDesc A pointer to a valid standard USB configuration descriptor or NULL. The values
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2760
    initially required in the descriptor follow from its constructor. The descriptor is not copied over, but
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2761
    rather this pointer is queued directly into the descriptor pool. Must be writable memory.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2762
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2763
    @param aLangId A pointer to a valid USB language ID (string) descriptor. The values initially required in
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2764
    the descriptor follow from its constructor. The descriptor is not copied over, but rather this pointer is
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2765
    queued directly into the descriptor pool. Must be writable memory. Other than the remaining four string
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2766
    descriptors, this one is not optional. The reason is that the USB spec mandates a LangId descriptor as
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2767
    soon as a single string descriptor gets returned by the device. So, even though the device might omit the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2768
    Manufacturer, Product, SerialNumber, and Configuration string descriptors, it is at this point not known
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2769
    whether there will be any Interface string descriptors. Since any USB API user can create an interface
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2770
    with an Interface string descriptor, we have to insist here on the provision of a LangId string
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2771
    descriptor. (The PIL decides at run-time whether or not to return the LangId string descriptor to the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2772
    host, depending on whether there exist any string descriptors at that time.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2773
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2774
    @param aManufacturer A pointer to a valid USB string descriptor or NULL. The values initially required in
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2775
    the descriptor follow from its constructor. The descriptor is not copied over, but rather this pointer is
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2776
    queued directly into the descriptor pool. Must be writable memory. This descriptor will be referenced by
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2777
    the iManufacturer field in the device descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2778
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2779
    @param aProduct A pointer to a valid USB string descriptor or NULL. The values initially required in the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2780
    descriptor follow from its constructor. The descriptor is not copied over, but rather this pointer is
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2781
    queued directly into the descriptor pool. Must be writable memory. This descriptor will be referenced by
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2782
    the iProduct field in the device descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2783
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2784
    @param aSerialNum A pointer to a valid USB string descriptor or NULL. The values initially required in the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2785
    descriptor follow from its constructor. The descriptor is not copied over, but rather this pointer is
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2786
    queued directly into the descriptor pool. Must be writable memory. This descriptor will be referenced by
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2787
    the iSerialNumber field in the device descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2788
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2789
    @param aConfig A pointer to a valid USB string descriptor or NULL. The values initially required in the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2790
    descriptor follow from its constructor. The descriptor is not copied over, but rather this pointer is
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2791
    queued directly into the descriptor pool. Must be writable memory. This descriptor will be referenced by
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2792
    the iConfiguration field in the configuration descriptor.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2793
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2794
    @param aOtgDesc A pointer to a valid USB OTG descriptor (if OTG is supported by this device and is to be
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2795
    supported by the driver) or NULL. The values initially required in the descriptor follow from its
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2796
    constructor. The descriptor is not copied over, but rather this pointer is queued directly into the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2797
    descriptor pool. Must be writable memory.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2798
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2799
    @return EFalse, if USB descriptor pool initialisation fails, or if configuration creation fails, or if the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2800
    PSL reports more endpoints than the constant KUsbcMaxEndpoints permits, or if the Ep0 logical endpoint
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2801
    creation fails, or if the creation of the power handler fails; ETrue, if base class object successfully
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2802
    initialised.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2803
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2804
    @publishedPartner @released
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2805
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2806
TBool DUsbClientController::Initialise(TUsbPeripheralDescriptorPool& aDescPool,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2807
                                       const UsbShai::TUsbPeripheralEndpointCaps* aEndpointCaps,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2808
                                       TInt aTotalEndpoints)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2809
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2810
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::InitialiseBaseClass()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2811
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2812
    // We don't want the host to see us (at least not yet):
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2813
    UsbDisconnect();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2814
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2815
    iDeviceTotalEndpoints = aTotalEndpoints;    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2816
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2817
    // Initialise USB descriptor pool
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2818
    if (iDescriptors.Init(aDescPool.iDeviceDesc, 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2819
                          aDescPool.iConfigDesc, 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2820
                          aDescPool.iLangId, 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2821
                          aDescPool.iManufacturer, 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2822
                          aDescPool.iProduct,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2823
                          aDescPool.iSerialNum, 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2824
                          aDescPool.iConfig, 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2825
                          aDescPool.iOtgDesc) != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2826
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2827
        __KTRACE_OPT(KUSB, Kern::Printf("  Error: Descriptor initialization failed"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2828
        return EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2829
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2830
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2831
    if (aDescPool.iOtgDesc)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2832
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2833
        iOtgSupport = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2834
        iOtgFuncMap = aDescPool.iOtgDesc->DescriptorData()[2];
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2835
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2836
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2837
    // Some member variables
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2838
    iSelfPowered  = aDescPool.iConfigDesc->Byte(7) & (1 << 6);        // Byte 7: bmAttributes
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2839
    iRemoteWakeup = aDescPool.iConfigDesc->Byte(7) & (1 << 5);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2840
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2841
    if (iControllerProperties.iControllerCaps & UsbShai::KDevCapHighSpeed)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2842
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2843
        if (iDescriptors.InitHs() != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2844
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2845
            return EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2846
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2847
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2848
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2849
    // Create and initialise our first (and only) configuration
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2850
    TUsbcConfiguration* config = new TUsbcConfiguration(1);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2851
    if (!config)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2852
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2853
        return EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2854
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2855
    iConfigs.Append(config);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2856
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2857
    // Initialise the array of physical endpoints    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2858
    __KTRACE_OPT(KUSB, Kern::Printf("  DeviceTotalEndpoints: %d", aTotalEndpoints));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2859
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2860
    // KUsbcMaxEndpoints doesn't include ep 0
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2861
    if ((aTotalEndpoints > (KUsbcMaxEndpoints + 2)) ||
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2862
        ((aTotalEndpoints * sizeof(TUsbcPhysicalEndpoint)) > sizeof(iRealEndpoints)))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2863
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2864
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: too many endpoints! (change KUsbcMaxEndpoints: %d)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2865
                                          KUsbcMaxEndpoints));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2866
        return EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2867
        }      
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2868
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2869
    for (TInt i = 0; i < aTotalEndpoints; ++i)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2870
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2871
        iRealEndpoints[i].iEndpointAddr = EpIdx2Addr(i);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2872
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2873
        __KTRACE_OPT(KUSB, Kern::Printf("  aEndpointCaps[%02d] - iTypes: 0x%08x iSizes: 0x%08x",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2874
                                        i, aEndpointCaps[i].iTypesAndDir, aEndpointCaps[i].iSizes));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2875
                                                                                
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2876
        iRealEndpoints[i].iCaps = aEndpointCaps[i];
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2877
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2878
        // Reset revered bytes to zero
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2879
        iRealEndpoints[i].iCaps.iReserved[0] = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2880
        iRealEndpoints[i].iCaps.iReserved[1] = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2881
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2882
        if ((i > 1) && (aEndpointCaps[i].iTypesAndDir != UsbShai::KUsbEpNotAvailable))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2883
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2884
            __KTRACE_OPT(KUSB, Kern::Printf("  --> UsableEndpoint: #%d", i));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2885
            iDeviceUsableEndpoints++;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2886
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2887
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2888
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2889
    // Initialise Ep0 structures (logical endpoints are numbered 1..KMaxEndpointsPerClient,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2890
    // and virtual 0 is real 0):
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2891
    // -- Ep0 OUT
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2892
    iEp0MaxPacketSize = MaxEndpointPacketSize(aEndpointCaps[0].iSizes);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2893
    __KTRACE_OPT(KUSB, Kern::Printf("  using Ep0 maxpacketsize of %d bytes", iEp0MaxPacketSize));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2894
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2895
    TUsbcEndpointInfo info(UsbShai::KUsbEpTypeControl, UsbShai::KUsbEpDirOut, 0);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2896
    TUsbcLogicalEndpoint* ep = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2897
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2898
    info.iSize = iEp0MaxPacketSize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2899
    ep = new TUsbcLogicalEndpoint(this, 0, info, NULL, &iRealEndpoints[KEp0_Out]);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2900
    if (!ep)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2901
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2902
        return EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2903
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2904
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2905
    __KTRACE_OPT(KUSB, Kern::Printf("  creating ep: mapping real ep %d --> logical ep 0", KEp0_Out));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2906
    iRealEndpoints[KEp0_Out].iLEndpoint = ep;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2907
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2908
    // -- Ep0 IN
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2909
    info.iDir = UsbShai::KUsbEpDirIn;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2910
    ep = new TUsbcLogicalEndpoint(this, 0, info, NULL, &iRealEndpoints[KEp0_In]);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2911
    if (!ep)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2912
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2913
        delete iRealEndpoints[KEp0_Out].iLEndpoint;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2914
        iRealEndpoints[KEp0_Out].iLEndpoint = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2915
        return EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2916
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2917
    __KTRACE_OPT(KUSB, Kern::Printf("  creating ep: mapping real ep %d --> logical ep 0", KEp0_In));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2918
    iRealEndpoints[KEp0_In].iLEndpoint = ep;    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2919
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2920
    iPowerHandler = new DUsbcPowerHandler(this);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2921
    if (!iPowerHandler)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2922
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2923
        delete iRealEndpoints[KEp0_Out].iLEndpoint;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2924
        iRealEndpoints[KEp0_Out].iLEndpoint = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2925
        delete iRealEndpoints[KEp0_In].iLEndpoint;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2926
        iRealEndpoints[KEp0_In].iLEndpoint = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2927
        return EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2928
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2929
    iPowerHandler->Add();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2930
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2931
    return ETrue;    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2932
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2933
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2934
/** The standard constructor for this class.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2935
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2936
    @publishedPartner @released
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2937
 */
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2938
DUsbClientController::DUsbClientController(UsbShai::MPeripheralControllerIf&               aPeripheralControllerIf, 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2939
                                           const UsbShai::TPeripheralControllerProperties& aProperties,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2940
                                           TBool                                  aIsOtgPort)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2941
    : iEp0ReceivedNonStdRequest(EFalse),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2942
      iRmWakeupStatus_Enabled(EFalse),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2943
      iEp0_RxBuf(),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2944
      iDeviceTotalEndpoints(0),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2945
      iDeviceUsableEndpoints(0),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2946
      iDeviceState(UsbShai::EUsbPeripheralStateUndefined),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2947
      iDeviceStateB4Suspend(UsbShai::EUsbPeripheralStateUndefined),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2948
      iSelfPowered(EFalse),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2949
      iRemoteWakeup(EFalse),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2950
      iHardwareActivated(EFalse),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2951
      iOtgSupport(EFalse),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2952
      iOtgFuncMap(0),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2953
      iHighSpeed(EFalse),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2954
      iEp0MaxPacketSize(0),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2955
      iEp0ClientId(NULL),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2956
      iEp0DataReceived(0),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2957
      iEp0WritePending(EFalse),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2958
      iEp0ClientDataTransmitting(EFalse),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2959
      iEp0DeviceControl(NULL),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2960
      iDescriptors(iEp0_TxBuf),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2961
      iCurrentConfig(0),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2962
      iConfigs(1),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2963
      iRealEndpoints(),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2964
      iEp0_TxBuf(),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2965
      iEp0_RxExtraCount(0),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2966
      iEp0_TxNonStdCount(0),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2967
      iEp0ReadRequestCallbacks(_FOFF(TUsbcRequestCallback, iLink)),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2968
      iClientCallbacks(_FOFF(TUsbcClientCallback, iLink)),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2969
      iStatusCallbacks(_FOFF(TUsbcStatusCallback, iLink)),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2970
      iEpStatusCallbacks(_FOFF(TUsbcEndpointStatusCallback, iLink)),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2971
      iOtgCallbacks(_FOFF(TUsbcOtgFeatureCallback, iLink)),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2972
      iReconnectTimer(ReconnectTimerCallback, this),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2973
      iUsbLock(TSpinLock::EOrderGenericIrqLow3),      
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2974
      iController(aPeripheralControllerIf),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2975
      iControllerProperties(aProperties),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2976
      iIsOtgPort(aIsOtgPort),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2977
      iOtgObserver(NULL),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2978
      iConTransferMgr(NULL),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2979
      iLastError(EFalse),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2980
      iSetupPacketPending(EFalse),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2981
      iCommonDfcQThread(NULL),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2982
      iPowerUpDfc(PowerUpDfc, this, 3),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2983
      iPowerDownDfc(PowerDownDfc, this, 3),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2984
      iDeviceEventNotifyDfc(DeviceEventNotifyDfc,this,3),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2985
      iThreadContextFinder(ThreadContextFinderDfc,this,3),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2986
      iStandby(EFalse),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2987
      iStackIsActive(EFalse),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2988
      iClientSupportReady(EFalse),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2989
      iUsbResetDeferred(EFalse),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2990
      iEnablePullUpOnDPlus(NULL),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2991
      iDisablePullUpOnDPlus(NULL),
48
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2992
      iOtgContext(NULL),
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2993
	  iChargerTypeCallbacks(_FOFF(TUsbcChargerTypeCallback, iLink)),
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2994
	  iCurrentChargerType(UsbShai::EPortTypeNone)
33
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2995
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2996
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DUsbClientController()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  2997
    
48
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2998
    // Note that we take a direct copy of the controller properties in
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  2999
    // the initialization list for now. If fields are later added to
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  3000
    // the properties class in the SHAI, we need to start copying
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  3001
    // field-by-field and check the PSL reported capabilities before
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  3002
    // accessing a field that may not be present in an older PSL
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  3003
    // binary.
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  3004
33
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3005
    iLastError = KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3006
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3007
#ifndef SEPARATE_USB_DFC_QUEUE
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3008
    iPowerUpDfc.SetDfcQ(Kern::DfcQue0());
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3009
    iPowerDownDfc.SetDfcQ(Kern::DfcQue0());
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3010
#endif // SEPARATE_USB_DFC_QUEUE
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3011
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3012
    for (TInt i = 0; i < KUsbcEpArraySize; i++)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3013
        iRequestCallbacks[i] = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3014
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3015
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3016
TInt DUsbClientController::Construct()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3017
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3018
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::Construct"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3019
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3020
    // Setup the state machines of ep0
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3021
    TInt err = SetupEp0StateMachine();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3022
    if( err != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3023
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3024
        __KTRACE_OPT(KUSB, Kern::Printf("    Can not setup state machines, exit"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3025
        return err;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3026
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3027
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3028
#ifdef SEPARATE_USB_DFC_QUEUE
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3029
    iPowerUpDfc.SetDfcQ(iControllerProperties.iDfcQueue);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3030
    iPowerDownDfc.SetDfcQ(iControllerProperties.iDfcQueue);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3031
#endif  // SEPARATE_USB_DFC_QUEUE
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3032
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3033
    iDeviceEventNotifyDfc.SetDfcQ(iControllerProperties.iDfcQueue);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3034
    iThreadContextFinder.SetDfcQ(iControllerProperties.iDfcQueue);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3035
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3036
    // Register 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3037
    if( RegisterUdc(0) != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3038
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3039
        // This is the only reason.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3040
        return KErrInUse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3041
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3042
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3043
    __KTRACE_OPT(KUSB, Kern::Printf("    peripheral controller registered"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3044
    TUsbPeripheralDescriptorPool descPool;       
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3045
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3046
    if( CreateDescriptors(descPool) == KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3047
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3048
        __KTRACE_OPT(KUSB, Kern::Printf("    descriptors created"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3049
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3050
        // Initialise the array of physical endpoints 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3051
        __KTRACE_OPT(KUSB, Kern::Printf("    initialising PIL "));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3052
        TBool initOk = Initialise(descPool,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3053
                                  iControllerProperties.iDeviceEndpointCaps,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3054
                                  iControllerProperties.iDeviceTotalEndpoints);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3055
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3056
        // Let UDC has a changes to know the callback interface is ready.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3057
        // Any further initialization/startup/preparation etc can be performed now.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3058
        if  ( initOk )
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3059
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3060
            __KTRACE_OPT(KUSB, Kern::Printf("    Initializing PSL "));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3061
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3062
            // Set Rx buffer for endpoint zero
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3063
            iController.SetEp0RxBuffer(iEp0_RxBuf,KUsbcBufSzControl);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3064
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3065
            // Set pil callback interface for PSL.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3066
            iController.SetPilCallbackInterface(*this);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3067
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3068
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3069
        else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3070
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3071
            return KErrNoMemory;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3072
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3073
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3074
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3075
    // Register ourself as the ONLY one client of charger detection observer
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3076
    gChargerObsever = this;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3077
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3078
    // In case the charger detector already registered, start monitor
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3079
    // Charger type notifications
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3080
    if( gChargerDetector != NULL )
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3081
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3082
        gChargerDetector->SetChargerDetectorObserver(*gChargerObsever);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3083
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3084
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3085
    iThreadContextFinder.Enque();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3086
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3087
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3088
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3089
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3090
// This function doesn't consider the situation of OOM.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3091
// Because, this function will be call during extension's entry point,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3092
// There is no way to start up phone successfully if anything failed anyway...
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3093
TInt DUsbClientController::SetupEp0StateMachine()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3094
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3095
	// Create the state machine first
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3096
	__ASSERT_DEBUG((iConTransferMgr == NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3097
	iConTransferMgr = new DControlTransferManager(*this);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3098
	if(iConTransferMgr == 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3099
		{
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3100
		return KErrNoMemory;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3101
		}
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3102
		
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3103
    // Add UsbShai::EControlTransferStageSetup stage machine
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3104
    TControlStageSm* stageSm = new DSetupStageSm(*iConTransferMgr);    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3105
    __ASSERT_DEBUG((stageSm != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3106
    if(stageSm != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3107
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3108
        iConTransferMgr->AddState(UsbShai::EControlTransferStageSetup,*stageSm);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3109
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3110
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3111
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3112
        return KErrNoMemory;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3113
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3114
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3115
    // Add EControlTransferStageDataOut stage state machine        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3116
    stageSm = new DDataOutStageSm(*iConTransferMgr);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3117
    __ASSERT_DEBUG((stageSm != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3118
    if(stageSm != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3119
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3120
        iConTransferMgr->AddState(UsbShai::EControlTransferStageDataOut,*stageSm);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3121
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3122
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3123
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3124
        // we don't need bother to delete the previous allocated memory
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3125
        // system can not bootup if we return error
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3126
        return KErrNoMemory;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3127
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3128
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3129
    // Add EControlTransferStageStatusIn stage state machine     
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3130
    stageSm = new DStatusInStageSm(*iConTransferMgr);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3131
    __ASSERT_DEBUG((stageSm != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3132
    if(stageSm != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3133
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3134
        iConTransferMgr->AddState(UsbShai::EControlTransferStageStatusIn,*stageSm); 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3135
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3136
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3137
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3138
        return KErrNoMemory;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3139
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3140
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3141
    // Add EControlTransferStageDataIn stage state machine    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3142
    stageSm = new DDataInStageSm(*iConTransferMgr);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3143
    __ASSERT_DEBUG((stageSm != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3144
   if(stageSm != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3145
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3146
        iConTransferMgr->AddState(UsbShai::EControlTransferStageDataIn,*stageSm);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3147
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3148
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3149
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3150
        return KErrNoMemory;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3151
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3152
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3153
    // Add EControlTransferStageStatusOut stage state machine    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3154
    stageSm = new DStatusOutStageSm(*iConTransferMgr);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3155
    __ASSERT_DEBUG((stageSm != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3156
    if(stageSm != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3157
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3158
        iConTransferMgr->AddState(UsbShai::EControlTransferStageStatusOut,*stageSm);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3159
        }    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3160
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3161
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3162
        return KErrNoMemory;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3163
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3164
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3165
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3166
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3167
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3168
// ---------------------------------------------------------------------------
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3169
// From MUsbPeripheralPilCallbackIf.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3170
// Enable the peripheral stack
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3171
// ---------------------------------------------------------------------------
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3172
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3173
void DUsbClientController::EnablePeripheralStack()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3174
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3175
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::EnablePeripheralStack"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3176
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3177
    if (iStackIsActive)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3178
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3179
        __KTRACE_OPT(KUSB, Kern::Printf("  Already enabled - returning"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3180
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3181
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3182
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3183
    // Mark stack is enabled, Waiting upper application to power controller
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3184
    // Anyway, this will lead us to attached state
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3185
    iStackIsActive = ETrue;    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3186
    NextDeviceState(UsbShai::EUsbPeripheralStateAttached);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3187
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3188
    // If hardware is not activated yet, do it here.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3189
    if(iClientSupportReady && !iHardwareActivated)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3190
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3191
        // PowerUpUdc only do Activating Hardware when there are at least 1
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3192
        // Iterface registered.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3193
        PowerUpUdc();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3194
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3195
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3196
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3197
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3198
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3199
// ---------------------------------------------------------------------------
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3200
// From MUsbPeripheralPilCallbackIf.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3201
// Disable the peripheral stack
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3202
// ---------------------------------------------------------------------------
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3203
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3204
void DUsbClientController::DisablePeripheralStack()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3205
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3206
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DisablePeripheralStack"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3207
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3208
    if (!iStackIsActive)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3209
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3210
        __KTRACE_OPT(KUSB, Kern::Printf("  Already disabled - returning"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3211
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3212
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3213
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3214
    // Reset OTG features, leave attributes as is (just as in USB Reset case)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3215
    // (OTG spec 1.3 sections 6.5.x all say "... on a bus reset or at the end
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3216
    //  of a session." VBus drop is the end of a session.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3217
    iOtgFuncMap &= KUsbOtgAttr_SrpSupp | KUsbOtgAttr_HnpSupp;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3218
    OtgFeaturesNotify();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3219
    // Tear down the current configuration (if any)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3220
    ChangeConfiguration(0);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3221
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3222
    if (iDeviceState != UsbShai::EUsbPeripheralStateUndefined)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3223
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3224
        // Not being in state UNDEFINED implies that the cable is inserted.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3225
        if (iHardwareActivated)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3226
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3227
            NextDeviceState(UsbShai::EUsbPeripheralStatePowered);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3228
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3229
        // (If the hardware is NOT activated at this point, we can only be in
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3230
        //    state UsbShai::EUsbPeripheralStateAttached, so we don't have to move to it.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3231
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3232
    DeActivateHardwareController();                     // turn off UDC altogether
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3233
    iStackIsActive = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3234
    // Notify registered clients on the user side about a USB device state
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3235
    // change event and a transition to the "Undefined" state.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3236
    // Note: the state should be changed to "Undefined" before calling RunClientCallbacks(), 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3237
    //       otherwise the "Undefined" state will probably be lost.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3238
    NextDeviceState(UsbShai::EUsbPeripheralStateUndefined);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3239
    // Complete all pending requests, returning KErrDisconnected
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3240
    RunClientCallbacks();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3241
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3242
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3243
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3244
// ---------------------------------------------------------------------------
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3245
// From MUsbPeripheralPilCallbackIf.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3246
// Set the OTG Observer
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3247
// ---------------------------------------------------------------------------
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3248
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3249
void DUsbClientController::SetOtgObserver(MUsbOtgPeripheralObserverIf* aObserver)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3250
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3251
    iOtgObserver = aObserver;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3252
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3253
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3254
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3255
/** This function gets called by the PSL upon detection of either of the following events:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3256
    - USB Reset,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3257
    - USB Suspend event,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3258
    - USB Resume signalling,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3259
    - The USB cable has been attached (inserted) or detached (removed).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3260
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3261
    @param anEvent An enum denoting the event that has occured.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3262
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3263
    @return KErrArgument if the event is not recognized, otherwise KErrNone.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3264
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3265
    @publishedPartner @released
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3266
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3267
TInt DUsbClientController::DeviceEventNotification(UsbShai::TUsbPeripheralEvent anEvent)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3268
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3269
    TInt err = KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3270
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3271
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeviceEventNotification(anEvent=%d)", anEvent));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3272
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3273
    switch (anEvent)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3274
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3275
        case UsbShai::EUsbEventSuspend:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3276
        case UsbShai::EUsbEventResume:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3277
        case UsbShai::EUsbEventReset:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3278
        case UsbShai::EUsbEventVbusRisen:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3279
        case UsbShai::EUsbEventVbusFallen:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3280
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3281
            TInt nkern_curr_ctx= NKern::CurrentContext();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3282
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3283
            if( (nkern_curr_ctx != NKern::EInterrupt) && (nkern_curr_ctx != NKern::EIDFC))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3284
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3285
                // Normal context
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3286
                __ASSERT_DEBUG((iCommonDfcQThread != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3287
                if(iCommonDfcQThread == &(Kern::CurrentThread().iNThread))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3288
                    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3289
                    // we already in the correct context, just run processes here directly.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3290
                    __KTRACE_OPT(KUSB, Kern::Printf("  Correct thread context"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3291
                    ProcessDeviceEventNotification(anEvent);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3292
                    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3293
                else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3294
                    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3295
                    // we're in a normal thread, but it is not the same as the DfcQ context
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3296
                    // passed by PSL, queue it
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3297
                    __KTRACE_OPT(KUSB, Kern::Printf("  Incorrect thread context"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3298
                    iDevEventQueue.FifoAdd(anEvent);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3299
                    iDeviceEventNotifyDfc.Enque();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3300
                    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3301
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3302
            else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3303
                {                
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3304
                // We're in a ISR or IDFC context
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3305
                __KTRACE_OPT(KUSB, Kern::Printf("  ISR|IDFC context"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3306
                iDevEventQueue.FifoAdd(anEvent);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3307
                iDeviceEventNotifyDfc.Add();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3308
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3309
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3310
            break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3311
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3312
        default:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3313
            err = KErrArgument;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3314
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3315
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3316
    return err;    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3317
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3318
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3319
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3320
/** This function gets called by the PSL upon completion of a pending data transfer request.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3321
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3322
    This function is not to be used for endpoint zero completions (use Ep0RequestComplete instead).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3323
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3324
    @param aCallback A pointer to a data transfer request callback structure which was previously passed to
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3325
    the PSL in a SetupReadBuffer() or SetupWriteBuffer() call.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3326
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3327
    @publishedPartner @released
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3328
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3329
void DUsbClientController::EndpointRequestComplete(UsbShai::TUsbPeripheralRequest* aCallback)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3330
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3331
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::EndpointRequestComplete(%p)", aCallback));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3332
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3333
    TUsbcRequestCallback* cb = static_cast<TUsbcRequestCallback*>(aCallback);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3334
    // This function may be called by the PSL from within an ISR -- so we have
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3335
    // to take care what we do here (and also in all functions that get called
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3336
    // from here).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3337
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3338
    // We don't test aCallback for NULL here (and therefore risk a crash)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3339
    // because the PSL should never give us a NULL argument. If it does it
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3340
    // means the PSL is buggy and ought to be fixed.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3341
    ProcessDataTransferDone(*cb);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3342
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3343
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3344
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3345
/** This function should be called by the PSL after reception of an Ep0
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3346
    SET_FEATURE request with a feature selector of either {b_hnp_enable,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3347
    a_hnp_support, a_alt_hnp_support}, but only when that Setup packet is not
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3348
    handed up to the PIL (for instance because it is auto-decoded and
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3349
    'swallowed' by the UDC hardware).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3350
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3351
    @param aHnpState A bitmask indicating the present state of the three OTG
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3352
    feature selectors as follows:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3353
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3354
    bit.0 == a_alt_hnp_support
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3355
    bit.1 == a_hnp_support
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3356
    bit.2 == b_hnp_enable
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3357
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3358
    @see DUsbClientController::ProcessSetClearDevFeature()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3359
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3360
    @publishedPartner @released
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3361
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3362
void DUsbClientController::HandleHnpRequest(TInt aHnpState)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3363
// This function is called by the PSL from within an ISR -- so we have to take care what we do here
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3364
// (and also in all functions that get called from here).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3365
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3366
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::HandleHnpRequest(%d)", aHnpState));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3367
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3368
    if (!iOtgSupport)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3369
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3370
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Request only supported on a OTG device"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3371
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3372
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3373
    if (!(iOtgFuncMap & KUsbOtgAttr_HnpSupp))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3374
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3375
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Request only valid if OTG device supports HNP"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3376
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3377
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3378
    //    (case KUsbFeature_B_HnpEnable:)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3379
    if (aHnpState & 0x04)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3380
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3381
        iOtgFuncMap |= KUsbOtgAttr_B_HnpEnable;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3382
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3383
    // (case KUsbFeature_A_HnpSupport:)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3384
    if (aHnpState & 0x02)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3385
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3386
        iOtgFuncMap |= KUsbOtgAttr_A_HnpSupport;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3387
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3388
    // (case KUsbFeature_A_AltHnpSupport:)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3389
    if (aHnpState & 0x01)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3390
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3391
        iOtgFuncMap |= KUsbOtgAttr_A_AltHnpSupport;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3392
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3393
    OtgFeaturesNotify();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3394
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3395
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3396
void DUsbClientController::GetEp0RxBufferInfo(TUint8*& aBuffer, TInt& aBufferLen)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3397
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3398
    aBuffer = iEp0_RxBuf;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3399
    aBufferLen = KUsbcBufSzControl;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3400
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3401
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3402
UsbShai::TUsbPeripheralState DUsbClientController::DeviceStatus() const
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3403
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3404
    return iDeviceState;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3405
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3406
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3407
TBool DUsbClientController::Ep0ReceivedNonStdRequest()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3408
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3409
    return iEp0ReceivedNonStdRequest;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3410
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3411
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3412
/** This function gets called by the PSL upon completion of a pending endpoint zero data transfer request.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3413
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3414
    @param aRealEndpoint Either 0 for Ep0 OUT (= Read), or 1 for Ep0 IN (= Write).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3415
    @param aCount The number of bytes received or transmitted, respectively.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3416
    @param aError The error status of the completed transfer request. Can be KErrNone if no error, KErrCancel
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3417
    if transfer was cancelled, or KErrPrematureEnd if a premature status end was encountered.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3418
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3419
    @return KErrNone if no error during transfer completion processing, KErrGeneral if the request was a read &
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3420
    a Setup packet was received & the recipient for that packet couldn't be found (invalid packet: Ep0 has been
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3421
    stalled), KErrNotFound if the request was a read & the recipient for that packet (Setup or data) _was_
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3422
    found - however no read had been set up by that recipient (this case should be used by the PSL to disable
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3423
    the Ep0 interrupt at that point and give the LDD time to set up a new Ep0 read; once the 'missing' read
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3424
    was set up either Ep0ReceiveProceed or Ep0ReadSetupPktProceed will be called by the PIL).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3425
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3426
    @publishedPartner @released
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3427
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3428
TInt DUsbClientController::Ep0RequestComplete(TInt aRealEndpoint,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3429
                                              TInt aCount, 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3430
                                              TInt aError, 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3431
                                              UsbShai::TControlPacketType aPktType)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3432
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3433
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::Ep0RequestComplete(%d)", aRealEndpoint));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3434
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3435
    iLastError = KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3436
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3437
    iConTransferMgr->Ep0RequestComplete(iEp0_RxBuf,aCount,aError,aPktType);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3438
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3439
    __KTRACE_OPT(KUSB, Kern::Printf("    iLastError(%d)", iLastError));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3440
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3441
    if(iEp0WritePending == EFalse)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3442
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3443
        iConTransferMgr->SetupEndpointZeroRead();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3444
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3445
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3446
    __KTRACE_OPT(KUSB, Kern::Printf("< DUsbClientController::Ep0RequestComplete"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3447
    return iLastError;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3448
    }    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3449
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3450
/** This function should be called by the PSL once the UDC (and thus the USB device) is in the Address state.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3451
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3452
    @publishedPartner @released
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3453
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3454
void DUsbClientController::MoveToAddressState()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3455
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3456
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::MoveToAddressState()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3457
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3458
    // This function may be called by the PSL from within an ISR -- so we have
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3459
    // to take care what we do here (and also in all functions that get called
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3460
    // from here).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3461
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3462
    NextDeviceState(UsbShai::EUsbPeripheralStateAddress);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3463
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3464
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3465
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3466
TBool DUsbClientController::CreateDescriptors(TUsbPeripheralDescriptorPool& aOutput)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3467
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3468
    TInt errCode = KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3469
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3470
    // Create all the string descriptors
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3471
    TUsbcDeviceDescriptor* deviceDesc = TUsbcDeviceDescriptor::New(
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3472
                                                0,     // aDeviceClass, will be changed later by upper app
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3473
                                                0,     // aDeviceSubClass, will be changed later by upper app
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3474
                                                0,     // aDeviceProtocol, will be changed later by upper app
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3475
                                                iControllerProperties.iMaxEp0Size  ,   // aMaxPacketSize0
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3476
                                                KUsbVendorId,           // aVendorId
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3477
                                                KUsbProductId ,         // aProductId
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3478
                                                iControllerProperties.iDeviceRelease,         // aDeviceRelease
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3479
                                                KUsbNumberOfConfiguration);// aNumConfigurations
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3480
    __ASSERT_DEBUG( (deviceDesc != NULL), Kern::Fault( "USB PSL Out of memory, deviceDesc", __LINE__ ));    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3481
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3482
    TUsbcConfigDescriptor* configDesc = TUsbcConfigDescriptor::New(
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3483
                                            1,       // Only one configruation is supported current.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3484
                                            EFalse,  // at here, we always mark it as bus powered.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3485
                                            (iControllerProperties.iControllerCaps & UsbShai::KDevCapRemoteWakeupSupport)?ETrue:EFalse,  // remote wakeup
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3486
                                            100);    // 100 is a default value, thise value will be changed by
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3487
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3488
    __ASSERT_DEBUG( (configDesc != NULL), Kern::Fault( "USB PSL Out of memory, configDesc", __LINE__ ));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3489
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3490
    TUsbcLangIdDescriptor* stringDescLang = TUsbcLangIdDescriptor::New(KUsbLangId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3491
    __ASSERT_DEBUG( (stringDescLang != NULL), Kern::Fault( "USB PSL Out of memory, stringDescLang", __LINE__ ));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3492
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3493
    // Default manufacturer string
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3494
    TPtrC8 aString;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3495
    aString.Set(reinterpret_cast<const TUint8*>(KStringManufacturer), sizeof(KStringManufacturer) - 2);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3496
    TUsbcStringDescriptor* stringDescManu = TUsbcStringDescriptor::New(aString);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3497
    __ASSERT_DEBUG( (stringDescManu != NULL), Kern::Fault( "USB PSL Out of memory, stringDescManu", __LINE__ ));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3498
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3499
    // Default product name string
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3500
    aString.Set(reinterpret_cast<const TUint8*>(KStringProduct), sizeof(KStringProduct) - 2);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3501
    TUsbcStringDescriptor* stringDescProd = TUsbcStringDescriptor::New(aString);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3502
    __ASSERT_DEBUG( (stringDescProd != NULL), Kern::Fault( "USB PSL Out of memory, stringDescProd", __LINE__ ));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3503
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3504
    // Default configuration name string
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3505
    aString.Set(reinterpret_cast<const TUint8*>(KStringConfig), sizeof(KStringConfig) - 2);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3506
    TUsbcStringDescriptor* stringDescConf = TUsbcStringDescriptor::New(aString);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3507
    __ASSERT_DEBUG( (stringDescConf != NULL), Kern::Fault( "USB PSL Out of memory, stringDescConf", __LINE__ ));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3508
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3509
    // Default serial bumber string
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3510
    aString.Set(reinterpret_cast<const TUint8*>(KStringSerial), sizeof(KStringSerial) - 2);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3511
    TUsbcStringDescriptor* stringSerial = TUsbcStringDescriptor::New(aString);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3512
    __ASSERT_DEBUG( (stringSerial != NULL), Kern::Fault( "USB PSL Out of memory, stringDescConf", __LINE__ ));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3513
   
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3514
    TUsbcOtgDescriptor* otgDesc = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3515
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3516
    // In an OTG-environment, we also need to create the OTG
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3517
    // descriptor. The PSL supports both HNP and SRP and hence we
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3518
    // report support for them. Upper layers will override the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3519
    // descriptors anyway.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3520
    if (iIsOtgPort)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3521
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3522
        TBool srpSupported = (iControllerProperties.iControllerCaps & UsbShai::KDevCapSrpSupport)?ETrue:EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3523
        TBool hnpSupported = (iControllerProperties.iControllerCaps & UsbShai::KDevCapHnpSupport)?ETrue:EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3524
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3525
        otgDesc = TUsbcOtgDescriptor::New(srpSupported,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3526
                                          hnpSupported);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3527
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3528
        __ASSERT_DEBUG( (otgDesc != NULL), Kern::Fault( "USB PSL Out of memory, otgDesc", __LINE__ ));     
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3529
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3530
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3531
    if( (deviceDesc != NULL) && 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3532
        (configDesc != NULL) && 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3533
        (stringDescLang != NULL) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3534
        (stringDescManu != NULL) && 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3535
        (stringDescProd != NULL) && 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3536
        (stringDescConf != NULL) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3537
        ((!iIsOtgPort) || (iIsOtgPort && (otgDesc != NULL))))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3538
        {    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3539
        aOutput.iDeviceDesc = deviceDesc;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3540
        aOutput.iConfigDesc = configDesc;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3541
        aOutput.iLangId = stringDescLang;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3542
        aOutput.iManufacturer = stringDescManu;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3543
        aOutput.iProduct = stringDescProd;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3544
        aOutput.iConfig = stringDescConf;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3545
        aOutput.iSerialNum = stringSerial;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3546
        aOutput.iOtgDesc = otgDesc;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3547
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3548
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3549
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3550
        if( deviceDesc != NULL )
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3551
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3552
            delete deviceDesc;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3553
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3554
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3555
        if( configDesc != NULL )
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3556
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3557
            delete configDesc;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3558
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3559
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3560
        if( stringDescLang != NULL )
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3561
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3562
            delete stringDescLang;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3563
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3564
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3565
        if( stringDescManu != NULL )
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3566
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3567
            delete stringDescManu;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3568
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3569
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3570
        if( stringDescProd != NULL )
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3571
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3572
            delete stringDescProd;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3573
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3574
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3575
        if( stringDescConf != NULL )
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3576
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3577
            delete stringDescConf;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3578
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3579
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3580
        if( stringSerial != NULL )
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3581
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3582
            delete stringSerial;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3583
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3584
            
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3585
        if( otgDesc != NULL )
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3586
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3587
            delete otgDesc;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3588
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3589
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3590
        errCode = KErrNoMemory;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3591
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3592
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3593
    // We don't support serial number 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3594
    aOutput.iSerialNum = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3595
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3596
    return errCode;    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3597
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3598
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3599
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3600
// === USB Controller member function implementations - Internal utility functions (private) =======
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3601
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3602
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3603
TInt DUsbClientController::DeRegisterClientCallback(const DBase* aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3604
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3605
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeRegisterClientCallback()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3606
    __ASSERT_DEBUG((aClientId != NULL), Kern::Fault(KUsbPILPanicCat, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3607
    TSglQueIter<TUsbcClientCallback> iter(iClientCallbacks);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3608
    TUsbcClientCallback* p;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3609
    while ((p = iter++) != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3610
        if (p->Owner() == aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3611
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3612
            __KTRACE_OPT(KUSB, Kern::Printf("  removing ClientCallback @ 0x%x", p));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3613
            iClientCallbacks.Remove(*p);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3614
            return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3615
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3616
    __KTRACE_OPT(KUSB, Kern::Printf("  Client not found"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3617
    return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3618
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3619
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3620
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3621
TBool DUsbClientController::CheckEpAvailability(TInt aEndpointsUsed,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3622
                                                const TUsbcEndpointInfoArray& aEndpointData,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3623
                                                TInt aIfcNumber) const
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3624
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3625
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::CheckEpAvailability()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3626
    if (aEndpointsUsed > KMaxEndpointsPerClient)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3627
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3628
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: too many endpoints claimed (%d)", aEndpointsUsed));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3629
        return EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3630
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3631
    TBool reserve[KUsbcEpArraySize]; // iDeviceTotalEndpoints can be equal to 32
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3632
    memset(reserve, EFalse, sizeof(reserve));                // reset the array
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3633
    for (TInt i = 0; i < aEndpointsUsed; ++i)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3634
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3635
        __KTRACE_OPT(KUSB, Kern::Printf("  checking for (user) endpoint #%d availability...", i + 1));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3636
        TInt j = 2;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3637
        while (j < iDeviceTotalEndpoints)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3638
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3639
            if ((iRealEndpoints[j].EndpointSuitable(&aEndpointData[i], aIfcNumber)) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3640
                (reserve[j] == EFalse))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3641
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3642
                __KTRACE_OPT(KUSB, Kern::Printf("  ---> found suitable endpoint: RealEndpoint #%d", j));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3643
                reserve[j] = ETrue;                            // found one: mark this ep as reserved
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3644
                break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3645
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3646
            __KTRACE_OPT(KUSB, Kern::Printf("  -> endpoint not suitable: RealEndpoint #%d", j));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3647
            j++;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3648
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3649
        if (j == iDeviceTotalEndpoints)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3650
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3651
            return EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3652
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3653
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3654
    return ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3655
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3656
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3657
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3658
TUsbcInterface* DUsbClientController::CreateInterface(const DBase* aClientId, TInt aIfc, TUint32 aFeatureWord)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3659
// We know that 9.2.3 says: "Interfaces are numbered from zero to one less than the number of
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3660
// concurrent interfaces supported by the configuration."  But since we permit the user to
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3661
// change interface numbers, we can neither assume nor enforce anything about them here.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3662
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3663
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::CreateInterface(x, aIfc=%d)", aIfc));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3664
    TUsbcInterfaceSet* ifcset_ptr = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3665
    TInt ifcset = ClientId2InterfaceNumber(aClientId);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3666
    TBool new_ifc;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3667
    if (ifcset < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3668
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3669
        // New interface(set), so we need to find a number for it.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3670
        new_ifc = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3671
        const TInt num_ifcsets = iConfigs[0]->iInterfaceSets.Count();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3672
        if (num_ifcsets == 255)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3673
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3674
            __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Too many interfaces already exist: 255"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3675
            return NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3676
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3677
        // Find the smallest interface number that has not yet been used.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3678
        for (ifcset = 0; ifcset < 256; ++ifcset)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3679
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3680
            TBool n_used = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3681
            for (TInt i = 0; i < num_ifcsets; ++i)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3682
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3683
                if ((iConfigs[0]->iInterfaceSets[i]->iInterfaceNumber) == ifcset)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3684
                    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3685
                    __KTRACE_OPT(KUSB, Kern::Printf("  interface number %d already used", ifcset));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3686
                    n_used = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3687
                    break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3688
                    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3689
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3690
            if (!n_used)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3691
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3692
                break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3693
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3694
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3695
        if (ifcset == 256)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3696
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3697
            __KTRACE_OPT(KPANIC, Kern::Printf("  Error: no available interface number found"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3698
            return NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3699
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3700
        // append the ifcset
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3701
        __KTRACE_OPT(KUSB, Kern::Printf("  creating new InterfaceSet %d first", ifcset));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3702
        if (aIfc != 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3703
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3704
            __KTRACE_OPT(KPANIC, Kern::Printf("  Error: invalid interface setting number (1): %d", aIfc));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3705
            return NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3706
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3707
        if ((ifcset_ptr = new TUsbcInterfaceSet(aClientId, ifcset)) == NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3708
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3709
            __KTRACE_OPT(KPANIC,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3710
                         Kern::Printf("  Error: new TUsbcInterfaceSet(aClientId, ifcset_num) failed"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3711
            return NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3712
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3713
        iConfigs[0]->iInterfaceSets.Append(ifcset_ptr);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3714
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3715
    else /* if (ifcset_num >= 0) */
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3716
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3717
        // use an existent ifcset
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3718
        new_ifc = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3719
        __KTRACE_OPT(KUSB, Kern::Printf("  using existing InterfaceSet %d", ifcset));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3720
        ifcset_ptr = InterfaceNumber2InterfacePointer(ifcset);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3721
        if (aIfc != ifcset_ptr->iInterfaces.Count())
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3722
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3723
            // 9.2.3: "Alternate settings range from zero to one less than the number of alternate
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3724
            // settings for a specific interface." (Thus we can here only append a setting.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3725
            __KTRACE_OPT(KPANIC, Kern::Printf("  Error: invalid interface setting number (2): %d", aIfc));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3726
            return NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3727
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3728
        // Check whether the existing interface belongs indeed to this client
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3729
        if (ifcset_ptr->iClientId != aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3730
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3731
            __KTRACE_OPT(KPANIC, Kern::Printf("  Error: iClientId (%p) != aClientId (%p)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3732
                                              ifcset_ptr->iClientId, aClientId));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3733
            return NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3734
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3735
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3736
    const TBool no_ep0_requests = aFeatureWord & KUsbcInterfaceInfo_NoEp0RequestsPlease;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3737
    TUsbcInterface* const ifc_ptr = new TUsbcInterface(ifcset_ptr, aIfc, no_ep0_requests);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3738
    if (!ifc_ptr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3739
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3740
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: new TUsbcInterface(ifcset, aIfc) failed"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3741
        if (new_ifc)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3742
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3743
            DeleteInterfaceSet(ifcset);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3744
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3745
        return NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3746
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3747
    ifcset_ptr->iInterfaces.Append(ifc_ptr);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3748
    return ifc_ptr;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3749
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3750
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3751
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3752
#define RESET_SETTINGRESERVE \
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3753
    for (TInt i = start_ep; i < iDeviceTotalEndpoints; i++) \
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3754
        { \
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3755
        if (iRealEndpoints[i].iSettingReserve) \
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3756
            iRealEndpoints[i].iSettingReserve = EFalse; \
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3757
        } \
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3758
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3759
TInt DUsbClientController::CreateEndpoints(TUsbcInterface* aIfc, TInt aEndpointsUsed,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3760
                                           const TUsbcEndpointInfoArray& aEndpointData,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3761
                                           TInt aRealEpNumbers[])
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3762
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3763
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::CreateEndpoints()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3764
    const TInt ifc_num = aIfc->iInterfaceSet->iInterfaceNumber;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3765
    const TInt start_ep = 2;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3766
    for (TInt i = 0; i < aEndpointsUsed; ++i)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3767
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3768
        for (TInt j = start_ep; j < iDeviceTotalEndpoints; ++j)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3769
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3770
            if (iRealEndpoints[j].EndpointSuitable(&aEndpointData[i], ifc_num))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3771
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3772
                // Logical endpoints are numbered 1..KMaxEndpointsPerClient (virtual 0 is real 0 and 1)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3773
                TUsbcLogicalEndpoint* const ep = new TUsbcLogicalEndpoint(this, i + 1, aEndpointData[i],
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3774
                                                                          aIfc, &iRealEndpoints[j]);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3775
                if (!ep)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3776
                    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3777
                    __KTRACE_OPT(KPANIC, Kern::Printf("  Error: new TUsbcLogicalEndpoint() failed"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3778
                    aIfc->iEndpoints.ResetAndDestroy();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3779
                    RESET_SETTINGRESERVE;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3780
                    return KErrNoMemory;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3781
                    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3782
                aIfc->iEndpoints.Append(ep);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3783
                // Check on logical endpoint's sizes for compliance with special restrictions.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3784
                if (aIfc->iSettingCode == 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3785
                    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3786
                    // For details see last paragraph of 5.7.3 "Interrupt Transfer Packet Size Constraints".
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3787
                    if ((ep->iInfo.iType == UsbShai::KUsbEpTypeInterrupt) && (ep->iEpSize_Hs > 64))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3788
                        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3789
                        __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: INT ep HS size = %d on default ifc setting",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3790
                                                          ep->iEpSize_Hs));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3791
                        __KTRACE_OPT(KPANIC, Kern::Printf("           (should be <= 64)"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3792
                        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3793
                    // For details see last paragraph of 5.6.3 "Isochronous Transfer Packet Size Constraints".
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3794
                    else if ((ep->iInfo.iType == UsbShai::KUsbEpTypeIsochronous) && (ep->iInfo.iSize > 0))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3795
                        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3796
                        __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: ISO ep size = %d on default ifc setting",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3797
                                                          ep->iInfo.iSize));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3798
                        __KTRACE_OPT(KPANIC, Kern::Printf("           (should be zero or ep non-existent)"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3799
                        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3800
                    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3801
                // If the endpoint doesn't support DMA (now or never) the next operation
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3802
                // will be a successful no-op.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3803
                /*
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3804
                const TInt r = OpenDmaChannel(j);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3805
                if (r != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3806
                    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3807
                    __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Opening of DMA channel failed"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3808
                    aIfc->iEndpoints.ResetAndDestroy();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3809
                    RESET_SETTINGRESERVE;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3810
                    return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3811
                    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3812
                */
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3813
                __KTRACE_OPT(KUSB, Kern::Printf("  creating ep: mapping real ep %d -> logical ep %d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3814
                                                j, i + 1));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3815
                iRealEndpoints[j].iIfcNumber = &aIfc->iInterfaceSet->iInterfaceNumber;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3816
                iRealEndpoints[j].iSettingReserve = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3817
                __KTRACE_OPT(KUSB,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3818
                             Kern::Printf("  ep->iInfo: iType=0x%x iDir=0x%x iSize=%d iInterval=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3819
                                          ep->iInfo.iType, ep->iInfo.iDir, ep->iInfo.iSize,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3820
                                          ep->iInfo.iInterval));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3821
                __KTRACE_OPT(KUSB,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3822
                             Kern::Printf("  ep->iInfo: iInterval_Hs=%d iTransactions=%d iExtra=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3823
                                          ep->iInfo.iInterval_Hs, ep->iInfo.iTransactions,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3824
                                          ep->iInfo.iExtra));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3825
                // Store real endpoint numbers:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3826
                // array[x] holds the number for logical ep x.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3827
                aRealEpNumbers[i + 1] = j;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3828
                break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3829
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3830
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3831
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3832
    aRealEpNumbers[0] = 0;                                // ep0: 0.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3833
    __KTRACE_OPT(KUSB,{
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3834
        Kern::Printf("  Endpoint Mapping for Interface %d / Setting %d:", ifc_num, aIfc->iSettingCode);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3835
        Kern::Printf("Logical  | Real");
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3836
        Kern::Printf("Endpoint | Endpoint");
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3837
        for (TInt ep = 0; ep <= aEndpointsUsed; ++ep) Kern::Printf("   %2d       %3d",ep, aRealEpNumbers[ep]);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3838
        });
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3839
    RESET_SETTINGRESERVE;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3840
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3841
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3842
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3843
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3844
TInt DUsbClientController::SetupIfcDescriptor(TUsbcInterface* aIfc, TUsbcClassInfo& aClass, DThread* aThread,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3845
                                              TDesC8* aString, const TUsbcEndpointInfoArray& aEndpointData)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3846
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3847
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::SetupIfcDescriptor()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3848
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3849
    // Interface descriptor
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3850
    TUsbcDescriptorBase* d = TUsbcInterfaceDescriptor::New(aIfc->iInterfaceSet->iInterfaceNumber,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3851
                                                           aIfc->iSettingCode,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3852
                                                           aIfc->iEndpoints.Count(),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3853
                                                           aClass);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3854
    if (!d)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3855
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3856
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Memory allocation for ifc desc failed."));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3857
        return KErrNoMemory;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3858
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3859
    iDescriptors.InsertDescriptor(d);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3860
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3861
    // Interface string descriptor
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3862
    if (aString)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3863
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3864
        // we don't know the length of the string, so we have to allocate memory dynamically
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3865
        TUint strlen = Kern::ThreadGetDesLength(aThread, aString);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3866
        if (strlen > KUsbStringDescStringMaxSize)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3867
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3868
            __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: $ descriptor too long - string will be truncated"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3869
            strlen = KUsbStringDescStringMaxSize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3870
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3871
        HBuf8* const stringbuf = HBuf8::New(strlen);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3872
        if (!stringbuf)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3873
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3874
            __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Memory allocation for ifc $ desc string failed."));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3875
            iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3876
                                             aIfc->iSettingCode);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3877
            return KErrNoMemory;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3878
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3879
        stringbuf->SetMax();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3880
        // the aString points to data that lives in user memory, so we have to copy it:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3881
        TInt r = Kern::ThreadDesRead(aThread, aString, *stringbuf, 0);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3882
        if (r != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3883
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3884
            __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Thread read error"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3885
            iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3886
                                             aIfc->iSettingCode);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3887
            delete stringbuf;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3888
            return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3889
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3890
        TUsbcStringDescriptor* const sd = TUsbcStringDescriptor::New(*stringbuf);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3891
        if (!sd)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3892
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3893
            __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Memory allocation for ifc $ desc failed."));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3894
            iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3895
                                             aIfc->iSettingCode);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3896
            delete stringbuf;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3897
            return KErrNoMemory;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3898
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3899
        iDescriptors.SetIfcStringDescriptor(sd, aIfc->iInterfaceSet->iInterfaceNumber, aIfc->iSettingCode);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3900
        delete stringbuf;                                    // the (EPOC) descriptor was copied by New()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3901
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3902
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3903
    // Endpoint descriptors
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3904
    for (TInt i = 0; i < aIfc->iEndpoints.Count(); ++i)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3905
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3906
        // The reason for using another function argument for Endpoint Info
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3907
        // (and not possibly - similar to the Endpoint Address -
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3908
        // "aIfc->iEndpoints[i]->iPEndpoint->iLEndpoint->iInfo") is that this time
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3909
        // there are no logical endpoints associated with our real endpoints,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3910
        // i.e. iLEndpoint is NULL!.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3911
        if (aEndpointData[i].iExtra)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3912
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3913
            // if a non-standard endpoint descriptor is requested...
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3914
            if (aEndpointData[i].iExtra != 2)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3915
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3916
                // ...then it must be a Audio Class endpoint descriptor. Else...
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3917
                __KTRACE_OPT(KPANIC, Kern::Printf("  Error: EP desc extension > 2 bytes (%d)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3918
                                                  aEndpointData[i].iExtra));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3919
                iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3920
                                                 aIfc->iSettingCode);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3921
                return KErrArgument;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3922
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3923
            d = TUsbcAudioEndpointDescriptor::New(aIfc->iEndpoints[i]->iPEndpoint->iEndpointAddr,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3924
                                                  aEndpointData[i]);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3925
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3926
        else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3927
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3928
            d = TUsbcEndpointDescriptor::New(aIfc->iEndpoints[i]->iPEndpoint->iEndpointAddr,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3929
                                             aEndpointData[i]);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3930
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3931
        if (!d)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3932
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3933
            __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Memory allocation for ep desc #%d failed.", i));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3934
            iDescriptors.DeleteIfcDescriptor(aIfc->iInterfaceSet->iInterfaceNumber,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3935
                                             aIfc->iSettingCode);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3936
            return KErrNoMemory;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3937
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3938
        iDescriptors.InsertDescriptor(d);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3939
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3940
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3941
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3942
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3943
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3944
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3945
TInt DUsbClientController::ClientId2InterfaceNumber(const DBase* aClientId) const
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3946
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3947
    const TInt num_ifcsets = iConfigs[0]->iInterfaceSets.Count();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3948
    for (TInt i = 0; i < num_ifcsets; ++i)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3949
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3950
        if (iConfigs[0]->iInterfaceSets[i]->iClientId == aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3951
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3952
            return iConfigs[0]->iInterfaceSets[i]->iInterfaceNumber;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3953
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3954
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3955
    return -1;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3956
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3957
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3958
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3959
TUsbcInterfaceSet* DUsbClientController::ClientId2InterfacePointer(const DBase* aClientId) const
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3960
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3961
    const TInt num_ifcsets = iConfigs[0]->iInterfaceSets.Count();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3962
    for (TInt i = 0; i < num_ifcsets; ++i)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3963
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3964
        if (iConfigs[0]->iInterfaceSets[i]->iClientId == aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3965
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3966
            return iConfigs[0]->iInterfaceSets[i];
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3967
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3968
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3969
    return NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3970
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3971
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3972
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3973
const DBase* DUsbClientController::InterfaceNumber2ClientId(TInt aIfcSet) const
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3974
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3975
    if (!InterfaceExists(aIfcSet))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3976
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3977
        return NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3978
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3979
    return InterfaceNumber2InterfacePointer(aIfcSet)->iClientId;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3980
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3981
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3982
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3983
TUsbcInterfaceSet* DUsbClientController::InterfaceNumber2InterfacePointer(TInt aIfcSet) const
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3984
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3985
    const TInt num_ifcsets = iConfigs[0]->iInterfaceSets.Count();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3986
    for (TInt i = 0; i < num_ifcsets; ++i)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3987
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3988
        if ((iConfigs[0]->iInterfaceSets[i]->iInterfaceNumber) == aIfcSet)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3989
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3990
            return iConfigs[0]->iInterfaceSets[i];
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3991
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3992
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3993
    return NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3994
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3995
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3996
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3997
TInt DUsbClientController::ActivateHardwareController()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3998
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  3999
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::ActivateHardwareController()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4000
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4001
    // iStackIsActive must be ETrue at this time
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4002
    // the caller of this function shall checked that iStackIsActive is ETrue
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4003
    __ASSERT_DEBUG(iStackIsActive, Kern::Fault(KUsbPILPanicCat, __LINE__));   
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4004
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4005
    if (iHardwareActivated)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4006
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4007
        __KTRACE_OPT(KUSB, Kern::Printf("  already active -> returning"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4008
        return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4009
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4010
    // Initialise HW
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4011
    TInt r = iController.StartPeripheralController();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4012
    if (r != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4013
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4014
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: StartPeripheralController() failed"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4015
        return KErrHardwareNotAvailable;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4016
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4017
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4018
    iHardwareActivated = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4019
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4020
    // Configure & enable endpoint zero
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4021
    const TUsbcLogicalEndpoint* const ep0_0 = iRealEndpoints[0].iLEndpoint;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4022
    const TUsbcLogicalEndpoint* const ep0_1 = iRealEndpoints[1].iLEndpoint;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4023
    if (iHighSpeed)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4024
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4025
        const_cast<TUsbcLogicalEndpoint*>(ep0_0)->iInfo.iSize = ep0_0->iEpSize_Hs;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4026
        const_cast<TUsbcLogicalEndpoint*>(ep0_1)->iInfo.iSize = ep0_1->iEpSize_Hs;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4027
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4028
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4029
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4030
        const_cast<TUsbcLogicalEndpoint*>(ep0_0)->iInfo.iSize = ep0_0->iEpSize_Fs;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4031
        const_cast<TUsbcLogicalEndpoint*>(ep0_1)->iInfo.iSize = ep0_1->iEpSize_Fs;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4032
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4033
    iController.ConfigureEndpoint(0, ep0_0->iInfo);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4034
    iController.ConfigureEndpoint(1, ep0_1->iInfo);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4035
    iEp0MaxPacketSize = ep0_0->iInfo.iSize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4036
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4037
    __KTRACE_OPT(KUSB, Kern::Printf("  Controller activated."));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4038
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4039
    // Controller is powered up, changes device state to powered
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4040
    NextDeviceState(UsbShai::EUsbPeripheralStatePowered);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4041
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4042
    __KTRACE_OPT(KUSB, Kern::Printf("< DUsbClientController::ActivateHardwareController()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4043
    return  KErrNone;;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4044
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4045
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4046
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4047
void DUsbClientController::DeActivateHardwareController()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4048
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4049
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeActivateHardwareController()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4050
    if (!iHardwareActivated)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4051
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4052
        __KTRACE_OPT(KUSB, Kern::Printf("  not active -> returning"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4053
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4054
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4055
    // Deconfigure & disable endpoint zero
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4056
    iController.DeConfigureEndpoint(KEp0_Out);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4057
    iController.DeConfigureEndpoint(KEp0_In);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4058
    // Stop HW
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4059
    iController.StopPeripheralController();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4060
    iHardwareActivated = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4061
    __KTRACE_OPT(KUSB, Kern::Printf("  Controller deactivated."));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4062
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4063
    // Always go to attached state, until statck is disabled
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4064
    NextDeviceState(UsbShai::EUsbPeripheralStateAttached);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4065
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4066
    return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4067
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4068
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4069
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4070
void DUsbClientController::DeleteInterfaceSet(TInt aIfcSet)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4071
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4072
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeleteInterfaceSet(%d)", aIfcSet));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4073
    TUsbcInterfaceSet* const ifcset_ptr = InterfaceNumber2InterfacePointer(aIfcSet);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4074
    if (!ifcset_ptr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4075
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4076
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: invalid interface number: %d", aIfcSet));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4077
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4078
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4079
    const TInt idx = iConfigs[0]->iInterfaceSets.Find(ifcset_ptr);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4080
    if (idx == KErrNotFound)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4081
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4082
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: interface not found in array"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4083
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4084
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4085
    //Add this mutex to protect the interface set data structure
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4086
    if (NKern::CurrentContext() == EThread)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4087
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4088
        NKern::FMWait(&iMutex);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4089
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4090
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4091
    iConfigs[0]->iInterfaceSets.Remove(idx);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4092
    if (NKern::CurrentContext() == EThread)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4093
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4094
        NKern::FMSignal(&iMutex);    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4095
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4096
    delete ifcset_ptr;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4097
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4098
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4099
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4100
void DUsbClientController::DeleteInterface(TInt aIfcSet, TInt aIfc)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4101
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4102
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeleteInterface(%d, %d)", aIfcSet, aIfc));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4103
    TUsbcInterfaceSet* const ifcset_ptr = InterfaceNumber2InterfacePointer(aIfcSet);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4104
    if (!ifcset_ptr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4105
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4106
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: invalid interface number: %d", aIfcSet));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4107
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4108
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4109
    if (ifcset_ptr->iInterfaces.Count() <= aIfc)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4110
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4111
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: invalid interface setting: %d", aIfc));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4112
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4113
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4114
    //Add this mutex to protect the interface set data structure
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4115
    if (NKern::CurrentContext() == EThread)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4116
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4117
        NKern::FMWait(&iMutex);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4118
        }    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4119
    TUsbcInterface* const ifc_ptr = ifcset_ptr->iInterfaces[aIfc];
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4120
    // Always first remove, then delete (see ~TUsbcLogicalEndpoint() for the reason why)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4121
    ifcset_ptr->iInterfaces.Remove(aIfc);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4122
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4123
    if (aIfc == ifcset_ptr->iCurrentInterface)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4124
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4125
        __KTRACE_OPT(KUSB, Kern::Printf(" > Warning: deleting current interface setting"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4126
        ifcset_ptr->iCurrentInterface = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4127
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4128
    if (NKern::CurrentContext() == EThread)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4129
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4130
        NKern::FMSignal(&iMutex);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4131
        }    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4132
    delete ifc_ptr;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4133
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4134
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4135
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4136
void DUsbClientController::CancelTransferRequests(TInt aRealEndpoint)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4137
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4138
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::CancelTransferRequests(aRealEndpoint=%d)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4139
                                    aRealEndpoint));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4140
    const DBase* const clientId = PEndpoint2ClientId(aRealEndpoint);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4141
    if (EpIdx2Addr(aRealEndpoint) & KUsbEpAddress_In)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4142
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4143
        CancelWriteBuffer(clientId, aRealEndpoint);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4144
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4145
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4146
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4147
        CancelReadBuffer(clientId, aRealEndpoint);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4148
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4149
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4150
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4151
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4152
void DUsbClientController::DeleteRequestCallback(const DBase* aClientId, TInt aEndpointNum,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4153
                                                 UsbShai::TTransferDirection aTransferDir)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4154
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4155
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeleteRequestCallback()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4156
    // Ep0 OUT
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4157
    if (aEndpointNum == 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4158
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4159
        const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4160
        TSglQueIter<TUsbcRequestCallback> iter(iEp0ReadRequestCallbacks);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4161
        TUsbcRequestCallback* p;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4162
        while ((p = iter++) != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4163
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4164
            if (p->Owner() == aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4165
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4166
                __ASSERT_DEBUG((p->iRealEpNum == 0), Kern::Fault(KUsbPILPanicCat, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4167
                __ASSERT_DEBUG((p->iTransferDir == UsbShai::EControllerRead), Kern::Fault(KUsbPILPanicCat, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4168
                __KTRACE_OPT(KUSB, Kern::Printf("  removing RequestCallback @ 0x%x (ep0)", p));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4169
                iEp0ReadRequestCallbacks.Remove(*p);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4170
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4171
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4172
        __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4173
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4174
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4175
    // Other endpoints
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4176
    TUsbcRequestCallback* const p = iRequestCallbacks[aEndpointNum];
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4177
    if (p)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4178
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4179
         __ASSERT_DEBUG((p->Owner() == aClientId), Kern::Fault(KUsbPILPanicCat, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4180
        __ASSERT_DEBUG((p->iTransferDir == aTransferDir), Kern::Fault(KUsbPILPanicCat, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4181
        __KTRACE_OPT(KUSB, Kern::Printf("  removing RequestCallback @ 0x%x", p));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4182
        iRequestCallbacks[aEndpointNum] = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4183
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4184
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4185
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4186
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4187
void DUsbClientController::DeleteRequestCallbacks(const DBase* aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4188
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4189
    // aClientId being NULL means: delete all requests for *all* clients.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4190
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::DeleteRequestCallbacks()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4191
    // Ep0 OUT
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4192
    const TInt irq = __SPIN_LOCK_IRQSAVE(iUsbLock);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4193
    TSglQueIter<TUsbcRequestCallback> iter(iEp0ReadRequestCallbacks);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4194
    TUsbcRequestCallback* p;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4195
    while ((p = iter++) != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4196
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4197
        if (!aClientId || p->Owner() == aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4198
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4199
            __KTRACE_OPT(KUSB, Kern::Printf("  removing RequestCallback @ 0x%x (ep0)", p));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4200
            iEp0ReadRequestCallbacks.Remove(*p);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4201
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4202
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4203
    __SPIN_UNLOCK_IRQRESTORE(iUsbLock, irq);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4204
    // Other endpoints
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4205
    for (TInt i = 1; i < KUsbcEpArraySize; i++)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4206
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4207
        TUsbcRequestCallback* const p = iRequestCallbacks[i];
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4208
        if (p && (!aClientId || p->Owner() == aClientId))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4209
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4210
            __KTRACE_OPT(KUSB, Kern::Printf("  removing RequestCallback @ 0x%x", p));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4211
            iRequestCallbacks[i] = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4212
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4213
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4214
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4215
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4216
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4217
void DUsbClientController::StatusNotify(UsbShai::TUsbPeripheralState aState, const DBase* aClientId)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4218
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4219
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::StatusNotify()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4220
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4221
    // This function may be called by the PSL (via chapter9.cpp) from within an
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4222
    // ISR -- so we have to take care what we do here (and also in all
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4223
    // functions that get called from here).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4224
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4225
    TSglQueIter<TUsbcStatusCallback> iter(iStatusCallbacks);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4226
    TUsbcStatusCallback* p;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4227
    while ((p = iter++) != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4228
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4229
        if (!aClientId || aClientId == p->Owner())
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4230
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4231
            __KTRACE_OPT(KUSB, Kern::Printf("  notifying LDD @ 0x%x about %d", p->Owner(), aState));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4232
            p->SetState(aState);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4233
            p->DoCallback();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4234
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4235
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4236
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4237
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4238
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4239
void DUsbClientController::EpStatusNotify(TInt aRealEndpoint)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4240
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4241
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::EpStatusNotify()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4242
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4243
    // This function may be called by the PSL (via chapter9.cpp) from within an
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4244
    // ISR -- so we have to take care what we do here (and also in all
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4245
    // functions that get called from here).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4246
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4247
    const DBase* const client_id = PEndpoint2ClientId(aRealEndpoint);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4248
    if (!client_id)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4249
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4250
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Client not found for real ep %d", aRealEndpoint));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4251
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4252
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4253
    // Check if there is a notification request queued for that client (if not, we can return here).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4254
    TSglQueIter<TUsbcEndpointStatusCallback> iter(iEpStatusCallbacks);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4255
    TUsbcEndpointStatusCallback* p;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4256
    while ((p = iter++) != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4257
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4258
        if (p->Owner() == client_id)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4259
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4260
            break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4261
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4262
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4263
    if (!p)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4264
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4265
        __KTRACE_OPT(KUSB, Kern::Printf("  No notification request for that client, returning"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4266
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4267
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4268
    const TInt ifcset = ClientId2InterfaceNumber(client_id);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4269
    if (ifcset < 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4270
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4271
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Ifcset not found for clientid %d", client_id));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4272
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4273
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4274
    const TUsbcInterfaceSet* const ifcset_ptr = InterfaceNumber2InterfacePointer(ifcset);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4275
    if (!ifcset_ptr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4276
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4277
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Ifcset pointer not found for ifcset %d", ifcset));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4278
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4279
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4280
    const TUsbcInterface* const ifc_ptr = ifcset_ptr->CurrentInterface();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4281
    if (!ifc_ptr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4282
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4283
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Current ifc pointer not found for ifcset %d", ifcset));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4284
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4285
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4286
    TUint state = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4287
    const TInt eps = ifc_ptr->iEndpoints.Count();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4288
    for (TInt i = 0; i < eps; i++)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4289
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4290
        const TUsbcLogicalEndpoint* const ep_ptr = ifc_ptr->iEndpoints[i];
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4291
        __KTRACE_OPT(KUSB, Kern::Printf("  checking logical ep #%d for stall state...",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4292
                                        ep_ptr->iLEndpointNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4293
        if (ep_ptr->iPEndpoint->iHalt)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4294
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4295
            __KTRACE_OPT(KUSB, Kern::Printf("  -- stalled"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4296
            // set the bit n to 1, where n is the logical endpoint number minus one
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4297
            state |= (1 << (ep_ptr->iLEndpointNum - 1));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4298
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4299
        else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4300
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4301
            __KTRACE_OPT(KUSB, Kern::Printf("  -- not stalled"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4302
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4303
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4304
    __KTRACE_OPT(KUSB, Kern::Printf(" passing ep state 0x%x on to LDD @ 0x%x", state, client_id));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4305
    p->SetState(state);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4306
    p->DoCallback();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4307
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4308
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4309
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4310
void DUsbClientController::OtgFeaturesNotify()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4311
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4312
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::OtgFeaturesNotify()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4313
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4314
    // This function may be called from the PSL (via PIL's chapter9.cpp) from
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4315
    // within an ISR -- so we have to take care what we do here (and also in
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4316
    // all functions that get called from here).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4317
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4318
    TSglQueIter<TUsbcOtgFeatureCallback> iter(iOtgCallbacks);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4319
    TUsbcOtgFeatureCallback* p;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4320
    while ((p = iter++) != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4321
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4322
        p->SetFeatures(iOtgFuncMap & 0x1C);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4323
        p->DoCallback();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4324
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4325
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4326
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4327
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4328
void DUsbClientController::RunClientCallbacks()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4329
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4330
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::RunClientCallbacks()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4331
    TSglQueIter<TUsbcClientCallback> iter(iClientCallbacks);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4332
    TUsbcClientCallback* p;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4333
    while ((p = iter++) != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4334
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4335
        __KTRACE_OPT(KUSB, Kern::Printf("Callback 0x%x", p));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4336
        p->DoCallback();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4337
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4338
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4339
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4340
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4341
void DUsbClientController::ProcessDataTransferDone(TUsbcRequestCallback& aRcb)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4342
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4343
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessDataTransferDone()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4344
    // This piece can only be called in thread context from ProcessEp0DataReceived() /
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4345
    // ProcessEp0SetupReceived() via the call to ProcessEp0ReceiveDone() in
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4346
    // SetupReadBuffer(), which is guarded by an interrupt lock.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4347
    TInt ep = aRcb.iRealEpNum;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4348
    if (ep == 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4349
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4350
        if (aRcb.iTransferDir == UsbShai::EControllerRead)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4351
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4352
            // Ep0 OUT is special
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4353
            iEp0ReadRequestCallbacks.Remove(aRcb);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4354
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4355
        else                                                // UsbShai::EControllerWrite
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4356
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4357
            // Ep0 IN needs to be adjusted: it's '1' within the PIL.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4358
            ep = KEp0_Tx;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4359
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4360
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4361
    if (ep > 0)                                                // not 'else'!
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4362
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4363
        __ASSERT_DEBUG((iRequestCallbacks[ep] == &aRcb), Kern::Fault(KUsbPILPanicCat, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4364
        __KTRACE_OPT(KUSB, Kern::Printf(" > removing RequestCallback[%d] @ 0x%x", ep, &aRcb));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4365
        iRequestCallbacks[ep] = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4366
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4367
    aRcb.DoCallback();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4368
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4369
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4370
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4371
void DUsbClientController::NextDeviceState(UsbShai::TUsbPeripheralState aNextState)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4372
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4373
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::NextDeviceState()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4374
#ifdef _DEBUG
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4375
    const char* const states[] = {"Undefined", "Attached", "Powered", "Default",
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4376
                                  "Address", "Configured", "Suspended"};
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4377
    if ((aNextState >= UsbShai::EUsbPeripheralStateUndefined) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4378
        (aNextState <= UsbShai::EUsbPeripheralStateSuspended))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4379
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4380
        __KTRACE_OPT(KUSB, Kern::Printf("  next device state: %s", states[aNextState]));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4381
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4382
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4383
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4384
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Unknown next device state: %d", aNextState));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4385
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4386
    // Print a warning when an invalid state transition is detected
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4387
    // 'Undefined' is not a state that is mentioned in the USB spec, but
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4388
    // that's what we're in once the cable gets pulled (for instance).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4389
    switch (iDeviceState)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4390
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4391
    case UsbShai::EUsbPeripheralStateUndefined:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4392
        // valid: Undefined -> Attached
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4393
        if (aNextState != UsbShai::EUsbPeripheralStateAttached)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4394
            break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4395
        goto OK;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4396
    case UsbShai::EUsbPeripheralStateAttached:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4397
        // valid: Attached -> {Undefined, Powered}
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4398
        if ((aNextState != UsbShai::EUsbPeripheralStateUndefined) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4399
            (aNextState != UsbShai::EUsbPeripheralStatePowered))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4400
            break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4401
        goto OK;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4402
    case UsbShai::EUsbPeripheralStatePowered:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4403
        // valid: Powered -> {Undefined, Attached, Default, Suspended}
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4404
        if ((aNextState != UsbShai::EUsbPeripheralStateUndefined) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4405
            (aNextState != UsbShai::EUsbPeripheralStateAttached) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4406
            (aNextState != UsbShai::EUsbPeripheralStateDefault)     &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4407
            (aNextState != UsbShai::EUsbPeripheralStateSuspended))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4408
            break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4409
        goto OK;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4410
    case UsbShai::EUsbPeripheralStateDefault:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4411
        // valid: Default -> {Undefined, Powered, Default, Address, Suspended}
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4412
        if ((aNextState != UsbShai::EUsbPeripheralStateUndefined) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4413
            (aNextState != UsbShai::EUsbPeripheralStatePowered) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4414
            (aNextState != UsbShai::EUsbPeripheralStateDefault) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4415
            (aNextState != UsbShai::EUsbPeripheralStateAddress) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4416
            (aNextState != UsbShai::EUsbPeripheralStateSuspended))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4417
            break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4418
        goto OK;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4419
    case UsbShai::EUsbPeripheralStateAddress:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4420
        // valid: Address -> {Undefined, Powered, Default, Configured, Suspended}
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4421
        if ((aNextState != UsbShai::EUsbPeripheralStateUndefined) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4422
            (aNextState != UsbShai::EUsbPeripheralStatePowered) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4423
            (aNextState != UsbShai::EUsbPeripheralStateDefault) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4424
            (aNextState != UsbShai::EUsbPeripheralStateConfigured) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4425
            (aNextState != UsbShai::EUsbPeripheralStateSuspended))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4426
            break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4427
        goto OK;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4428
    case UsbShai::EUsbPeripheralStateConfigured:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4429
        // valid: Configured -> {Undefined, Powered, Default, Address, Suspended}
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4430
        if ((aNextState != UsbShai::EUsbPeripheralStateUndefined) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4431
            (aNextState != UsbShai::EUsbPeripheralStatePowered) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4432
            (aNextState != UsbShai::EUsbPeripheralStateDefault) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4433
            (aNextState != UsbShai::EUsbPeripheralStateAddress) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4434
            (aNextState != UsbShai::EUsbPeripheralStateSuspended))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4435
            break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4436
        goto OK;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4437
    case UsbShai::EUsbPeripheralStateSuspended:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4438
        // valid: Suspended -> {Undefined, Powered, Default, Address, Configured}
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4439
        if ((aNextState != UsbShai::EUsbPeripheralStateUndefined) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4440
            (aNextState != UsbShai::EUsbPeripheralStatePowered) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4441
            (aNextState != UsbShai::EUsbPeripheralStateDefault) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4442
            (aNextState != UsbShai::EUsbPeripheralStateAddress) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4443
            (aNextState != UsbShai::EUsbPeripheralStateConfigured))
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4444
            break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4445
        goto OK;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4446
    default:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4447
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Unknown current device state: %d", iDeviceState));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4448
        goto OK;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4449
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4450
    // KUSB only (instead of KPANIC) so as not to worry people too much where
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4451
    // a particular h/w regularly enforces invalid (but harmless) transitions
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4452
    __KTRACE_OPT(KUSB, Kern::Printf("  Warning: Invalid next state from %s", states[iDeviceState]));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4453
OK:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4454
#endif // _DEBUG
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4455
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4456
    iDeviceState = aNextState;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4457
    StatusNotify(iDeviceState);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4458
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4459
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4460
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4461
TInt DUsbClientController::ProcessSuspendEvent()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4462
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4463
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessSuspendEvent()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4464
    // A suspend interrupt has been received and needs attention.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4465
    iDeviceStateB4Suspend = iDeviceState;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4466
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4467
    // We have to move to the Suspend state immediately (in case it's a genuine Suspend)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4468
    // because 7.1.7.6 says: "The device must actually be suspended, [...] after no more
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4469
    // than 10ms of bus inactivity [...]." Assuming we got the interrupt 3ms after the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4470
    // Suspend condition arose, we have now 7ms left.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4471
    NextDeviceState(UsbShai::EUsbPeripheralStateSuspended);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4472
    iController.Suspend();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4473
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4474
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4475
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4476
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4477
TInt DUsbClientController::ProcessResumeEvent()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4478
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4479
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessResumeEvent()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4480
    if (iDeviceState == UsbShai::EUsbPeripheralStateSuspended)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4481
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4482
        NextDeviceState(iDeviceStateB4Suspend);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4483
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4484
    iController.Resume();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4485
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4486
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4487
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4488
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4489
TInt DUsbClientController::ProcessResetEvent(TBool aPslUpcall)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4490
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4491
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessResetEvent()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4492
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4493
    if (aPslUpcall)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4494
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4495
        // Call back into PSL if we're coming from there.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4496
        // Also, do it always, even when PIL processing will be deferred.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4497
        iController.Reset();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4498
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4499
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4500
    // In an OTG-environment, some OTG controllers have implemented
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4501
    // the OTG state machine in HW and connect to the bus
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4502
    // automatically already before the SW has indicated
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4503
    // readiness. Peripheral PSL operating on top of such controller
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4504
    // may report a reset event already before the upper layers are
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4505
    // ready. In this case we defer the reset processing to after the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4506
    // upper layers have indicated their readiness.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4507
    if (iUsbResetDeferred)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4508
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4509
        __KTRACE_OPT(KUSB, Kern::Printf("  User-side (still) not ready -> returning"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4510
        return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4511
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4512
    else if (!iClientSupportReady)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4513
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4514
        // Wait with the PIL Reset processing until user-side is ready
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4515
        __KTRACE_OPT(KUSB, Kern::Printf("  User-side not ready -> deferring"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4516
        iUsbResetDeferred = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4517
        return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4518
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4519
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4520
    if (iDeviceState == UsbShai::EUsbPeripheralStateAttached)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4521
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4522
        NextDeviceState(UsbShai::EUsbPeripheralStatePowered);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4523
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4524
    // Notify the world. (This will just queue a DFC, so users won't actually be
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4525
    // notified before we return. But we change the device state already here so
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4526
    // ChangeConfiguration will see the correct one.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4527
    NextDeviceState(UsbShai::EUsbPeripheralStateDefault);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4528
    // Tear down the current configuration (never called from thread)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4529
    ChangeConfiguration(0);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4530
    // Reset essential vars
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4531
    ResetEp0DataOutVars();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4532
    //iEp0_RxExtraData = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4533
    iEp0WritePending = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4534
    iEp0ClientDataTransmitting = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4535
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4536
    iLastError = KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4537
    iSetupPacketPending = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4538
    //iEp0_RxExtraError = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4539
    iConTransferMgr->Reset();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4540
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4541
    // Reset OTG features, leave attributes as is
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4542
    iOtgFuncMap &= KUsbOtgAttr_SrpSupp | KUsbOtgAttr_HnpSupp;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4543
    if (iOtgSupport)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4544
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4545
        OtgFeaturesNotify();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4546
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4547
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4548
    // Check whether there's a speed change
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4549
    const TBool was_hs = iHighSpeed;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4550
    iHighSpeed = CurrentlyUsingHighSpeed();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4551
    if (!was_hs && iHighSpeed)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4552
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4553
        __KTRACE_OPT(KUSB, Kern::Printf("  Moving to High-speed"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4554
        EnterHighSpeed();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4555
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4556
    else if (was_hs && !iHighSpeed)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4557
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4558
        __KTRACE_OPT(KUSB, Kern::Printf("  Moving to Full-speed"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4559
        EnterFullSpeed();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4560
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4561
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4562
    // Setup initial Ep0 read (SetupEndpointZeroRead never called from thread)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4563
    if (iConTransferMgr->SetupEndpointZeroRead() != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4564
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4565
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: while setting up Ep0 read"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4566
        return KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4567
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4568
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4569
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4570
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4571
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4572
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4573
TInt DUsbClientController::ProcessVbusRisenEvent()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4574
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4575
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessVbusRisenEvent()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4576
    if (iIsOtgPort)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4577
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4578
        // In an OTG environment, this notification is not expected
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4579
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: EUsbEventVbusRisen shouldn't be sent by an OTG Client PSL"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4580
        return KErrArgument;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4581
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4582
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4583
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4584
        // In a non-OTG environment, seeing VBUS rising causes the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4585
        // peripheral stack to be enabled
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4586
        EnablePeripheralStack();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4587
        return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4588
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4589
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4590
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4591
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4592
TInt DUsbClientController::ProcessVbusFallenEvent()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4593
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4594
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ProcessVbusFallenEvent()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4595
    if (iIsOtgPort)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4596
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4597
        // In an OTG environment, this notification is not expected
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4598
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: EUsbEventVbusFallen shouldn't be sent by an OTG Client PSL"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4599
        return KErrArgument;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4600
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4601
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4602
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4603
        // In a non-OTG environment, seeing VBUS falling causes the
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4604
        // peripheral stack to be disabled
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4605
        DisablePeripheralStack();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4606
        return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4607
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4608
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4609
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4610
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4611
void DUsbClientController::EnterFullSpeed()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4612
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4613
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::EnterFullSpeed()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4614
    iDescriptors.UpdateDescriptorsFs();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4615
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4616
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4617
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4618
void DUsbClientController::EnterHighSpeed()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4619
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4620
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::EnterHighSpeed()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4621
    iDescriptors.UpdateDescriptorsHs();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4622
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4623
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4624
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4625
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4626
// DFC (static), we are runing in a DFC context.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4627
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4628
void DUsbClientController::ReconnectTimerCallback(TAny *aPtr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4629
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4630
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::ReconnectTimerCallback()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4631
    if (!aPtr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4632
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4633
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: !aPtr"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4634
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4635
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4636
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4637
    DUsbClientController* const ptr = static_cast<DUsbClientController*>(aPtr);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4638
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4639
    ptr->UsbConnect();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4640
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4641
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4642
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4643
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4644
// static Dfc function
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4645
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4646
void DUsbClientController::PowerUpDfc(TAny* aPtr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4647
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4648
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::PowerUpDfc"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4649
    if (!aPtr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4650
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4651
        __KTRACE_OPT(KPANIC, Kern::Printf("     Error: !aPtr"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4652
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4653
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4654
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4655
    DUsbClientController* const ptr = static_cast<DUsbClientController*>(aPtr);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4656
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4657
    __PM_ASSERT(ptr->iStandby);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4658
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4659
    ptr->iStandby = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4660
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4661
    // We have nothing to do when powerup
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4662
    ptr->iPowerHandler->PowerUpDone();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4663
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4664
    __KTRACE_OPT(KUSB, Kern::Printf("< DUsbClientController::PowerUpDfc"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4665
    return ;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4666
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4667
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4668
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4669
// static Dfc function
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4670
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4671
void DUsbClientController::PowerDownDfc(TAny* aPtr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4672
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4673
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::PowerDownDfc"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4674
    if (!aPtr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4675
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4676
        __KTRACE_OPT(KPANIC, Kern::Printf("     Error: !aPtr"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4677
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4678
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4679
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4680
    DUsbClientController* const ptr = static_cast<DUsbClientController*>(aPtr);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4681
    __PM_ASSERT(!ptr->iStandby);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4682
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4683
    ptr->iStandby = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4684
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4685
    // Disable stack(stop controller inside)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4686
    ptr->DisablePeripheralStack();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4687
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4688
    ptr->iPowerHandler->PowerDownDone();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4689
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4690
    __KTRACE_OPT(KUSB, Kern::Printf("< DUsbClientController::PowerDownDfc"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4691
    return ;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4692
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4693
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4694
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4695
// Static Dfc function
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4696
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4697
void DUsbClientController::DeviceEventNotifyDfc(TAny* aPtr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4698
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4699
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::DeviceEventNotifyDfc"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4700
    DUsbClientController* const ptr = static_cast<DUsbClientController*>(aPtr);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4701
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4702
    UsbShai::TUsbPeripheralEvent event = ptr->iDevEventQueue.FifoGet();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4703
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4704
    if( event == -1)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4705
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4706
        // No event queued
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4707
        __KTRACE_OPT(KUSB, Kern::Printf("  Warning, No event found, exit !!!"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4708
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4709
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4710
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4711
    ptr->ProcessDeviceEventNotification(event);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4712
    __KTRACE_OPT(KUSB, Kern::Printf("< DUsbClientController::DeviceEventNotifyDfc"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4713
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4714
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4715
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4716
// Static Dfc function
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4717
//    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4718
void DUsbClientController::ThreadContextFinderDfc(TAny* aPtr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4719
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4720
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::ThreadContextFinderDfc"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4721
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4722
    DUsbClientController* const ptr = static_cast<DUsbClientController*>(aPtr);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4723
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4724
    ptr->iCommonDfcQThread = NKern::CurrentThread();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4725
    __KTRACE_OPT(KUSB, Kern::Printf("  iCommonDfcQThread = %d",ptr->iCommonDfcQThread));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4726
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4727
    __KTRACE_OPT(KUSB, Kern::Printf("< DUsbClientController::ThreadContextFinderDfc"));    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4728
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4729
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4730
// 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4731
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4732
void DUsbClientController::ProcessDeviceEventNotification(UsbShai::TUsbPeripheralEvent aEvent)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4733
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4734
    __KTRACE_OPT(KUSB, Kern::Printf("> DUsbClientController::ProcessDeviceEventNotification %d",aEvent));    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4735
    // If an OTG Observer has registered, forward the event
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4736
    // notification to it as well
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4737
    if (iOtgObserver != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4738
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4739
        __KTRACE_OPT(KUSB, Kern::Printf("  Forwarding to OTG Observer"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4740
        iOtgObserver->NotifyPeripheralEvent(aEvent);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4741
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4742
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4743
    // This function may be called by the PSL from within an ISR -- so we have
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4744
    // to take care what we do here (and also in all functions that get called
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4745
    // from here).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4746
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4747
    switch (aEvent)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4748
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4749
    case UsbShai::EUsbEventSuspend:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4750
        ProcessSuspendEvent();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4751
        break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4752
    case UsbShai::EUsbEventResume:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4753
        ProcessResumeEvent();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4754
        break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4755
    case UsbShai::EUsbEventReset:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4756
        ProcessResetEvent();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4757
        break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4758
    case UsbShai::EUsbEventVbusRisen:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4759
        ProcessVbusRisenEvent();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4760
        break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4761
    case UsbShai::EUsbEventVbusFallen:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4762
        ProcessVbusFallenEvent();
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4763
        break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4764
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4765
    default:
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4766
        break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4767
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4768
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4769
    __KTRACE_OPT(KUSB, Kern::Printf("< DUsbClientController::ProcessDeviceEventNotification"));    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4770
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4771
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4772
// Functions from UsbShai::MChargerDetectorObserverIf
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4773
void DUsbClientController::NotifyPortType(UsbShai::TPortType aPortType)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4774
    {
48
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4775
    __KTRACE_OPT(KUSB, Kern::Printf("DUsbClientController::NotifyPortType(), aPortType = %d", aPortType));
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4776
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4777
    TSglQueIter<TUsbcChargerTypeCallback> iter(iChargerTypeCallbacks);
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4778
    TUsbcChargerTypeCallback* p;
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4779
    
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4780
    iCurrentChargerType = aPortType;
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4781
    
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4782
    while ((p = iter++) != NULL)
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4783
        {
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4784
        p->SetChargerType(aPortType);
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4785
        p->DoCallback();
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4786
        }    
33
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4787
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4788
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4789
void DUsbClientController::Buffer2Setup(const TAny* aBuf, TUsbcSetup& aSetup) const
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4790
	{
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4791
	// TUint8 index
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4792
	aSetup.iRequestType = static_cast<const TUint8*>(aBuf)[0];
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4793
	aSetup.iRequest		= static_cast<const TUint8*>(aBuf)[1];
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4794
	// TUint16 index from here!
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4795
	aSetup.iValue  = SWAP_BYTES_16((static_cast<const TUint16*>(aBuf))[1]);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4796
	aSetup.iIndex  = SWAP_BYTES_16((static_cast<const TUint16*>(aBuf))[2]);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4797
	aSetup.iLength = SWAP_BYTES_16((static_cast<const TUint16*>(aBuf))[3]);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4798
	}
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4799
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4800
TUsbPeriDeviceEventQueue::TUsbPeriDeviceEventQueue()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4801
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4802
    iDeviceQueueHead = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4803
    iDeviceQueueTail = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4804
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4805
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4806
// FifoAdd will be called from Isr or IDfc context
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4807
// be careful when processing
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4808
void TUsbPeriDeviceEventQueue::FifoAdd(UsbShai::TUsbPeripheralEvent aDeviceEvent)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4809
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4810
    __KTRACE_OPT(KUSB, Kern::Printf("> TUsbPeriDeviceEventQueue::FifoAdd %d , %d",iDeviceQueueHead,iDeviceQueueTail));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4811
    iDeviceEventQueue[iDeviceQueueTail] = aDeviceEvent;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4812
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4813
    iDeviceQueueTail ++;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4814
    iDeviceQueueTail %= KUsbDeviceEventQueueDepth;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4815
    if(iDeviceQueueTail == iDeviceQueueHead)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4816
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4817
        __KTRACE_OPT(KUSB, Kern::Printf("TUsbPeriDeviceEventQueue::FifoAdd overflow, oldest event missed"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4818
        iDeviceQueueHead ++;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4819
        iDeviceQueueHead %= KUsbDeviceEventQueueDepth;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4820
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4821
    __KTRACE_OPT(KUSB, Kern::Printf("< TUsbPeriDeviceEventQueue::FifoAdd %d , %d",iDeviceQueueHead,iDeviceQueueTail));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4822
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4823
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4824
// FifoAdd will be called from thread context
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4825
UsbShai::TUsbPeripheralEvent TUsbPeriDeviceEventQueue::FifoGet()
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4826
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4827
    __KTRACE_OPT(KUSB, Kern::Printf("> TUsbPeriDeviceEventQueue::FifoGet %d , %d",iDeviceQueueHead,iDeviceQueueTail));    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4828
    UsbShai::TUsbPeripheralEvent ret = (UsbShai::TUsbPeripheralEvent)-1;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4829
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4830
    if(iDeviceQueueHead != iDeviceQueueTail)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4831
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4832
        ret = iDeviceEventQueue[iDeviceQueueHead];    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4833
        iDeviceQueueHead++;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4834
        iDeviceQueueHead %= KUsbDeviceEventQueueDepth;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4835
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4836
    __KTRACE_OPT(KUSB, Kern::Printf("< TUsbPeriDeviceEventQueue::FifoGet %d , %d",iDeviceQueueHead,iDeviceQueueTail));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4837
    return ret;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4838
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4839
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4840
/** Sets some data members of this request for a read request.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4841
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4842
    @param aBufferStart The start of the data buffer to be filled.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4843
    @param aBufferAddr The physical address of the buffer (used for DMA).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4844
    @param aPacketIndex A pointer to the packet index values array.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4845
    @param aPacketSize A pointer to the packet size values array.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4846
    @param aLength The number of bytes to be received.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4847
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4848
EXPORT_C void TUsbcRequestCallback::SetRxBufferInfo(TUint8* aBufferStart, TUintPtr aBufferAddr,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4849
                                           TUint32* aPacketIndex,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4850
                                           TUint32* aPacketSize,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4851
                                           TInt aLength)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4852
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4853
    iTransferDir = UsbShai::EControllerRead;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4854
    iBufferStart = aBufferStart;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4855
    iBufferAddr = aBufferAddr;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4856
    iPacketIndex = aPacketIndex;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4857
    iPacketSize = aPacketSize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4858
    iLength = aLength;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4859
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4860
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4861
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4862
/** Sets some data members of this request for a write request.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4863
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4864
    @param aBufferStart The start of the buffer that contains the data to be sent.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4865
    @param aBufferAddr The physical address of the buffer (used for DMA).
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4866
    @param aLength The number of bytes to be transmitted.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4867
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4868
EXPORT_C void TUsbcRequestCallback::SetTxBufferInfo(TUint8* aBufferStart, TUintPtr aBufferAddr, TInt aLength)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4869
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4870
    iTransferDir = UsbShai::EControllerWrite;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4871
    iBufferStart = aBufferStart;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4872
    iBufferAddr = aBufferAddr;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4873
    iLength = aLength;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4874
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4875
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4876
EXPORT_C UsbShai::TUsbPeripheralRequest::TUsbPeripheralRequest(TInt aRealEpNum):
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4877
    iRealEpNum(aRealEpNum),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4878
    iBufferStart(NULL), 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4879
    iBufferAddr(0),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4880
    iLength(0),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4881
    iTxBytes(0),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4882
    iRxPackets(0),   
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4883
    iPacketIndex(NULL),          // actually TUint16 (*)[]
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4884
    iPacketSize(NULL),           // actually TUint16 (*)[]
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4885
    iTransferDir(EControllerNone),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4886
    iZlpReqd(EFalse),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4887
    iError(KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4888
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4889
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4890
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4891
// Peripheral PSL use this interface to register itself to PIL layer, in our case, 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4892
// DUsbClientController instance
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4893
//
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4894
// param aPeripheralControllerIf point to an implementation of 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4895
// UsbShai::MPeripheralControllerIf which represent a peripheral controller hardware.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4896
EXPORT_C void UsbShai::UsbPeripheralPil::RegisterPeripheralController( UsbShai::MPeripheralControllerIf& aPeripheralControllerIf, 
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4897
                                                              const UsbShai::TPeripheralControllerProperties& aProperties)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4898
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4899
    __KTRACE_OPT(KUSB, Kern::Printf("> UsbPeripheralPil::RegisterPeripheralController enter."));
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4900
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4901
    DUsbClientController* usbcc = DUsbClientController::Create(aPeripheralControllerIf,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4902
                                                               aProperties,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4903
                                                               /*aIsOtgPort=*/EFalse);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4904
    __ASSERT_DEBUG( (usbcc != NULL),
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4905
                    Kern::Fault( "DUsbClientController extension entry point: USB PSL Out of memory", __LINE__ ) );
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4906
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4907
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4908
// The way for charger detector(PSL) to make it known to us.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4909
EXPORT_C void UsbShai::UsbChargerDetectionPil::RegisterChargerDetector(UsbShai::MChargerDetectorIf&         aChargerDetector,
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4910
                                                                       UsbShai::TChargerDetectorProperties& aProperties)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4911
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4912
    // Only on charger detector is allowed per system.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4913
    if( gChargerDetector != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4914
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4915
        return ;
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4916
        }
48
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4917
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4918
    // We take a direct copy of the charger detector properties for
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4919
    // now. If fields are later added to the properties classes in the
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4920
    // SHAI, we need to start copying field-by-field and check the PSL
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4921
    // reported capabilities before accessing a field that may not be
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4922
    // present in an older PSL binary.
33
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4923
    gChargerDetector = &aChargerDetector;
48
21625e5de155 201035_01
hgs
parents: 33
diff changeset
  4924
    gChargerDetectorProperties = aProperties;
33
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4925
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4926
    if(gChargerObsever != NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4927
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4928
        // Register to charger detector to listen to any charger type change
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4929
        // events.
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4930
        gChargerDetector->SetChargerDetectorObserver(*gChargerObsever);
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4931
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4932
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4933
089413cdde3c 201028_02
hgs
parents:
diff changeset
  4934
// -EOF-