usbdrv/peripheral/pdd/pil/src/misc.cpp
author hgs
Wed, 20 Oct 2010 12:04:53 +0800
changeset 59 bbdce6bffaad
parent 33 089413cdde3c
permissions -rw-r--r--
201041_02
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
59
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
     1
/*
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
     2
* Copyright (c) 2010 Nokia Corporation and/or its subsidiary(-ies).
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
     3
* All rights reserved.
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
     4
* This component and the accompanying materials are made available
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
     5
* under the terms of "Eclipse Public License v1.0"
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
     6
* which accompanies this distribution, and is available
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
     7
* at the URL "http://www.eclipse.org/legal/epl-v10.html".
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
     8
*
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
     9
* Initial Contributors:
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
    10
* Nokia Corporation - initial contribution.
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
    11
*
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
    12
* Contributors:
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
    13
*
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
    14
* Description:
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
    15
* e32/drivers/usbcc/misc.cpp
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
    16
* Platform independent layer (PIL) of the USB Device controller driver:
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
    17
* Implementations of misc. classes defined in usbc.h.
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
    18
*
bbdce6bffaad 201041_02
hgs
parents: 33
diff changeset
    19
*/
33
089413cdde3c 201028_02
hgs
parents:
diff changeset
    20
089413cdde3c 201028_02
hgs
parents:
diff changeset
    21
/**
089413cdde3c 201028_02
hgs
parents:
diff changeset
    22
 @file misc.cpp
089413cdde3c 201028_02
hgs
parents:
diff changeset
    23
 @internalTechnology
089413cdde3c 201028_02
hgs
parents:
diff changeset
    24
*/
089413cdde3c 201028_02
hgs
parents:
diff changeset
    25
// #include <drivers/usbc.h>
089413cdde3c 201028_02
hgs
parents:
diff changeset
    26
#include <usb/usbc.h>
089413cdde3c 201028_02
hgs
parents:
diff changeset
    27
089413cdde3c 201028_02
hgs
parents:
diff changeset
    28
089413cdde3c 201028_02
hgs
parents:
diff changeset
    29
/** Helper function for logical endpoints and endpoint descriptors:
089413cdde3c 201028_02
hgs
parents:
diff changeset
    30
    Split single Ep size into separate FS/HS sizes.
089413cdde3c 201028_02
hgs
parents:
diff changeset
    31
    This function modifies its arguments.
089413cdde3c 201028_02
hgs
parents:
diff changeset
    32
 */
089413cdde3c 201028_02
hgs
parents:
diff changeset
    33
TInt TUsbcEndpointInfo::AdjustEpSizes(TInt& aEpSize_Fs, TInt& aEpSize_Hs) const
089413cdde3c 201028_02
hgs
parents:
diff changeset
    34
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    35
    if (iType == UsbShai::KUsbEpTypeBulk)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    36
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    37
        // FS: [8|16|32|64] HS: 512
089413cdde3c 201028_02
hgs
parents:
diff changeset
    38
        if (iSize < 64)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    39
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    40
            aEpSize_Fs = iSize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    41
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    42
        else
089413cdde3c 201028_02
hgs
parents:
diff changeset
    43
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    44
            aEpSize_Fs = 64;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    45
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    46
        aEpSize_Hs = 512;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    47
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    48
    else if (iType == UsbShai::KUsbEpTypeInterrupt)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    49
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    50
        // FS: [0..64] HS: [0..1024]
089413cdde3c 201028_02
hgs
parents:
diff changeset
    51
        if (iSize < 64)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    52
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    53
            aEpSize_Fs = iSize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    54
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    55
        else
089413cdde3c 201028_02
hgs
parents:
diff changeset
    56
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    57
            aEpSize_Fs = 64;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    58
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    59
        aEpSize_Hs = iSize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    60
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    61
    else if (iType == UsbShai::KUsbEpTypeIsochronous)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    62
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    63
        // FS: [0..1023] HS: [0..1024]
089413cdde3c 201028_02
hgs
parents:
diff changeset
    64
        if (iSize < 1023)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    65
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    66
            aEpSize_Fs = iSize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    67
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    68
        else
089413cdde3c 201028_02
hgs
parents:
diff changeset
    69
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    70
            aEpSize_Fs = 1023;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    71
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    72
        aEpSize_Hs = iSize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    73
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    74
    else if (iType == UsbShai::KUsbEpTypeControl)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    75
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    76
        // FS: [8|16|32|64] HS: 64
089413cdde3c 201028_02
hgs
parents:
diff changeset
    77
        if (iSize < 64)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    78
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    79
            aEpSize_Fs = iSize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    80
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    81
        else
089413cdde3c 201028_02
hgs
parents:
diff changeset
    82
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    83
            aEpSize_Fs = 64;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    84
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    85
        aEpSize_Hs = 64;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    86
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    87
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
    88
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    89
        aEpSize_Fs = aEpSize_Hs = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    90
        return KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    91
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    92
089413cdde3c 201028_02
hgs
parents:
diff changeset
    93
    // For the reason of the following checks see Table 9-14. "Allowed wMaxPacketSize
089413cdde3c 201028_02
hgs
parents:
diff changeset
    94
    // Values for Different Numbers of Transactions per Microframe".
089413cdde3c 201028_02
hgs
parents:
diff changeset
    95
    if ((iType == UsbShai::KUsbEpTypeInterrupt) || (iType == UsbShai::KUsbEpTypeIsochronous))
089413cdde3c 201028_02
hgs
parents:
diff changeset
    96
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    97
        if (iTransactions == 1)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    98
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    99
            if (aEpSize_Hs < 513)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   100
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   101
                __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Ep size too small: %d < 513. Correcting...",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   102
                                                  aEpSize_Hs));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   103
                aEpSize_Hs = 513;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   104
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   105
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   106
        else if (iTransactions == 2)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   107
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   108
            if (aEpSize_Hs < 683)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   109
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   110
                __KTRACE_OPT(KPANIC, Kern::Printf("  Warning: Ep size too small: %d < 683. Correcting...",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   111
                                                  aEpSize_Hs));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   112
                aEpSize_Hs = 683;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   113
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   114
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   115
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   116
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   117
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   118
089413cdde3c 201028_02
hgs
parents:
diff changeset
   119
089413cdde3c 201028_02
hgs
parents:
diff changeset
   120
/** Helper function for logical endpoints and endpoint descriptors:
089413cdde3c 201028_02
hgs
parents:
diff changeset
   121
    If not set, assign a valid and meaningful value to iInterval_Hs, deriving from iInterval.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   122
    This function modifies the objects's data member(s).
089413cdde3c 201028_02
hgs
parents:
diff changeset
   123
 */
089413cdde3c 201028_02
hgs
parents:
diff changeset
   124
TInt TUsbcEndpointInfo::AdjustPollInterval()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   125
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   126
    if (iInterval_Hs != -1)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   127
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   128
        // Already done.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   129
        return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   130
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   131
    if ((iType == UsbShai::KUsbEpTypeBulk) || (iType == UsbShai::KUsbEpTypeControl))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   132
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   133
        // Valid range: 0..255 (maximum NAK rate).
089413cdde3c 201028_02
hgs
parents:
diff changeset
   134
        // (The host controller will probably ignore this value though -
089413cdde3c 201028_02
hgs
parents:
diff changeset
   135
        //  see the last sentence of section 9.6.6 for details.)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   136
        iInterval_Hs = 255;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   137
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   138
    else if (iType == UsbShai::KUsbEpTypeInterrupt)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   139
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   140
        // HS interval = 2^(iInterval_Hs-1) with a valid iInterval_Hs range of 1..16.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   141
        // The following table shows the mapping of HS values to actual intervals (and
089413cdde3c 201028_02
hgs
parents:
diff changeset
   142
        // thus FS values) for the range of possible FS values (1..255).
089413cdde3c 201028_02
hgs
parents:
diff changeset
   143
        // There is not always a 1:1 mapping possible, but we want at least to make sure
089413cdde3c 201028_02
hgs
parents:
diff changeset
   144
        // that the HS polling interval is never longer than the FS one (except for 255).
089413cdde3c 201028_02
hgs
parents:
diff changeset
   145
        //
089413cdde3c 201028_02
hgs
parents:
diff changeset
   146
        // 1 = 1
089413cdde3c 201028_02
hgs
parents:
diff changeset
   147
        // 2 = 2
089413cdde3c 201028_02
hgs
parents:
diff changeset
   148
        // 3 = 4
089413cdde3c 201028_02
hgs
parents:
diff changeset
   149
        // 4 = 8
089413cdde3c 201028_02
hgs
parents:
diff changeset
   150
        // 5 = 16
089413cdde3c 201028_02
hgs
parents:
diff changeset
   151
        // 6 = 32
089413cdde3c 201028_02
hgs
parents:
diff changeset
   152
        // 7 = 64
089413cdde3c 201028_02
hgs
parents:
diff changeset
   153
        // 8 = 128
089413cdde3c 201028_02
hgs
parents:
diff changeset
   154
        // 9 = 256
089413cdde3c 201028_02
hgs
parents:
diff changeset
   155
        if (iInterval == 255)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   156
            iInterval_Hs = 9;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   157
        else if (iInterval >= 128)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   158
            iInterval_Hs = 8;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   159
        else if (iInterval >= 64)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   160
            iInterval_Hs = 7;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   161
        else if (iInterval >= 32)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   162
            iInterval_Hs = 6;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   163
        else if (iInterval >= 16)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   164
            iInterval_Hs = 5;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   165
        else if (iInterval >= 8)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   166
            iInterval_Hs = 4;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   167
        else if (iInterval >= 4)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   168
            iInterval_Hs = 3;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   169
        else if (iInterval >= 2)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   170
            iInterval_Hs = 2;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   171
        else if (iInterval == 1)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   172
            iInterval_Hs = 1;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   173
        else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   174
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   175
            // iInterval wasn't set properly by the user
089413cdde3c 201028_02
hgs
parents:
diff changeset
   176
            iInterval_Hs = 1;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   177
            return KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   178
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   179
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   180
    else if (iType == UsbShai::KUsbEpTypeIsochronous)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   181
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   182
        // Interpretation is the same for FS and HS.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   183
        iInterval_Hs = iInterval;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   184
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   185
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   186
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   187
        // '1' is a valid value for all endpoint types...
089413cdde3c 201028_02
hgs
parents:
diff changeset
   188
        iInterval_Hs = 1;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   189
        return KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   190
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   191
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   192
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   193
089413cdde3c 201028_02
hgs
parents:
diff changeset
   194
089413cdde3c 201028_02
hgs
parents:
diff changeset
   195
TUsbcPhysicalEndpoint::TUsbcPhysicalEndpoint()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   196
    : iEndpointAddr(0), iIfcNumber(NULL), iLEndpoint(NULL), iSettingReserve(EFalse), iHalt(EFalse)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   197
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   198
    __KTRACE_OPT(KUSB, Kern::Printf("TUsbcPhysicalEndpoint::TUsbcPhysicalEndpoint"));
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
TInt TUsbcPhysicalEndpoint::TypeAvailable(TUint aType) const
089413cdde3c 201028_02
hgs
parents:
diff changeset
   203
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   204
    __KTRACE_OPT(KUSB, Kern::Printf("TUsbcPhysicalEndpoint::TypeAvailable"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   205
    switch (aType)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   206
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   207
    case UsbShai::KUsbEpTypeControl:
089413cdde3c 201028_02
hgs
parents:
diff changeset
   208
        return (iCaps.iTypesAndDir & UsbShai::KUsbEpTypeControl);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   209
    case UsbShai::KUsbEpTypeIsochronous:
089413cdde3c 201028_02
hgs
parents:
diff changeset
   210
        return (iCaps.iTypesAndDir & UsbShai::KUsbEpTypeIsochronous);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   211
    case UsbShai::KUsbEpTypeBulk:
089413cdde3c 201028_02
hgs
parents:
diff changeset
   212
        return (iCaps.iTypesAndDir & UsbShai::KUsbEpTypeBulk);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   213
    case UsbShai::KUsbEpTypeInterrupt:
089413cdde3c 201028_02
hgs
parents:
diff changeset
   214
        return (iCaps.iTypesAndDir & UsbShai::KUsbEpTypeInterrupt);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   215
    default:
089413cdde3c 201028_02
hgs
parents:
diff changeset
   216
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: invalid EP type: %d", aType));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   217
        return 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   218
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   219
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   220
089413cdde3c 201028_02
hgs
parents:
diff changeset
   221
089413cdde3c 201028_02
hgs
parents:
diff changeset
   222
TInt TUsbcPhysicalEndpoint::DirAvailable(TUint aDir) const
089413cdde3c 201028_02
hgs
parents:
diff changeset
   223
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   224
    __KTRACE_OPT(KUSB, Kern::Printf("TUsbcPhysicalEndpoint::DirAvailable"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   225
    switch (aDir)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   226
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   227
    case UsbShai::KUsbEpDirIn:
089413cdde3c 201028_02
hgs
parents:
diff changeset
   228
        return (iCaps.iTypesAndDir & UsbShai::KUsbEpDirIn);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   229
    case UsbShai::KUsbEpDirOut:
089413cdde3c 201028_02
hgs
parents:
diff changeset
   230
        return (iCaps.iTypesAndDir & UsbShai::KUsbEpDirOut);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   231
    default:
089413cdde3c 201028_02
hgs
parents:
diff changeset
   232
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: invalid EP direction: %d", aDir));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   233
        return 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   234
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   235
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   236
089413cdde3c 201028_02
hgs
parents:
diff changeset
   237
089413cdde3c 201028_02
hgs
parents:
diff changeset
   238
TInt TUsbcPhysicalEndpoint::EndpointSuitable(const TUsbcEndpointInfo* aEpInfo, TInt aIfcNumber) const
089413cdde3c 201028_02
hgs
parents:
diff changeset
   239
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   240
    __KTRACE_OPT(KUSB, Kern::Printf("TUsbcPhysicalEndpoint::EndpointSuitable"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   241
    __KTRACE_OPT(KUSB, Kern::Printf("  looking for EP: type=0x%x dir=0x%x size=%d (ifc_num=%d)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   242
                                    aEpInfo->iType, aEpInfo->iDir, aEpInfo->iSize, aIfcNumber));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   243
    if (iSettingReserve)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   244
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   245
        __KTRACE_OPT(KUSB, Kern::Printf("  -> setting conflict"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   246
        return 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   247
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   248
    // (aIfcNumber == -1) means the ep is for a new default interface setting
089413cdde3c 201028_02
hgs
parents:
diff changeset
   249
    else if (iIfcNumber && (*iIfcNumber != aIfcNumber))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   250
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   251
        // If this endpoint has already been claimed (iIfcNumber != NULL),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   252
        // but by a different interface(-set) than the currently looking one
089413cdde3c 201028_02
hgs
parents:
diff changeset
   253
        // (*iIfcNumber != aIfcNumber), then it's not available.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   254
        // This works because we can assign the same physical endpoint
089413cdde3c 201028_02
hgs
parents:
diff changeset
   255
        // to different alternate settings of the *same* interface, and
089413cdde3c 201028_02
hgs
parents:
diff changeset
   256
        // because we check for available endpoints for every alternate setting
089413cdde3c 201028_02
hgs
parents:
diff changeset
   257
        // as a whole.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   258
        __KTRACE_OPT(KUSB, Kern::Printf("  -> ifc conflict"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   259
        return 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   260
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   261
    else if (!TypeAvailable(aEpInfo->iType))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   262
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   263
        __KTRACE_OPT(KUSB, Kern::Printf("  -> type conflict"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   264
        return 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   265
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   266
    else if (!DirAvailable(aEpInfo->iDir))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   267
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   268
        __KTRACE_OPT(KUSB, Kern::Printf("  -> direction conflict"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   269
        return 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   270
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   271
    else if (!(iCaps.iSizes & PacketSize2Mask(aEpInfo->iSize)) && !(iCaps.iSizes & UsbShai::KUsbEpSizeCont))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   272
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   273
        __KTRACE_OPT(KUSB, Kern::Printf("  -> size conflict"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   274
        return 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   275
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   276
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   277
        return 1;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   278
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   279
089413cdde3c 201028_02
hgs
parents:
diff changeset
   280
089413cdde3c 201028_02
hgs
parents:
diff changeset
   281
TUsbcPhysicalEndpoint::~TUsbcPhysicalEndpoint()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   282
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   283
    __KTRACE_OPT(KUSB, Kern::Printf("TUsbcPhysicalEndpoint::~TUsbcPhysicalEndpoint()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   284
    iLEndpoint = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   285
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   286
089413cdde3c 201028_02
hgs
parents:
diff changeset
   287
089413cdde3c 201028_02
hgs
parents:
diff changeset
   288
TUsbcLogicalEndpoint::TUsbcLogicalEndpoint(DUsbClientController* aController, TUint aEndpointNum,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   289
                                           const TUsbcEndpointInfo& aEpInfo, TUsbcInterface* aInterface,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   290
                                           TUsbcPhysicalEndpoint* aPEndpoint)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   291
    : iController(aController), iLEndpointNum(aEndpointNum), iInfo(aEpInfo), iInterface(aInterface),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   292
      iPEndpoint(aPEndpoint)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   293
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   294
    __KTRACE_OPT(KUSB, Kern::Printf("TUsbcLogicalEndpoint::TUsbcLogicalEndpoint()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   295
    //  Adjust FS/HS endpoint sizes
089413cdde3c 201028_02
hgs
parents:
diff changeset
   296
    if (iInfo.AdjustEpSizes(iEpSize_Fs, iEpSize_Hs) != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   297
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   298
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Unknown endpoint type: %d", iInfo.iType));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   299
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   300
    __KTRACE_OPT(KUSB, Kern::Printf("  Now set: iEpSize_Fs=%d iEpSize_Hs=%d (iInfo.iSize=%d)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   301
                                    iEpSize_Fs, iEpSize_Hs, iInfo.iSize));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   302
    //  Adjust HS polling interval
089413cdde3c 201028_02
hgs
parents:
diff changeset
   303
    if (iInfo.AdjustPollInterval() != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   304
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   305
        __KTRACE_OPT(KPANIC, Kern::Printf("  Error: Unknown ep type (%d) or invalid interval value (%d)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   306
                                          iInfo.iType, iInfo.iInterval));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   307
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   308
    __KTRACE_OPT(KUSB, Kern::Printf("  Now set: iInfo.iInterval=%d iInfo.iInterval_Hs=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   309
                                    iInfo.iInterval, iInfo.iInterval_Hs));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   310
    // Additional transactions requested on a non High Bandwidth ep?
089413cdde3c 201028_02
hgs
parents:
diff changeset
   311
    if ((iInfo.iTransactions > 0) && !aPEndpoint->iCaps.iHighBandwidth)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   312
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   313
        __KTRACE_OPT(KPANIC,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   314
                     Kern::Printf("  Warning: Additional transactions requested but not a High Bandwidth ep"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   315
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   316
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   317
089413cdde3c 201028_02
hgs
parents:
diff changeset
   318
089413cdde3c 201028_02
hgs
parents:
diff changeset
   319
TUsbcLogicalEndpoint::~TUsbcLogicalEndpoint()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   320
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   321
    __KTRACE_OPT(KUSB, Kern::Printf("TUsbcLogicalEndpoint::~TUsbcLogicalEndpoint: #%d", iLEndpointNum));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   322
    // If the real endpoint this endpoint points to is also used by
089413cdde3c 201028_02
hgs
parents:
diff changeset
   323
    // any other logical endpoint in any other setting of this interface
089413cdde3c 201028_02
hgs
parents:
diff changeset
   324
    // then we leave the real endpoint marked as used. Otherwise we mark
089413cdde3c 201028_02
hgs
parents:
diff changeset
   325
    // it as available (set its ifc number pointer to NULL).
089413cdde3c 201028_02
hgs
parents:
diff changeset
   326
    const TInt n = iInterface->iInterfaceSet->iInterfaces.Count();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   327
    for (TInt i = 0; i < n; ++i)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   328
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   329
        const TUsbcInterface* const ifc = iInterface->iInterfaceSet->iInterfaces[i];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   330
        const TInt m = ifc->iEndpoints.Count();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   331
        for (TInt j = 0; j < m; ++j)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   332
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   333
            const TUsbcLogicalEndpoint* const ep = ifc->iEndpoints[j];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   334
            if ((ep->iPEndpoint == iPEndpoint) && (ep != this))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   335
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   336
                __KTRACE_OPT(KUSB, Kern::Printf("  Physical endpoint still in use -> we leave it as is"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   337
                return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   338
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   339
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   340
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   341
    __KTRACE_OPT(KUSB, Kern::Printf("  Closing DMA channel"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   342
    const TInt idx = iController->EpAddr2Idx(iPEndpoint->iEndpointAddr);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   343
    // If the endpoint doesn't support DMA (now or ever) the next operation will be a no-op.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   344
    // iController->CloseDmaChannel(idx);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   345
    __KTRACE_OPT(KUSB, Kern::Printf("  Setting physical ep 0x%02x ifc number to NULL (was %d)",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   346
                                    iPEndpoint->iEndpointAddr, *iPEndpoint->iIfcNumber));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   347
    iPEndpoint->iIfcNumber = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   348
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   349
089413cdde3c 201028_02
hgs
parents:
diff changeset
   350
089413cdde3c 201028_02
hgs
parents:
diff changeset
   351
TUsbcInterface::TUsbcInterface(TUsbcInterfaceSet* aIfcSet, TUint8 aSetting, TBool aNoEp0Requests)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   352
    : iEndpoints(2), iInterfaceSet(aIfcSet), iSettingCode(aSetting), iNoEp0Requests(aNoEp0Requests)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   353
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   354
    __KTRACE_OPT(KUSB, Kern::Printf("TUsbcInterface::TUsbcInterface()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   355
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   356
089413cdde3c 201028_02
hgs
parents:
diff changeset
   357
089413cdde3c 201028_02
hgs
parents:
diff changeset
   358
TUsbcInterface::~TUsbcInterface()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   359
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   360
    __KTRACE_OPT(KUSB, Kern::Printf("TUsbcInterface::~TUsbcInterface()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   361
    iEndpoints.ResetAndDestroy();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   362
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   363
089413cdde3c 201028_02
hgs
parents:
diff changeset
   364
089413cdde3c 201028_02
hgs
parents:
diff changeset
   365
TUsbcInterfaceSet::TUsbcInterfaceSet(const DBase* aClientId, TUint8 aIfcNum)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   366
    : iInterfaces(2), iClientId(aClientId), iInterfaceNumber(aIfcNum), iCurrentInterface(0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   367
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   368
    __KTRACE_OPT(KUSB, Kern::Printf("TUsbcInterfaceSet::TUsbcInterfaceSet()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   369
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   370
089413cdde3c 201028_02
hgs
parents:
diff changeset
   371
089413cdde3c 201028_02
hgs
parents:
diff changeset
   372
TUsbcInterfaceSet::~TUsbcInterfaceSet()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   373
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   374
    __KTRACE_OPT(KUSB, Kern::Printf("TUsbcInterfaceSet::~TUsbcInterfaceSet()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   375
    iInterfaces.ResetAndDestroy();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   376
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   377
089413cdde3c 201028_02
hgs
parents:
diff changeset
   378
089413cdde3c 201028_02
hgs
parents:
diff changeset
   379
TUsbcConfiguration::TUsbcConfiguration(TUint8 aConfigVal)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   380
    : iInterfaceSets(1), iConfigValue(aConfigVal)            // iInterfaceSets(1): granularity
089413cdde3c 201028_02
hgs
parents:
diff changeset
   381
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   382
    __KTRACE_OPT(KUSB, Kern::Printf("TUsbcConfiguration::TUsbcConfiguration()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   383
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   384
089413cdde3c 201028_02
hgs
parents:
diff changeset
   385
089413cdde3c 201028_02
hgs
parents:
diff changeset
   386
TUsbcConfiguration::~TUsbcConfiguration()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   387
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   388
    __KTRACE_OPT(KUSB, Kern::Printf("TUsbcConfiguration::~TUsbcConfiguration()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   389
    iInterfaceSets.ResetAndDestroy();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   390
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   391
089413cdde3c 201028_02
hgs
parents:
diff changeset
   392
089413cdde3c 201028_02
hgs
parents:
diff changeset
   393
_LIT(KDriverName, "Usbcc");
089413cdde3c 201028_02
hgs
parents:
diff changeset
   394
089413cdde3c 201028_02
hgs
parents:
diff changeset
   395
DUsbcPowerHandler::DUsbcPowerHandler(DUsbClientController* aController)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   396
    : DPowerHandler(KDriverName), iController(aController)
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
void DUsbcPowerHandler::PowerUp()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   401
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   402
    if (iController)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   403
        iController->iPowerUpDfc.Enque();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   404
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   405
089413cdde3c 201028_02
hgs
parents:
diff changeset
   406
089413cdde3c 201028_02
hgs
parents:
diff changeset
   407
void DUsbcPowerHandler::PowerDown(TPowerState)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   408
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   409
    if (iController)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   410
        iController->iPowerDownDfc.Enque();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   411
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   412
089413cdde3c 201028_02
hgs
parents:
diff changeset
   413
089413cdde3c 201028_02
hgs
parents:
diff changeset
   414
// -eof-