usbdrv/peripheral/ldd/perildd/src/usbdma.cpp
author hgs
Fri, 23 Jul 2010 15:54:47 +0800
changeset 33 089413cdde3c
child 59 bbdce6bffaad
permissions -rw-r--r--
201028_02
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\usbc\usbdma.cpp
089413cdde3c 201028_02
hgs
parents:
diff changeset
    15
// LDD for USB Device driver stack:
089413cdde3c 201028_02
hgs
parents:
diff changeset
    16
// Management of DMA-capable data buffers.
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 usbdma.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
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
089413cdde3c 201028_02
hgs
parents:
diff changeset
    28
#if defined(_DEBUG)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    29
static const char KUsbPanicLdd[] = "USB LDD";
089413cdde3c 201028_02
hgs
parents:
diff changeset
    30
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
    31
089413cdde3c 201028_02
hgs
parents:
diff changeset
    32
089413cdde3c 201028_02
hgs
parents:
diff changeset
    33
TDmaBuf::TDmaBuf(TUsbcEndpointInfo* aEndpointInfo, TInt aBandwidthPriority)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    34
    : iBufBasePtr(NULL),
089413cdde3c 201028_02
hgs
parents:
diff changeset
    35
      iCurrentDrainingBuffer(NULL),
089413cdde3c 201028_02
hgs
parents:
diff changeset
    36
      iCurrentPacket(0),
089413cdde3c 201028_02
hgs
parents:
diff changeset
    37
      iCurrentPacketIndexArray(NULL),
089413cdde3c 201028_02
hgs
parents:
diff changeset
    38
      iCurrentPacketSizeArray(NULL)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    39
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    40
    iMaxPacketSize = aEndpointInfo->iSize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    41
    iEndpointType = aEndpointInfo->iType;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    42
089413cdde3c 201028_02
hgs
parents:
diff changeset
    43
    switch (aEndpointInfo->iType)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    44
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    45
    case UsbShai::KUsbEpTypeControl:
089413cdde3c 201028_02
hgs
parents:
diff changeset
    46
        iBufSz = KUsbcDmaBufSzControl;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    47
        iNumberofBuffers = KUsbcDmaBufNumControl;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    48
        break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    49
    case UsbShai::KUsbEpTypeIsochronous:
089413cdde3c 201028_02
hgs
parents:
diff changeset
    50
        iBufSz = KUsbcDmaBufSzIsochronous;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    51
        iNumberofBuffers = KUsbcDmaBufNumIsochronous;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    52
        break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    53
    case UsbShai::KUsbEpTypeBulk:
089413cdde3c 201028_02
hgs
parents:
diff changeset
    54
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    55
        if (aEndpointInfo->iDir == UsbShai::KUsbEpDirOut)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    56
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    57
            const TInt priorityOUT = aBandwidthPriority & 0x0f;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    58
            iBufSz = KUsbcDmaBufSizesBulkOUT[priorityOUT];
089413cdde3c 201028_02
hgs
parents:
diff changeset
    59
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    60
        else
089413cdde3c 201028_02
hgs
parents:
diff changeset
    61
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    62
            const TInt priorityIN = (aBandwidthPriority >> 4) & 0x0f;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    63
            iBufSz = KUsbcDmaBufSizesBulkIN[priorityIN];
089413cdde3c 201028_02
hgs
parents:
diff changeset
    64
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    65
        iNumberofBuffers = KUsbcDmaBufNumBulk;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    66
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    67
        break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    68
    case UsbShai::KUsbEpTypeInterrupt:
089413cdde3c 201028_02
hgs
parents:
diff changeset
    69
        iBufSz = KUsbcDmaBufSzInterrupt;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    70
        iNumberofBuffers = KUsbcDmaBufNumInterrupt;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    71
        break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    72
    default:
089413cdde3c 201028_02
hgs
parents:
diff changeset
    73
        iBufSz = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    74
        iNumberofBuffers = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    75
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    76
089413cdde3c 201028_02
hgs
parents:
diff changeset
    77
    if (aEndpointInfo->iDir == UsbShai::KUsbEpDirIn)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    78
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    79
        iNumberofBuffers = 1;                                // IN endpoints only have 1 buffer
089413cdde3c 201028_02
hgs
parents:
diff changeset
    80
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    81
089413cdde3c 201028_02
hgs
parents:
diff changeset
    82
    for (TInt i = 0; i < KUsbcDmaBufNumMax; i++)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    83
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    84
        // Buffer logical addresses (pointers)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    85
        iBuffers[i] = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    86
        // Buffer physical addresses
089413cdde3c 201028_02
hgs
parents:
diff changeset
    87
        iBufferPhys[i] = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    88
        // Packet indexes base array
089413cdde3c 201028_02
hgs
parents:
diff changeset
    89
        iPacketIndex[i] = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    90
        // Packet sizes base array
089413cdde3c 201028_02
hgs
parents:
diff changeset
    91
        iPacketSize[i] = NULL;
089413cdde3c 201028_02
hgs
parents:
diff changeset
    92
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    93
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
    94
089413cdde3c 201028_02
hgs
parents:
diff changeset
    95
089413cdde3c 201028_02
hgs
parents:
diff changeset
    96
TInt TDmaBuf::Construct(TUsbcEndpointInfo* aEndpointInfo)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    97
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
    98
    if (aEndpointInfo->iDir != UsbShai::KUsbEpDirIn)
089413cdde3c 201028_02
hgs
parents:
diff changeset
    99
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   100
        // IN endpoints don't need a packet array
089413cdde3c 201028_02
hgs
parents:
diff changeset
   101
089413cdde3c 201028_02
hgs
parents:
diff changeset
   102
        // At most 2 packets (clump of max packet size packets) + possible zlp
089413cdde3c 201028_02
hgs
parents:
diff changeset
   103
        TUsbcPacketArray* bufPtr = iPacketInfoStorage;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   104
        // this divides up the packet indexing & packet size array over the number of buffers
089413cdde3c 201028_02
hgs
parents:
diff changeset
   105
        __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::Construct() array base=0x%08x", bufPtr));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   106
        for (TInt i = 0; i < iNumberofBuffers; i++)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   107
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   108
            iPacketIndex[i] = bufPtr;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   109
            bufPtr += KUsbcDmaBufMaxPkts;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   110
            iPacketSize[i] = bufPtr;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   111
            bufPtr += KUsbcDmaBufMaxPkts;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   112
            __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::Construct() packetIndex[%d]=0x%08x packetSize[%d]=0x%08x",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   113
                                            i, iPacketIndex[i], i, iPacketSize[i]));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   114
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   115
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   116
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   117
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   118
        __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::Construct() IN endpoint"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   119
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   120
    Flush();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   121
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   122
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   123
089413cdde3c 201028_02
hgs
parents:
diff changeset
   124
089413cdde3c 201028_02
hgs
parents:
diff changeset
   125
TDmaBuf::~TDmaBuf()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   126
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   127
    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::~TDmaBuf()"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   128
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   129
089413cdde3c 201028_02
hgs
parents:
diff changeset
   130
TInt TDmaBuf::BufferTotalSize() const
089413cdde3c 201028_02
hgs
parents:
diff changeset
   131
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   132
    return iBufSz * iNumberofBuffers;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   133
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   134
089413cdde3c 201028_02
hgs
parents:
diff changeset
   135
TInt TDmaBuf::BufferSize() const
089413cdde3c 201028_02
hgs
parents:
diff changeset
   136
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   137
    return iBufSz;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   138
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   139
089413cdde3c 201028_02
hgs
parents:
diff changeset
   140
TInt TDmaBuf::SetBufferAddr(TInt aBufInd, TUint8* aBufAddr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   141
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   142
    __ASSERT_DEBUG((aBufInd < iNumberofBuffers),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   143
                       Kern::Fault(KUsbPanicLdd, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   144
    iDrainable[aBufInd] = iCanBeFreed[aBufInd] = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   145
    iBuffers[aBufInd] = aBufAddr;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   146
    iBufferPhys[aBufInd] = Epoc::LinearToPhysical((TLinAddr)aBufAddr);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   147
    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::SetBufferAddr() iBuffers[%d]=0x%08x", aBufInd, iBuffers[aBufInd]));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   148
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   149
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   150
089413cdde3c 201028_02
hgs
parents:
diff changeset
   151
TInt TDmaBuf::BufferNumber() const
089413cdde3c 201028_02
hgs
parents:
diff changeset
   152
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   153
    return iNumberofBuffers;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   154
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   155
089413cdde3c 201028_02
hgs
parents:
diff changeset
   156
void TDmaBuf::SetMaxPacketSize(TInt aSize)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   157
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   158
    iMaxPacketSize = aSize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   159
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   160
089413cdde3c 201028_02
hgs
parents:
diff changeset
   161
089413cdde3c 201028_02
hgs
parents:
diff changeset
   162
void TDmaBuf::Flush()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   163
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   164
    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::Flush %x", this));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   165
    iRxActive = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   166
    iTxActive = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   167
    iExtractOffset = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   168
    iTotalRxBytesAvail = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   169
    iTotalRxPacketsAvail = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   170
    iCurrentDrainingBufferIndex = KUsbcInvalidBufferIndex;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   171
    iCurrentFillingBufferIndex = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   172
    iDrainQueueIndex = KUsbcInvalidDrainQueueIndex;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   173
    for (TInt i = 0; i < KUsbcDmaBufNumMax; i++)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   174
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   175
        iDrainable[i] = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   176
        iCanBeFreed[i] = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   177
        iNumberofBytesRx[i] = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   178
        iNumberofPacketsRx[i] = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   179
        iError[i] = KErrGeneral;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   180
        iDrainQueue[i] = KUsbcInvalidBufferIndex;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   181
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   182
        iFillingOrderArray[i] = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   183
        iNumberofBytesRxRemain[i] = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   184
        iNumberofPacketsRxRemain[i] = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   185
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   186
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   187
    // Drain queue is 1 oversized
089413cdde3c 201028_02
hgs
parents:
diff changeset
   188
    iDrainQueue[KUsbcDmaBufNumMax] = KUsbcInvalidBufferIndex;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   189
089413cdde3c 201028_02
hgs
parents:
diff changeset
   190
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   191
    iFillingOrder = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   192
    iDrainingOrder = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   193
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   194
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   195
089413cdde3c 201028_02
hgs
parents:
diff changeset
   196
089413cdde3c 201028_02
hgs
parents:
diff changeset
   197
void TDmaBuf::RxSetActive()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   198
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   199
    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxSetActive %x", this));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   200
    iRxActive = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   201
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   202
089413cdde3c 201028_02
hgs
parents:
diff changeset
   203
089413cdde3c 201028_02
hgs
parents:
diff changeset
   204
void TDmaBuf::RxSetInActive()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   205
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   206
    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxSetInActive %x", this));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   207
    iRxActive = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   208
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   209
089413cdde3c 201028_02
hgs
parents:
diff changeset
   210
089413cdde3c 201028_02
hgs
parents:
diff changeset
   211
TBool TDmaBuf::RxIsActive()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   212
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   213
    return iRxActive;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   214
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   215
089413cdde3c 201028_02
hgs
parents:
diff changeset
   216
089413cdde3c 201028_02
hgs
parents:
diff changeset
   217
void TDmaBuf::TxSetActive()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   218
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   219
    iTxActive = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   220
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   221
089413cdde3c 201028_02
hgs
parents:
diff changeset
   222
089413cdde3c 201028_02
hgs
parents:
diff changeset
   223
void TDmaBuf::TxSetInActive()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   224
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   225
    iTxActive = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   226
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   227
089413cdde3c 201028_02
hgs
parents:
diff changeset
   228
089413cdde3c 201028_02
hgs
parents:
diff changeset
   229
TBool TDmaBuf::TxIsActive()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   230
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   231
    return iTxActive;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   232
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   233
089413cdde3c 201028_02
hgs
parents:
diff changeset
   234
089413cdde3c 201028_02
hgs
parents:
diff changeset
   235
/**************************** Rx DMA Buffer Access *************************/
089413cdde3c 201028_02
hgs
parents:
diff changeset
   236
089413cdde3c 201028_02
hgs
parents:
diff changeset
   237
void TDmaBuf::ModifyTotalRxBytesAvail(TInt aVal)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   238
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   239
    iTotalRxBytesAvail += aVal;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   240
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   241
089413cdde3c 201028_02
hgs
parents:
diff changeset
   242
089413cdde3c 201028_02
hgs
parents:
diff changeset
   243
void TDmaBuf::ModifyTotalRxPacketsAvail(TInt aVal)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   244
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   245
    iTotalRxPacketsAvail += aVal;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   246
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   247
089413cdde3c 201028_02
hgs
parents:
diff changeset
   248
089413cdde3c 201028_02
hgs
parents:
diff changeset
   249
TBool TDmaBuf::AdvancePacket()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   250
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   251
    ModifyTotalRxPacketsAvail(-1);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   252
    TBool r = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   253
    __ASSERT_DEBUG((iCurrentDrainingBufferIndex >= 0),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   254
                       Kern::Fault(KUsbPanicLdd, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   255
    if (++iCurrentPacket >= iNumberofPacketsRx[iCurrentDrainingBufferIndex])
089413cdde3c 201028_02
hgs
parents:
diff changeset
   256
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   257
        r = NextDrainableBuffer();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   258
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   259
    iExtractOffset = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   260
    __ASSERT_DEBUG((iCurrentDrainingBufferIndex == KUsbcInvalidBufferIndex) ||
089413cdde3c 201028_02
hgs
parents:
diff changeset
   261
                   (iCurrentPacket < KUsbcDmaBufMaxPkts),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   262
                   Kern::Fault(KUsbPanicLdd, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   263
    return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   264
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   265
089413cdde3c 201028_02
hgs
parents:
diff changeset
   266
089413cdde3c 201028_02
hgs
parents:
diff changeset
   267
TInt TDmaBuf::PeekNextPacketSize()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   268
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   269
    TUint pkt = iCurrentPacket;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   270
    TInt index = iCurrentDrainingBufferIndex;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   271
    TInt size = -1;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   272
    if (pkt >= iNumberofPacketsRx[index])
089413cdde3c 201028_02
hgs
parents:
diff changeset
   273
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   274
        index = PeekNextDrainableBuffer();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   275
        pkt = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   276
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   277
089413cdde3c 201028_02
hgs
parents:
diff changeset
   278
    if ((index != KUsbcInvalidBufferIndex) && iNumberofPacketsRx[index])
089413cdde3c 201028_02
hgs
parents:
diff changeset
   279
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   280
        const TUsbcPacketArray* sizeArray = iPacketSize[index];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   281
        size = (TInt)sizeArray[pkt];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   282
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   283
089413cdde3c 201028_02
hgs
parents:
diff changeset
   284
    __ASSERT_DEBUG((iCurrentDrainingBufferIndex == KUsbcInvalidBufferIndex) ||
089413cdde3c 201028_02
hgs
parents:
diff changeset
   285
                   (iCurrentPacket < KUsbcDmaBufMaxPkts),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   286
                   Kern::Fault(KUsbPanicLdd, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   287
    return size;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   288
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   289
089413cdde3c 201028_02
hgs
parents:
diff changeset
   290
089413cdde3c 201028_02
hgs
parents:
diff changeset
   291
inline TInt TDmaBuf::GetCurrentError()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   292
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   293
    // USB bus errors are v.rare. To avoid having an error code attached to every packet since
089413cdde3c 201028_02
hgs
parents:
diff changeset
   294
    // almost every errorcode will be KErrNone, we have a single error code per buffer
089413cdde3c 201028_02
hgs
parents:
diff changeset
   295
    // If the error code is != KErrNone then it refers to the LAST packet in the buffer
089413cdde3c 201028_02
hgs
parents:
diff changeset
   296
    TInt errorCode = KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   297
    //Check the index, it's not equal to negative (-1) value defined in 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   298
    //KUsbcInvalidBufferIndex.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   299
    __ASSERT_DEBUG((iCurrentDrainingBufferIndex >= 0),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   300
                       Kern::Fault(KUsbPanicLdd, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   301
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   302
    if (iError[iCurrentDrainingBufferIndex] != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   303
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   304
        // See if we are at the last packet
089413cdde3c 201028_02
hgs
parents:
diff changeset
   305
        if ((iCurrentPacket + 1) == iNumberofPacketsRx[iCurrentDrainingBufferIndex])
089413cdde3c 201028_02
hgs
parents:
diff changeset
   306
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   307
            errorCode = iError[iCurrentDrainingBufferIndex];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   308
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   309
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   310
    return errorCode;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   311
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   312
089413cdde3c 201028_02
hgs
parents:
diff changeset
   313
089413cdde3c 201028_02
hgs
parents:
diff changeset
   314
// used to decide whether a client read can complete straight away
089413cdde3c 201028_02
hgs
parents:
diff changeset
   315
TBool TDmaBuf::IsReaderEmpty()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   316
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   317
    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::IsReaderEmpty iTotalRxPacketsAvail=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   318
                                    iTotalRxPacketsAvail));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   319
    return (iTotalRxPacketsAvail == 0);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   320
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   321
089413cdde3c 201028_02
hgs
parents:
diff changeset
   322
089413cdde3c 201028_02
hgs
parents:
diff changeset
   323
void TDmaBuf::ReadXferComplete(TInt aNoBytesRecv, TInt aNoPacketsRecv, TInt aErrorCode)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   324
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   325
    // Adjust pending packet
089413cdde3c 201028_02
hgs
parents:
diff changeset
   326
    if ((aNoBytesRecv == 0) && (aErrorCode != KErrNone))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   327
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   328
        // Make the buffer available for reuse
089413cdde3c 201028_02
hgs
parents:
diff changeset
   329
        iDrainable[iCurrentFillingBufferIndex] = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   330
        return;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   331
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   332
089413cdde3c 201028_02
hgs
parents:
diff changeset
   333
    ModifyTotalRxBytesAvail(aNoBytesRecv);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   334
    ModifyTotalRxPacketsAvail(aNoPacketsRecv);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   335
    iNumberofBytesRx[iCurrentFillingBufferIndex] = aNoBytesRecv;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   336
    iNumberofPacketsRx[iCurrentFillingBufferIndex] = aNoPacketsRecv;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   337
089413cdde3c 201028_02
hgs
parents:
diff changeset
   338
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   339
    iNumberofBytesRxRemain[iCurrentFillingBufferIndex] = aNoBytesRecv;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   340
    iNumberofPacketsRxRemain[iCurrentFillingBufferIndex] = aNoPacketsRecv;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   341
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   342
089413cdde3c 201028_02
hgs
parents:
diff changeset
   343
    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::ReadXferComplete 2 # of bytes=%d # of packets=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   344
                                    iTotalRxBytesAvail, iTotalRxPacketsAvail));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   345
    iDrainable[iCurrentFillingBufferIndex] = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   346
    iError[iCurrentFillingBufferIndex] = aErrorCode;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   347
    AddToDrainQueue(iCurrentFillingBufferIndex);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   348
    if (iCurrentDrainingBufferIndex == KUsbcInvalidBufferIndex)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   349
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   350
        NextDrainableBuffer();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   351
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   352
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   353
089413cdde3c 201028_02
hgs
parents:
diff changeset
   354
089413cdde3c 201028_02
hgs
parents:
diff changeset
   355
TInt TDmaBuf::RxGetNextXfer(TUint8*& aBufferAddr, TUsbcPacketArray*& aIndexArray,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   356
                            TUsbcPacketArray*& aSizeArray, TInt& aLength, TPhysAddr& aBufferPhys)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   357
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   358
    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxGetNextXfer 1"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   359
    if (RxIsActive())
089413cdde3c 201028_02
hgs
parents:
diff changeset
   360
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   361
        __KTRACE_OPT(KUSB, Kern::Printf(" ---> RxIsActive, returning"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   362
        return KErrInUse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   363
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   364
089413cdde3c 201028_02
hgs
parents:
diff changeset
   365
    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxGetNextXfer Current buffer=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   366
                                    iCurrentFillingBufferIndex));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   367
    if (iDrainable[iCurrentFillingBufferIndex])
089413cdde3c 201028_02
hgs
parents:
diff changeset
   368
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   369
        // If the controller refused the last read request, then the current buffer will still be marked
089413cdde3c 201028_02
hgs
parents:
diff changeset
   370
        // as !Drainable, because the controller never completed the read to the ldd. and therefore the buffer
089413cdde3c 201028_02
hgs
parents:
diff changeset
   371
        // can be reused.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   372
        if (!NextFillableBuffer())
089413cdde3c 201028_02
hgs
parents:
diff changeset
   373
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   374
            return KErrNoMemory;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   375
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   376
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   377
089413cdde3c 201028_02
hgs
parents:
diff changeset
   378
    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxGetNextXfer New buffer=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   379
                                    iCurrentFillingBufferIndex));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   380
    aBufferAddr = iBuffers[iCurrentFillingBufferIndex];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   381
    aBufferPhys = iBufferPhys[iCurrentFillingBufferIndex];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   382
    aIndexArray = iPacketIndex[iCurrentFillingBufferIndex];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   383
    aSizeArray = iPacketSize[iCurrentFillingBufferIndex];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   384
    aLength = iBufSz;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   385
089413cdde3c 201028_02
hgs
parents:
diff changeset
   386
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   387
    iFillingOrderArray[iCurrentFillingBufferIndex] = ++iFillingOrder;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   388
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   389
089413cdde3c 201028_02
hgs
parents:
diff changeset
   390
    return KErrNone;
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
TInt TDmaBuf::RxCopyPacketToClient(DThread* aThread, TClientBuffer *aTcb, TInt aLength)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   395
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   396
    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxCopyPacketToClient 1"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   397
089413cdde3c 201028_02
hgs
parents:
diff changeset
   398
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   399
    const TInt numPkts = NoRxPackets();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   400
    const TInt numPktsAlt = NoRxPacketsAlt();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   401
    const TInt numBytes = RxBytesAvailable();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   402
    const TInt numBytesAlt = NoRxBytesAlt();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   403
089413cdde3c 201028_02
hgs
parents:
diff changeset
   404
    if (numPkts != numPktsAlt)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   405
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   406
        Kern::Printf(
089413cdde3c 201028_02
hgs
parents:
diff changeset
   407
            "TDmaBuf::RxCopyPacketToClient: Error: #pkts mismatch global=%d actual=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   408
            numPkts, numPktsAlt);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   409
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   410
    if (numBytes != numBytesAlt)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   411
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   412
        Kern::Printf(
089413cdde3c 201028_02
hgs
parents:
diff changeset
   413
            "TDmaBuf::RxCopyPacketToClient: Error: #bytes mismatch global=%d actual=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   414
            numBytes, numBytesAlt);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   415
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   416
    if ((numPkts == 0) && (numBytes !=0))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   417
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   418
        Kern::Printf(
089413cdde3c 201028_02
hgs
parents:
diff changeset
   419
            "TDmaBuf::RxCopyPacketToClient: Error: global bytes & pkts mismatch pkts=%d bytes=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   420
            numPkts, numBytes);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   421
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   422
    if ((numPktsAlt == 0) && (numBytesAlt !=0))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   423
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   424
        Kern::Printf(
089413cdde3c 201028_02
hgs
parents:
diff changeset
   425
            "TDmaBuf::RxCopyPacketToClient: Error: actual bytes & pkts mismatch pkts=%d bytes=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   426
            numPktsAlt, numBytesAlt);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   427
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   428
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   429
089413cdde3c 201028_02
hgs
parents:
diff changeset
   430
    if (!NoRxPackets())
089413cdde3c 201028_02
hgs
parents:
diff changeset
   431
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   432
089413cdde3c 201028_02
hgs
parents:
diff changeset
   433
    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxCopyPacketToClient 2"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   434
    // the next condition should be true because we have some packets available
089413cdde3c 201028_02
hgs
parents:
diff changeset
   435
    // coverity[var_tested_neg]
089413cdde3c 201028_02
hgs
parents:
diff changeset
   436
    if (iCurrentDrainingBufferIndex == KUsbcInvalidBufferIndex)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   437
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   438
        // Marked as Coverity "Intentional" as the member variable
089413cdde3c 201028_02
hgs
parents:
diff changeset
   439
        // iCurrentDrainingBufferIndex is attentionaly negative, from previous 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   440
        // initialization to KUsbcInvalidBufferIndex (which equals -1).
089413cdde3c 201028_02
hgs
parents:
diff changeset
   441
        if (!NextDrainableBuffer())
089413cdde3c 201028_02
hgs
parents:
diff changeset
   442
            return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   443
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   444
089413cdde3c 201028_02
hgs
parents:
diff changeset
   445
    __ASSERT_DEBUG((iCurrentDrainingBufferIndex >= 0 ),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   446
                           Kern::Fault(KUsbPanicLdd, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   447
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   448
    if (!iDrainable[iCurrentDrainingBufferIndex])
089413cdde3c 201028_02
hgs
parents:
diff changeset
   449
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   450
089413cdde3c 201028_02
hgs
parents:
diff changeset
   451
    // Calculate copy-from address & adjust for the fact that
089413cdde3c 201028_02
hgs
parents:
diff changeset
   452
    // some data may have already been read from the packet
089413cdde3c 201028_02
hgs
parents:
diff changeset
   453
    TUint8* logicalSrc = iCurrentDrainingBuffer + iCurrentPacketIndexArray[iCurrentPacket] + iExtractOffset;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   454
    TInt packetSz = iCurrentPacketSizeArray[iCurrentPacket];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   455
    TInt thisPacketSz = packetSz - iExtractOffset;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   456
    TInt errorCode;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   457
    // try and sort out what a "packet" might mean.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   458
    // in a multi-packet dma environment, we might see super-packets
089413cdde3c 201028_02
hgs
parents:
diff changeset
   459
    // i.e. we might just see one packet, maybe 4K or so long, made of lots of small packets
089413cdde3c 201028_02
hgs
parents:
diff changeset
   460
    // Since we don't know where the packet boundaries will be, we have to assume that
089413cdde3c 201028_02
hgs
parents:
diff changeset
   461
    // any 'packet' larger than the max packet size of the ep is, in fact, a conglomeration
089413cdde3c 201028_02
hgs
parents:
diff changeset
   462
    // of smaller packets. However, for the purposes of the packet count, this is still regarded
089413cdde3c 201028_02
hgs
parents:
diff changeset
   463
    // as a single packet and the packet count only decremented when it is consumed.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   464
    // As before, if the user fails to read an entire packet out then the next packet is moved onto anyway
089413cdde3c 201028_02
hgs
parents:
diff changeset
   465
    // To be safe the user must always supply a buffer of at least max packet size bytes.
089413cdde3c 201028_02
hgs
parents:
diff changeset
   466
    if (thisPacketSz > iMaxPacketSize)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   467
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   468
        // Multiple packets left in buffer
089413cdde3c 201028_02
hgs
parents:
diff changeset
   469
        // calculate number of bytes to end of packet
089413cdde3c 201028_02
hgs
parents:
diff changeset
   470
        if (iEndpointType == UsbShai::KUsbEpTypeBulk)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   471
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   472
            thisPacketSz = iMaxPacketSize - (iExtractOffset & (iMaxPacketSize - 1));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   473
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   474
        else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   475
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   476
            thisPacketSz = iMaxPacketSize - (iExtractOffset % iMaxPacketSize);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   477
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   478
        errorCode = KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   479
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   480
    else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   481
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   482
        errorCode = GetCurrentError();                        // single packet left
089413cdde3c 201028_02
hgs
parents:
diff changeset
   483
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   484
089413cdde3c 201028_02
hgs
parents:
diff changeset
   485
    iExtractOffset += thisPacketSz;            // iExtractOffset is now at the end of the real or notional packet
089413cdde3c 201028_02
hgs
parents:
diff changeset
   486
089413cdde3c 201028_02
hgs
parents:
diff changeset
   487
    ModifyTotalRxBytesAvail(-thisPacketSz);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   488
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   489
    iNumberofBytesRxRemain[iCurrentDrainingBufferIndex] -= thisPacketSz;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   490
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   491
    // this can only be untrue if the "packet" is a conglomeration of smaller packets:
089413cdde3c 201028_02
hgs
parents:
diff changeset
   492
    if (iExtractOffset == packetSz)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   493
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   494
        // packet consumed, advance to next packet in buffer
089413cdde3c 201028_02
hgs
parents:
diff changeset
   495
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   496
        iNumberofPacketsRxRemain[iCurrentDrainingBufferIndex] -= 1;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   497
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   498
        AdvancePacket();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   499
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   500
089413cdde3c 201028_02
hgs
parents:
diff changeset
   501
    TPtrC8 des(logicalSrc, thisPacketSz);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   502
    TInt r=Kern::ThreadBufWrite(aThread, aTcb, des, 0, 0, aThread);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   503
    if (r == KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   504
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   505
        r = errorCode;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   506
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   507
    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxCopyPacketToClient 3"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   508
089413cdde3c 201028_02
hgs
parents:
diff changeset
   509
    FreeDrainedBuffers();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   510
089413cdde3c 201028_02
hgs
parents:
diff changeset
   511
    // Use this error code to complete client read request:
089413cdde3c 201028_02
hgs
parents:
diff changeset
   512
    return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   513
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   514
089413cdde3c 201028_02
hgs
parents:
diff changeset
   515
089413cdde3c 201028_02
hgs
parents:
diff changeset
   516
TInt TDmaBuf::RxCopyDataToClient(DThread* aThread, TClientBuffer *aTcb, TInt aLength, TUint32& aDestOffset,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   517
                                 TBool aRUS, TBool& aCompleteNow)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   518
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   519
    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxCopyDataToClient 1"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   520
    aCompleteNow = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   521
089413cdde3c 201028_02
hgs
parents:
diff changeset
   522
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   523
    const TInt numPkts = NoRxPackets();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   524
    const TInt numPktsAlt = NoRxPacketsAlt();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   525
    const TInt numBytes = RxBytesAvailable();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   526
    const TInt numBytesAlt = NoRxBytesAlt();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   527
089413cdde3c 201028_02
hgs
parents:
diff changeset
   528
    if (numPkts != numPktsAlt)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   529
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   530
        Kern::Printf(
089413cdde3c 201028_02
hgs
parents:
diff changeset
   531
            "TDmaBuf::RxCopyDataToClient: Error: #pkts mismatch global=%d actual=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   532
            numPkts, numPktsAlt);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   533
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   534
    if (numBytes != numBytesAlt)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   535
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   536
        Kern::Printf(
089413cdde3c 201028_02
hgs
parents:
diff changeset
   537
            "TDmaBuf::RxCopyDataToClient: Error: #bytes mismatch global=%d actual=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   538
            numBytes, numBytesAlt);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   539
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   540
    if ((numPkts == 0) && (numBytes != 0))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   541
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   542
        Kern::Printf(
089413cdde3c 201028_02
hgs
parents:
diff changeset
   543
            "TDmaBuf::RxCopyDataToClient: Error: global bytes & pkts mismatch pkts=%d bytes=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   544
            numPkts, numBytes);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   545
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   546
    if ((numPktsAlt == 0) && (numBytesAlt != 0))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   547
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   548
        Kern::Printf(
089413cdde3c 201028_02
hgs
parents:
diff changeset
   549
            "TDmaBuf::RxCopyDataToClient: Error: actual bytes & pkts mismatch pkts=%d bytes=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   550
            numPktsAlt, numBytesAlt);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   551
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   552
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   553
089413cdde3c 201028_02
hgs
parents:
diff changeset
   554
    if (!NoRxPackets())
089413cdde3c 201028_02
hgs
parents:
diff changeset
   555
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   556
        return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   557
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   558
089413cdde3c 201028_02
hgs
parents:
diff changeset
   559
    // coverity[var_tested_neg]
089413cdde3c 201028_02
hgs
parents:
diff changeset
   560
    if (iCurrentDrainingBufferIndex == KUsbcInvalidBufferIndex)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   561
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   562
        // Marked as Coverity "Inentional" as the member variable
089413cdde3c 201028_02
hgs
parents:
diff changeset
   563
        // iCurrentDrainingBufferIndex is attentionaly negative, from previous 
089413cdde3c 201028_02
hgs
parents:
diff changeset
   564
        // initialization to KUsbcInvalidBufferIndex (which equals -1).
089413cdde3c 201028_02
hgs
parents:
diff changeset
   565
089413cdde3c 201028_02
hgs
parents:
diff changeset
   566
        if (!NextDrainableBuffer())
089413cdde3c 201028_02
hgs
parents:
diff changeset
   567
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   568
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   569
            Kern::Printf("TDmaBuf::RxCopyDataToClient: Error:  No buffer draining=%d, packets=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   570
                         iCurrentDrainingBufferIndex, iTotalRxPacketsAvail);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   571
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   572
            return KErrNotFound;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   573
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   574
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   575
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   576
089413cdde3c 201028_02
hgs
parents:
diff changeset
   577
    __ASSERT_DEBUG((iCurrentDrainingBufferIndex >= 0 ),
089413cdde3c 201028_02
hgs
parents:
diff changeset
   578
                               Kern::Fault(KUsbPanicLdd, __LINE__));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   579
        
089413cdde3c 201028_02
hgs
parents:
diff changeset
   580
    if (iDrainingOrder != iFillingOrderArray[iCurrentDrainingBufferIndex])
089413cdde3c 201028_02
hgs
parents:
diff changeset
   581
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   582
        Kern::Printf("!!! Out of Order Draining TDmaBuf::RxCopyDataToClient 10 draining=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   583
                     iCurrentDrainingBufferIndex);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   584
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   585
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   586
    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxCopyDataToClient 2"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   587
089413cdde3c 201028_02
hgs
parents:
diff changeset
   588
    TUint8* blockStartAddr = iCurrentDrainingBuffer + iCurrentPacketIndexArray[iCurrentPacket] + iExtractOffset;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   589
    TUint8* lastEndAddr = blockStartAddr;                    // going to track the contiguity of the memory
089413cdde3c 201028_02
hgs
parents:
diff changeset
   590
    TUint8* thisStartAddr = blockStartAddr;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   591
    TInt toDo = Min(aLength - (TInt)aDestOffset, iTotalRxBytesAvail);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   592
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   593
    TInt bufnum = iCurrentDrainingBufferIndex;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   594
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   595
    TInt errorCode = KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   596
    TBool isShortPacket = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   597
    const TInt maxPacketSizeMask = iMaxPacketSize - 1;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   598
    do
089413cdde3c 201028_02
hgs
parents:
diff changeset
   599
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   600
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   601
        if (bufnum != iCurrentDrainingBufferIndex)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   602
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   603
            bufnum = iCurrentDrainingBufferIndex;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   604
            if (iDrainingOrder != iFillingOrderArray[iCurrentDrainingBufferIndex])
089413cdde3c 201028_02
hgs
parents:
diff changeset
   605
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   606
                Kern::Printf("!!! Out of Order Draining TDmaBuf::RxCopyDataToClient 20 draining=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   607
                             iCurrentDrainingBufferIndex);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   608
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   609
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   610
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   611
        if (errorCode == KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   612
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   613
            errorCode = GetCurrentError();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   614
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   615
        thisStartAddr = iCurrentDrainingBuffer + iCurrentPacketIndexArray[iCurrentPacket] + iExtractOffset;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   616
        const TInt thisPacketSize = iCurrentPacketSizeArray[iCurrentPacket];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   617
        const TInt size = thisPacketSize - iExtractOffset;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   618
        if (aRUS)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   619
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   620
            if (iEndpointType == UsbShai::KUsbEpTypeBulk)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   621
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   622
                isShortPacket = (size < iMaxPacketSize) || (size & maxPacketSizeMask);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   623
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   624
            else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   625
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   626
                // this 'if' block is arranged to avoid a division on packet sizes <= iMaxPacketSize
089413cdde3c 201028_02
hgs
parents:
diff changeset
   627
                isShortPacket = (size < iMaxPacketSize) ||
089413cdde3c 201028_02
hgs
parents:
diff changeset
   628
                    ((size > iMaxPacketSize) && (size % iMaxPacketSize));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   629
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   630
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   631
        TInt copySize = Min(size, toDo);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   632
        iExtractOffset += copySize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   633
        toDo -= copySize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   634
        if (thisStartAddr != lastEndAddr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   635
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   636
            TInt bytesToCopy = lastEndAddr - blockStartAddr;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   637
            TInt r=CopyToUser(aThread, blockStartAddr, bytesToCopy, aTcb, aDestOffset);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   638
            if(r != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   639
                Kern::ThreadKill(aThread, EExitPanic, r, KUsbLDDKillCat);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   640
            blockStartAddr = thisStartAddr;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   641
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   642
089413cdde3c 201028_02
hgs
parents:
diff changeset
   643
        ModifyTotalRxBytesAvail(-copySize);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   644
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   645
        iNumberofBytesRxRemain[iCurrentDrainingBufferIndex] -= copySize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   646
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   647
        lastEndAddr = thisStartAddr + copySize;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   648
        if (iExtractOffset == thisPacketSize)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   649
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   650
            // More data to copy, so need to access new packet
089413cdde3c 201028_02
hgs
parents:
diff changeset
   651
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   652
            iNumberofPacketsRxRemain[iCurrentDrainingBufferIndex] -= 1;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   653
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   654
            if (!AdvancePacket())
089413cdde3c 201028_02
hgs
parents:
diff changeset
   655
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   656
                break;                                        // no more packets left
089413cdde3c 201028_02
hgs
parents:
diff changeset
   657
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   658
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   659
        } while (toDo > 0 && !isShortPacket);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   660
089413cdde3c 201028_02
hgs
parents:
diff changeset
   661
    if (thisStartAddr != lastEndAddr)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   662
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   663
        TInt bytesToCopy = lastEndAddr - blockStartAddr;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   664
        TInt r=CopyToUser(aThread, blockStartAddr, bytesToCopy, aTcb, aDestOffset);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   665
        if(r != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   666
            Kern::ThreadKill(aThread, EExitPanic, r, KUsbLDDKillCat);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   667
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   668
089413cdde3c 201028_02
hgs
parents:
diff changeset
   669
    // If we have transferred the requested amount of data it is still possible that
089413cdde3c 201028_02
hgs
parents:
diff changeset
   670
    // the next packet is a zlp which needs to be bumped over
089413cdde3c 201028_02
hgs
parents:
diff changeset
   671
089413cdde3c 201028_02
hgs
parents:
diff changeset
   672
    if (aRUS && (toDo == 0) && (iExtractOffset == 0) && (!isShortPacket) && (!IsReaderEmpty()) &&
089413cdde3c 201028_02
hgs
parents:
diff changeset
   673
        (PeekNextPacketSize() == 0))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   674
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   675
        // swallow a zlp
089413cdde3c 201028_02
hgs
parents:
diff changeset
   676
        isShortPacket = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   677
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   678
        iNumberofPacketsRxRemain[iCurrentDrainingBufferIndex] -= 1;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   679
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   680
        AdvancePacket();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   681
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   682
    aCompleteNow = isShortPacket || (((TInt)aDestOffset) == aLength) || (errorCode != KErrNone);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   683
089413cdde3c 201028_02
hgs
parents:
diff changeset
   684
    FreeDrainedBuffers();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   685
089413cdde3c 201028_02
hgs
parents:
diff changeset
   686
    // Use this error code to complete client read request
089413cdde3c 201028_02
hgs
parents:
diff changeset
   687
    return errorCode;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   688
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   689
089413cdde3c 201028_02
hgs
parents:
diff changeset
   690
089413cdde3c 201028_02
hgs
parents:
diff changeset
   691
inline TInt TDmaBuf::CopyToUser(DThread* aThread, const TUint8* aSourceAddr,
089413cdde3c 201028_02
hgs
parents:
diff changeset
   692
                                TInt aLength, TClientBuffer *aTcb, TUint32& aDestOffset)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   693
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   694
    TPtrC8 des(aSourceAddr, aLength);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   695
    TInt errorCode = Kern::ThreadBufWrite(aThread, aTcb, des, aDestOffset, KChunkShiftBy0, aThread);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   696
    if (errorCode == KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   697
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   698
        aDestOffset += aLength;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   699
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   700
    return errorCode;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   701
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   702
089413cdde3c 201028_02
hgs
parents:
diff changeset
   703
089413cdde3c 201028_02
hgs
parents:
diff changeset
   704
inline TInt TDmaBuf::NoRxPackets() const
089413cdde3c 201028_02
hgs
parents:
diff changeset
   705
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   706
    return iTotalRxPacketsAvail;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   707
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   708
089413cdde3c 201028_02
hgs
parents:
diff changeset
   709
089413cdde3c 201028_02
hgs
parents:
diff changeset
   710
inline void TDmaBuf::IncrementBufferIndex(TInt& aIndex)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   711
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   712
    if (++aIndex == iNumberofBuffers)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   713
        aIndex = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   714
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   715
089413cdde3c 201028_02
hgs
parents:
diff changeset
   716
089413cdde3c 201028_02
hgs
parents:
diff changeset
   717
TBool TDmaBuf::NextDrainableBuffer()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   718
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   719
    TBool r = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   720
    if (iCurrentDrainingBufferIndex != KUsbcInvalidBufferIndex)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   721
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   722
        iCanBeFreed[iCurrentDrainingBufferIndex] = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   723
        iNumberofPacketsRx[iCurrentDrainingBufferIndex] = 0; // Current buffer is empty
089413cdde3c 201028_02
hgs
parents:
diff changeset
   724
        iNumberofBytesRx[iCurrentDrainingBufferIndex] = 0;    // Current buffer is empty
089413cdde3c 201028_02
hgs
parents:
diff changeset
   725
089413cdde3c 201028_02
hgs
parents:
diff changeset
   726
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   727
        TUint& bytesRemain = iNumberofBytesRxRemain[iCurrentDrainingBufferIndex];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   728
        TUint& pktsRemain = iNumberofPacketsRxRemain[iCurrentDrainingBufferIndex];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   729
        if ((bytesRemain != 0) || (pktsRemain != 0))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   730
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   731
            Kern::Printf(
089413cdde3c 201028_02
hgs
parents:
diff changeset
   732
                "TDmaBuf::NextDrainableBuffer: Error: data discarded buffer=%d pkts=%d bytes=%d",
089413cdde3c 201028_02
hgs
parents:
diff changeset
   733
                iCurrentDrainingBufferIndex, pktsRemain, bytesRemain);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   734
            bytesRemain = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   735
            pktsRemain = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   736
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   737
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   738
089413cdde3c 201028_02
hgs
parents:
diff changeset
   739
        iCurrentDrainingBufferIndex = KUsbcInvalidBufferIndex;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   740
        iCurrentPacket = KUsbcInvalidPacketIndex;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   741
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   742
089413cdde3c 201028_02
hgs
parents:
diff changeset
   743
    if (iDrainQueueIndex != KUsbcInvalidDrainQueueIndex)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   744
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   745
        r = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   746
        const TInt index = iDrainQueue[0];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   747
        iDrainQueueIndex--;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   748
        for (TInt i = 0; i < iNumberofBuffers; i++)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   749
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   750
            iDrainQueue[i] = iDrainQueue[i+1];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   751
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   752
089413cdde3c 201028_02
hgs
parents:
diff changeset
   753
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   754
        if (index != KUsbcInvalidBufferIndex)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   755
            iDrainingOrder++;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   756
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   757
089413cdde3c 201028_02
hgs
parents:
diff changeset
   758
        iCurrentDrainingBufferIndex = index;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   759
        iCurrentDrainingBuffer = iBuffers[index];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   760
        iCurrentPacketIndexArray = iPacketIndex[index];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   761
        iCurrentPacketSizeArray = iPacketSize[index];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   762
        iCurrentPacket = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   763
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   764
    return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   765
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   766
089413cdde3c 201028_02
hgs
parents:
diff changeset
   767
089413cdde3c 201028_02
hgs
parents:
diff changeset
   768
TInt TDmaBuf::PeekNextDrainableBuffer()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   769
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   770
    TInt r = KUsbcInvalidBufferIndex;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   771
    if (iDrainQueueIndex != KUsbcInvalidDrainQueueIndex)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   772
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   773
        r = iDrainQueue[0];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   774
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   775
    return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   776
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   777
089413cdde3c 201028_02
hgs
parents:
diff changeset
   778
089413cdde3c 201028_02
hgs
parents:
diff changeset
   779
TBool TDmaBuf::NextFillableBuffer()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   780
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   781
    TBool r = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   782
    TInt index = iCurrentFillingBufferIndex;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   783
    IncrementBufferIndex(index);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   784
    // the sequence will restart at 0 if a buffer can't be found this time
089413cdde3c 201028_02
hgs
parents:
diff changeset
   785
    iCurrentFillingBufferIndex = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   786
    for (TInt i = 0; i < iNumberofBuffers; i++)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   787
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   788
        if (!iDrainable[index])
089413cdde3c 201028_02
hgs
parents:
diff changeset
   789
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   790
            iCurrentFillingBufferIndex = index;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   791
            r = ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   792
            break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   793
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   794
        IncrementBufferIndex(index);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   795
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   796
    return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   797
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   798
089413cdde3c 201028_02
hgs
parents:
diff changeset
   799
089413cdde3c 201028_02
hgs
parents:
diff changeset
   800
void TDmaBuf::FreeDrainedBuffers()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   801
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   802
    for (TInt i = 0; i < iNumberofBuffers; i++)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   803
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   804
        if (iDrainable[i] && iCanBeFreed[i])
089413cdde3c 201028_02
hgs
parents:
diff changeset
   805
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   806
            iDrainable[i] = iCanBeFreed[i] = EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   807
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   808
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   809
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   810
089413cdde3c 201028_02
hgs
parents:
diff changeset
   811
089413cdde3c 201028_02
hgs
parents:
diff changeset
   812
TBool TDmaBuf::ShortPacketExists()
089413cdde3c 201028_02
hgs
parents:
diff changeset
   813
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   814
    // Actually, a short packet or residue data
089413cdde3c 201028_02
hgs
parents:
diff changeset
   815
    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::ShortPacketExists 1"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   816
    TInt index = iCurrentDrainingBufferIndex;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   817
    TUsbcPacketArray* pktSizeArray = iCurrentPacketSizeArray;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   818
089413cdde3c 201028_02
hgs
parents:
diff changeset
   819
    if (iMaxPacketSize > 0)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   820
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   821
        // No buffers available for draining
089413cdde3c 201028_02
hgs
parents:
diff changeset
   822
        if ((iCurrentDrainingBufferIndex == KUsbcInvalidBufferIndex) ||
089413cdde3c 201028_02
hgs
parents:
diff changeset
   823
            (iCurrentPacket == KUsbcInvalidPacketIndex))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   824
            return EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   825
089413cdde3c 201028_02
hgs
parents:
diff changeset
   826
        // Zlp waiting at tail
089413cdde3c 201028_02
hgs
parents:
diff changeset
   827
        if ((iTotalRxBytesAvail == 0) && (NoRxPackets() == 1))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   828
            return ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   829
089413cdde3c 201028_02
hgs
parents:
diff changeset
   830
        if (iEndpointType == UsbShai::KUsbEpTypeBulk)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   831
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   832
            const TInt mask = iMaxPacketSize - 1;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   833
            if (iTotalRxBytesAvail & mask)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   834
                return ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   835
089413cdde3c 201028_02
hgs
parents:
diff changeset
   836
            // residue==0; this can be because
089413cdde3c 201028_02
hgs
parents:
diff changeset
   837
            // zlps exist, or short packets combine to n * max_packet_size
089413cdde3c 201028_02
hgs
parents:
diff changeset
   838
            // This means spadework
089413cdde3c 201028_02
hgs
parents:
diff changeset
   839
            const TInt s = iCurrentPacketSizeArray[iCurrentPacket] - iExtractOffset;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   840
            if ((s == 0) || (s & mask))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   841
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   842
                return ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   843
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   844
089413cdde3c 201028_02
hgs
parents:
diff changeset
   845
            for (TInt i = 0; i < iNumberofBuffers; i++)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   846
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   847
                if (index == KUsbcInvalidBufferIndex)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   848
                    break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   849
                if (iDrainable[index])
089413cdde3c 201028_02
hgs
parents:
diff changeset
   850
                    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   851
                    const TInt packetCount = iNumberofPacketsRx[index];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   852
                    const TInt lastPacketSize=pktSizeArray[packetCount - 1];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   853
                    if ((lastPacketSize < iMaxPacketSize) || (lastPacketSize & mask))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   854
                        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   855
                        return ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   856
                        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   857
                    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   858
                index = iDrainQueue[i];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   859
                pktSizeArray = iPacketSize[index];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   860
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   861
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   862
        else
089413cdde3c 201028_02
hgs
parents:
diff changeset
   863
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   864
            if (iTotalRxBytesAvail % iMaxPacketSize)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   865
                return ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   866
089413cdde3c 201028_02
hgs
parents:
diff changeset
   867
            // residue==0; this can be because
089413cdde3c 201028_02
hgs
parents:
diff changeset
   868
            // zlps exist, or short packets combine to n * max_packet_size
089413cdde3c 201028_02
hgs
parents:
diff changeset
   869
            // This means spadework
089413cdde3c 201028_02
hgs
parents:
diff changeset
   870
            const TInt s = iCurrentPacketSizeArray[iCurrentPacket] - iExtractOffset;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   871
            if ((s == 0) || (s % iMaxPacketSize))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   872
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   873
                return ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   874
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   875
089413cdde3c 201028_02
hgs
parents:
diff changeset
   876
            for (TInt i = 0; i < iNumberofBuffers; i++)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   877
                {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   878
                if (index == KUsbcInvalidBufferIndex)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   879
                    break;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   880
                if (iDrainable[index])
089413cdde3c 201028_02
hgs
parents:
diff changeset
   881
                    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   882
                    const TInt packetCount = iNumberofPacketsRx[index];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   883
                    const TInt lastPacketSize = pktSizeArray[packetCount - 1];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   884
                    if ((lastPacketSize < iMaxPacketSize) || (lastPacketSize % iMaxPacketSize))
089413cdde3c 201028_02
hgs
parents:
diff changeset
   885
                        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   886
                        return ETrue;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   887
                        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   888
                    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   889
                index = iDrainQueue[i];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   890
                pktSizeArray = iPacketSize[index];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   891
                }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   892
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   893
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   894
089413cdde3c 201028_02
hgs
parents:
diff changeset
   895
    return EFalse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   896
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   897
089413cdde3c 201028_02
hgs
parents:
diff changeset
   898
089413cdde3c 201028_02
hgs
parents:
diff changeset
   899
void TDmaBuf::AddToDrainQueue(TInt aBufferIndex)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   900
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   901
    if (iDrainQueue[iDrainQueueIndex + 1] != KUsbcInvalidBufferIndex)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   902
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   903
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   904
        Kern::Printf("TDmaBuf::AddToDrainQueue: Error: invalid iDrainQueue[x]");
089413cdde3c 201028_02
hgs
parents:
diff changeset
   905
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   906
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   907
    iDrainQueue[++iDrainQueueIndex] = aBufferIndex;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   908
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   909
089413cdde3c 201028_02
hgs
parents:
diff changeset
   910
089413cdde3c 201028_02
hgs
parents:
diff changeset
   911
#if defined(USBC_LDD_BUFFER_TRACE)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   912
TInt TDmaBuf::NoRxPacketsAlt() const
089413cdde3c 201028_02
hgs
parents:
diff changeset
   913
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   914
    TInt pktCount = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   915
    for(TInt i = 0; i < iNumberofBuffers; i++)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   916
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   917
        if (iDrainable[i])
089413cdde3c 201028_02
hgs
parents:
diff changeset
   918
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   919
            pktCount += iNumberofPacketsRxRemain[i];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   920
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   921
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   922
    return pktCount;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   923
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   924
089413cdde3c 201028_02
hgs
parents:
diff changeset
   925
089413cdde3c 201028_02
hgs
parents:
diff changeset
   926
TInt TDmaBuf::NoRxBytesAlt() const
089413cdde3c 201028_02
hgs
parents:
diff changeset
   927
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   928
    TInt byteCount = 0;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   929
    for(TInt i = 0; i < iNumberofBuffers; i++)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   930
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   931
        if (iDrainable[i])
089413cdde3c 201028_02
hgs
parents:
diff changeset
   932
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   933
            byteCount += iNumberofBytesRxRemain[i];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   934
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   935
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   936
    return byteCount;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   937
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   938
#endif
089413cdde3c 201028_02
hgs
parents:
diff changeset
   939
089413cdde3c 201028_02
hgs
parents:
diff changeset
   940
089413cdde3c 201028_02
hgs
parents:
diff changeset
   941
// We only store 1 transaction, no other buffering is done
089413cdde3c 201028_02
hgs
parents:
diff changeset
   942
TInt TDmaBuf::TxStoreData(DThread* aThread, TClientBuffer *aTcb, TInt aTxLength, TUint32 aBufferOffset)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   943
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   944
    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::TxStoreData 1"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   945
    if (!IsReaderEmpty())
089413cdde3c 201028_02
hgs
parents:
diff changeset
   946
        return KErrInUse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   947
089413cdde3c 201028_02
hgs
parents:
diff changeset
   948
    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::TxStoreData 2"));
089413cdde3c 201028_02
hgs
parents:
diff changeset
   949
    
089413cdde3c 201028_02
hgs
parents:
diff changeset
   950
    TInt remainTxLength = aTxLength;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   951
    TUint32 bufferOffset = aBufferOffset;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   952
    // Store each buffer separately
089413cdde3c 201028_02
hgs
parents:
diff changeset
   953
    for( TInt i=0;(i<iNumberofBuffers)&&(remainTxLength>0);i++)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   954
        {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   955
        TUint8* logicalDest = iBuffers[i];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   956
        TInt xferSz = Min(remainTxLength, iBufSz);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   957
        TPtr8 des(logicalDest, xferSz, xferSz);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   958
        TInt r = Kern::ThreadBufRead(aThread, aTcb, des, bufferOffset, KChunkShiftBy0);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   959
        if(r != KErrNone)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   960
            {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   961
            Kern::ThreadKill(aThread, EExitPanic, r, KUsbLDDKillCat);
089413cdde3c 201028_02
hgs
parents:
diff changeset
   962
            return r;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   963
            }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   964
        remainTxLength -= iBufSz;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   965
        bufferOffset += iBufSz;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   966
        }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   967
089413cdde3c 201028_02
hgs
parents:
diff changeset
   968
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   969
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   970
089413cdde3c 201028_02
hgs
parents:
diff changeset
   971
089413cdde3c 201028_02
hgs
parents:
diff changeset
   972
TInt TDmaBuf::TxGetNextXfer(TUint8*& aBufferAddr, TInt& aTxLength, TPhysAddr& aBufferPhys)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   973
    {
089413cdde3c 201028_02
hgs
parents:
diff changeset
   974
    if (iTxActive)
089413cdde3c 201028_02
hgs
parents:
diff changeset
   975
        return KErrInUse;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   976
089413cdde3c 201028_02
hgs
parents:
diff changeset
   977
    aBufferAddr = iBuffers[0];                                // only 1 tx buffer
089413cdde3c 201028_02
hgs
parents:
diff changeset
   978
    aBufferPhys = iBufferPhys[0];
089413cdde3c 201028_02
hgs
parents:
diff changeset
   979
    aTxLength = BufferTotalSize();
089413cdde3c 201028_02
hgs
parents:
diff changeset
   980
089413cdde3c 201028_02
hgs
parents:
diff changeset
   981
    return KErrNone;
089413cdde3c 201028_02
hgs
parents:
diff changeset
   982
    }
089413cdde3c 201028_02
hgs
parents:
diff changeset
   983