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