usbdrv/peripheral/ldd/perildd/src/usbdma.cpp
branchRCL_3
changeset 16 012cc2ee6408
parent 15 f92a4f87e424
--- a/usbdrv/peripheral/ldd/perildd/src/usbdma.cpp	Tue Aug 31 17:01:47 2010 +0300
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,983 +0,0 @@
-// Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
-// All rights reserved.
-// This component and the accompanying materials are made available
-// under the terms of the License "Eclipse Public License v1.0"
-// which accompanies this distribution, and is available
-// at the URL "http://www.eclipse.org/legal/epl-v10.html".
-//
-// Initial Contributors:
-// Nokia Corporation - initial contribution.
-//
-// Contributors:
-//
-// Description:
-// e32\drivers\usbc\usbdma.cpp
-// LDD for USB Device driver stack:
-// Management of DMA-capable data buffers.
-// 
-//
-
-/**
- @file usbdma.cpp
- @internalTechnology
-*/
-
-#include <usb/usbc.h>
-
-
-#if defined(_DEBUG)
-static const char KUsbPanicLdd[] = "USB LDD";
-#endif
-
-
-TDmaBuf::TDmaBuf(TUsbcEndpointInfo* aEndpointInfo, TInt aBandwidthPriority)
-    : iBufBasePtr(NULL),
-      iCurrentDrainingBuffer(NULL),
-      iCurrentPacket(0),
-      iCurrentPacketIndexArray(NULL),
-      iCurrentPacketSizeArray(NULL)
-    {
-    iMaxPacketSize = aEndpointInfo->iSize;
-    iEndpointType = aEndpointInfo->iType;
-
-    switch (aEndpointInfo->iType)
-        {
-    case UsbShai::KUsbEpTypeControl:
-        iBufSz = KUsbcDmaBufSzControl;
-        iNumberofBuffers = KUsbcDmaBufNumControl;
-        break;
-    case UsbShai::KUsbEpTypeIsochronous:
-        iBufSz = KUsbcDmaBufSzIsochronous;
-        iNumberofBuffers = KUsbcDmaBufNumIsochronous;
-        break;
-    case UsbShai::KUsbEpTypeBulk:
-        {
-        if (aEndpointInfo->iDir == UsbShai::KUsbEpDirOut)
-            {
-            const TInt priorityOUT = aBandwidthPriority & 0x0f;
-            iBufSz = KUsbcDmaBufSizesBulkOUT[priorityOUT];
-            }
-        else
-            {
-            const TInt priorityIN = (aBandwidthPriority >> 4) & 0x0f;
-            iBufSz = KUsbcDmaBufSizesBulkIN[priorityIN];
-            }
-        iNumberofBuffers = KUsbcDmaBufNumBulk;
-        }
-        break;
-    case UsbShai::KUsbEpTypeInterrupt:
-        iBufSz = KUsbcDmaBufSzInterrupt;
-        iNumberofBuffers = KUsbcDmaBufNumInterrupt;
-        break;
-    default:
-        iBufSz = 0;
-        iNumberofBuffers = 0;
-        }
-
-    if (aEndpointInfo->iDir == UsbShai::KUsbEpDirIn)
-        {
-        iNumberofBuffers = 1;                                // IN endpoints only have 1 buffer
-        }
-
-    for (TInt i = 0; i < KUsbcDmaBufNumMax; i++)
-        {
-        // Buffer logical addresses (pointers)
-        iBuffers[i] = NULL;
-        // Buffer physical addresses
-        iBufferPhys[i] = 0;
-        // Packet indexes base array
-        iPacketIndex[i] = NULL;
-        // Packet sizes base array
-        iPacketSize[i] = NULL;
-        }
-    }
-
-
-TInt TDmaBuf::Construct(TUsbcEndpointInfo* aEndpointInfo)
-    {
-    if (aEndpointInfo->iDir != UsbShai::KUsbEpDirIn)
-        {
-        // IN endpoints don't need a packet array
-
-        // At most 2 packets (clump of max packet size packets) + possible zlp
-        TUsbcPacketArray* bufPtr = iPacketInfoStorage;
-        // this divides up the packet indexing & packet size array over the number of buffers
-        __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::Construct() array base=0x%08x", bufPtr));
-        for (TInt i = 0; i < iNumberofBuffers; i++)
-            {
-            iPacketIndex[i] = bufPtr;
-            bufPtr += KUsbcDmaBufMaxPkts;
-            iPacketSize[i] = bufPtr;
-            bufPtr += KUsbcDmaBufMaxPkts;
-            __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::Construct() packetIndex[%d]=0x%08x packetSize[%d]=0x%08x",
-                                            i, iPacketIndex[i], i, iPacketSize[i]));
-            }
-        }
-    else
-        {
-        __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::Construct() IN endpoint"));
-        }
-    Flush();
-    return KErrNone;
-    }
-
-
-TDmaBuf::~TDmaBuf()
-    {
-    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::~TDmaBuf()"));
-    }
-
-TInt TDmaBuf::BufferTotalSize() const
-    {
-    return iBufSz * iNumberofBuffers;
-    }
-
-TInt TDmaBuf::BufferSize() const
-    {
-    return iBufSz;
-    }
-
-TInt TDmaBuf::SetBufferAddr(TInt aBufInd, TUint8* aBufAddr)
-    {
-    __ASSERT_DEBUG((aBufInd < iNumberofBuffers),
-                       Kern::Fault(KUsbPanicLdd, __LINE__));
-    iDrainable[aBufInd] = iCanBeFreed[aBufInd] = EFalse;
-    iBuffers[aBufInd] = aBufAddr;
-    iBufferPhys[aBufInd] = Epoc::LinearToPhysical((TLinAddr)aBufAddr);
-    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::SetBufferAddr() iBuffers[%d]=0x%08x", aBufInd, iBuffers[aBufInd]));
-    return KErrNone;
-    }
-
-TInt TDmaBuf::BufferNumber() const
-    {
-    return iNumberofBuffers;
-    }
-
-void TDmaBuf::SetMaxPacketSize(TInt aSize)
-    {
-    iMaxPacketSize = aSize;
-    }
-
-
-void TDmaBuf::Flush()
-    {
-    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::Flush %x", this));
-    iRxActive = EFalse;
-    iTxActive = EFalse;
-    iExtractOffset = 0;
-    iTotalRxBytesAvail = 0;
-    iTotalRxPacketsAvail = 0;
-    iCurrentDrainingBufferIndex = KUsbcInvalidBufferIndex;
-    iCurrentFillingBufferIndex = 0;
-    iDrainQueueIndex = KUsbcInvalidDrainQueueIndex;
-    for (TInt i = 0; i < KUsbcDmaBufNumMax; i++)
-        {
-        iDrainable[i] = EFalse;
-        iCanBeFreed[i] = EFalse;
-        iNumberofBytesRx[i] = 0;
-        iNumberofPacketsRx[i] = 0;
-        iError[i] = KErrGeneral;
-        iDrainQueue[i] = KUsbcInvalidBufferIndex;
-#if defined(USBC_LDD_BUFFER_TRACE)
-        iFillingOrderArray[i] = 0;
-        iNumberofBytesRxRemain[i] = 0;
-        iNumberofPacketsRxRemain[i] = 0;
-#endif
-        }
-    // Drain queue is 1 oversized
-    iDrainQueue[KUsbcDmaBufNumMax] = KUsbcInvalidBufferIndex;
-
-#if defined(USBC_LDD_BUFFER_TRACE)
-    iFillingOrder = 0;
-    iDrainingOrder = 0;
-#endif
-    }
-
-
-void TDmaBuf::RxSetActive()
-    {
-    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxSetActive %x", this));
-    iRxActive = ETrue;
-    }
-
-
-void TDmaBuf::RxSetInActive()
-    {
-    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxSetInActive %x", this));
-    iRxActive = EFalse;
-    }
-
-
-TBool TDmaBuf::RxIsActive()
-    {
-    return iRxActive;
-    }
-
-
-void TDmaBuf::TxSetActive()
-    {
-    iTxActive = ETrue;
-    }
-
-
-void TDmaBuf::TxSetInActive()
-    {
-    iTxActive = EFalse;
-    }
-
-
-TBool TDmaBuf::TxIsActive()
-    {
-    return iTxActive;
-    }
-
-
-/**************************** Rx DMA Buffer Access *************************/
-
-void TDmaBuf::ModifyTotalRxBytesAvail(TInt aVal)
-    {
-    iTotalRxBytesAvail += aVal;
-    }
-
-
-void TDmaBuf::ModifyTotalRxPacketsAvail(TInt aVal)
-    {
-    iTotalRxPacketsAvail += aVal;
-    }
-
-
-TBool TDmaBuf::AdvancePacket()
-    {
-    ModifyTotalRxPacketsAvail(-1);
-    TBool r = ETrue;
-    __ASSERT_DEBUG((iCurrentDrainingBufferIndex >= 0),
-                       Kern::Fault(KUsbPanicLdd, __LINE__));
-    if (++iCurrentPacket >= iNumberofPacketsRx[iCurrentDrainingBufferIndex])
-        {
-        r = NextDrainableBuffer();
-        }
-    iExtractOffset = 0;
-    __ASSERT_DEBUG((iCurrentDrainingBufferIndex == KUsbcInvalidBufferIndex) ||
-                   (iCurrentPacket < KUsbcDmaBufMaxPkts),
-                   Kern::Fault(KUsbPanicLdd, __LINE__));
-    return r;
-    }
-
-
-TInt TDmaBuf::PeekNextPacketSize()
-    {
-    TUint pkt = iCurrentPacket;
-    TInt index = iCurrentDrainingBufferIndex;
-    TInt size = -1;
-    if (pkt >= iNumberofPacketsRx[index])
-        {
-        index = PeekNextDrainableBuffer();
-        pkt = 0;
-        }
-
-    if ((index != KUsbcInvalidBufferIndex) && iNumberofPacketsRx[index])
-        {
-        const TUsbcPacketArray* sizeArray = iPacketSize[index];
-        size = (TInt)sizeArray[pkt];
-        }
-
-    __ASSERT_DEBUG((iCurrentDrainingBufferIndex == KUsbcInvalidBufferIndex) ||
-                   (iCurrentPacket < KUsbcDmaBufMaxPkts),
-                   Kern::Fault(KUsbPanicLdd, __LINE__));
-    return size;
-    }
-
-
-inline TInt TDmaBuf::GetCurrentError()
-    {
-    // USB bus errors are v.rare. To avoid having an error code attached to every packet since
-    // almost every errorcode will be KErrNone, we have a single error code per buffer
-    // If the error code is != KErrNone then it refers to the LAST packet in the buffer
-    TInt errorCode = KErrNone;
-    //Check the index, it's not equal to negative (-1) value defined in 
-    //KUsbcInvalidBufferIndex.
-    __ASSERT_DEBUG((iCurrentDrainingBufferIndex >= 0),
-                       Kern::Fault(KUsbPanicLdd, __LINE__));
-    
-    if (iError[iCurrentDrainingBufferIndex] != KErrNone)
-        {
-        // See if we are at the last packet
-        if ((iCurrentPacket + 1) == iNumberofPacketsRx[iCurrentDrainingBufferIndex])
-            {
-            errorCode = iError[iCurrentDrainingBufferIndex];
-            }
-        }
-    return errorCode;
-    }
-
-
-// used to decide whether a client read can complete straight away
-TBool TDmaBuf::IsReaderEmpty()
-    {
-    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::IsReaderEmpty iTotalRxPacketsAvail=%d",
-                                    iTotalRxPacketsAvail));
-    return (iTotalRxPacketsAvail == 0);
-    }
-
-
-void TDmaBuf::ReadXferComplete(TInt aNoBytesRecv, TInt aNoPacketsRecv, TInt aErrorCode)
-    {
-    // Adjust pending packet
-    if ((aNoBytesRecv == 0) && (aErrorCode != KErrNone))
-        {
-        // Make the buffer available for reuse
-        iDrainable[iCurrentFillingBufferIndex] = EFalse;
-        return;
-        }
-
-    ModifyTotalRxBytesAvail(aNoBytesRecv);
-    ModifyTotalRxPacketsAvail(aNoPacketsRecv);
-    iNumberofBytesRx[iCurrentFillingBufferIndex] = aNoBytesRecv;
-    iNumberofPacketsRx[iCurrentFillingBufferIndex] = aNoPacketsRecv;
-
-#if defined(USBC_LDD_BUFFER_TRACE)
-    iNumberofBytesRxRemain[iCurrentFillingBufferIndex] = aNoBytesRecv;
-    iNumberofPacketsRxRemain[iCurrentFillingBufferIndex] = aNoPacketsRecv;
-#endif
-
-    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::ReadXferComplete 2 # of bytes=%d # of packets=%d",
-                                    iTotalRxBytesAvail, iTotalRxPacketsAvail));
-    iDrainable[iCurrentFillingBufferIndex] = ETrue;
-    iError[iCurrentFillingBufferIndex] = aErrorCode;
-    AddToDrainQueue(iCurrentFillingBufferIndex);
-    if (iCurrentDrainingBufferIndex == KUsbcInvalidBufferIndex)
-        {
-        NextDrainableBuffer();
-        }
-    }
-
-
-TInt TDmaBuf::RxGetNextXfer(TUint8*& aBufferAddr, TUsbcPacketArray*& aIndexArray,
-                            TUsbcPacketArray*& aSizeArray, TInt& aLength, TPhysAddr& aBufferPhys)
-    {
-    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxGetNextXfer 1"));
-    if (RxIsActive())
-        {
-        __KTRACE_OPT(KUSB, Kern::Printf(" ---> RxIsActive, returning"));
-        return KErrInUse;
-        }
-
-    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxGetNextXfer Current buffer=%d",
-                                    iCurrentFillingBufferIndex));
-    if (iDrainable[iCurrentFillingBufferIndex])
-        {
-        // If the controller refused the last read request, then the current buffer will still be marked
-        // as !Drainable, because the controller never completed the read to the ldd. and therefore the buffer
-        // can be reused.
-        if (!NextFillableBuffer())
-            {
-            return KErrNoMemory;
-            }
-        }
-
-    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxGetNextXfer New buffer=%d",
-                                    iCurrentFillingBufferIndex));
-    aBufferAddr = iBuffers[iCurrentFillingBufferIndex];
-    aBufferPhys = iBufferPhys[iCurrentFillingBufferIndex];
-    aIndexArray = iPacketIndex[iCurrentFillingBufferIndex];
-    aSizeArray = iPacketSize[iCurrentFillingBufferIndex];
-    aLength = iBufSz;
-
-#if defined(USBC_LDD_BUFFER_TRACE)
-    iFillingOrderArray[iCurrentFillingBufferIndex] = ++iFillingOrder;
-#endif
-
-    return KErrNone;
-    }
-
-
-TInt TDmaBuf::RxCopyPacketToClient(DThread* aThread, TClientBuffer *aTcb, TInt aLength)
-    {
-    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxCopyPacketToClient 1"));
-
-#if defined(USBC_LDD_BUFFER_TRACE)
-    const TInt numPkts = NoRxPackets();
-    const TInt numPktsAlt = NoRxPacketsAlt();
-    const TInt numBytes = RxBytesAvailable();
-    const TInt numBytesAlt = NoRxBytesAlt();
-
-    if (numPkts != numPktsAlt)
-        {
-        Kern::Printf(
-            "TDmaBuf::RxCopyPacketToClient: Error: #pkts mismatch global=%d actual=%d",
-            numPkts, numPktsAlt);
-        }
-    if (numBytes != numBytesAlt)
-        {
-        Kern::Printf(
-            "TDmaBuf::RxCopyPacketToClient: Error: #bytes mismatch global=%d actual=%d",
-            numBytes, numBytesAlt);
-        }
-    if ((numPkts == 0) && (numBytes !=0))
-        {
-        Kern::Printf(
-            "TDmaBuf::RxCopyPacketToClient: Error: global bytes & pkts mismatch pkts=%d bytes=%d",
-            numPkts, numBytes);
-        }
-    if ((numPktsAlt == 0) && (numBytesAlt !=0))
-        {
-        Kern::Printf(
-            "TDmaBuf::RxCopyPacketToClient: Error: actual bytes & pkts mismatch pkts=%d bytes=%d",
-            numPktsAlt, numBytesAlt);
-        }
-#endif
-
-    if (!NoRxPackets())
-        return KErrNotFound;
-
-    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxCopyPacketToClient 2"));
-    // the next condition should be true because we have some packets available
-    // coverity[var_tested_neg]
-    if (iCurrentDrainingBufferIndex == KUsbcInvalidBufferIndex)
-        {
-        // Marked as Coverity "Intentional" as the member variable
-        // iCurrentDrainingBufferIndex is attentionaly negative, from previous 
-        // initialization to KUsbcInvalidBufferIndex (which equals -1).
-        if (!NextDrainableBuffer())
-            return KErrNotFound;
-        }
-
-    __ASSERT_DEBUG((iCurrentDrainingBufferIndex >= 0 ),
-                           Kern::Fault(KUsbPanicLdd, __LINE__));
-    
-    if (!iDrainable[iCurrentDrainingBufferIndex])
-        return KErrNotFound;
-
-    // Calculate copy-from address & adjust for the fact that
-    // some data may have already been read from the packet
-    TUint8* logicalSrc = iCurrentDrainingBuffer + iCurrentPacketIndexArray[iCurrentPacket] + iExtractOffset;
-    TInt packetSz = iCurrentPacketSizeArray[iCurrentPacket];
-    TInt thisPacketSz = packetSz - iExtractOffset;
-    TInt errorCode;
-    // try and sort out what a "packet" might mean.
-    // in a multi-packet dma environment, we might see super-packets
-    // i.e. we might just see one packet, maybe 4K or so long, made of lots of small packets
-    // Since we don't know where the packet boundaries will be, we have to assume that
-    // any 'packet' larger than the max packet size of the ep is, in fact, a conglomeration
-    // of smaller packets. However, for the purposes of the packet count, this is still regarded
-    // as a single packet and the packet count only decremented when it is consumed.
-    // As before, if the user fails to read an entire packet out then the next packet is moved onto anyway
-    // To be safe the user must always supply a buffer of at least max packet size bytes.
-    if (thisPacketSz > iMaxPacketSize)
-        {
-        // Multiple packets left in buffer
-        // calculate number of bytes to end of packet
-        if (iEndpointType == UsbShai::KUsbEpTypeBulk)
-            {
-            thisPacketSz = iMaxPacketSize - (iExtractOffset & (iMaxPacketSize - 1));
-            }
-        else
-            {
-            thisPacketSz = iMaxPacketSize - (iExtractOffset % iMaxPacketSize);
-            }
-        errorCode = KErrNone;
-        }
-    else
-        {
-        errorCode = GetCurrentError();                        // single packet left
-        }
-
-    iExtractOffset += thisPacketSz;            // iExtractOffset is now at the end of the real or notional packet
-
-    ModifyTotalRxBytesAvail(-thisPacketSz);
-#if defined(USBC_LDD_BUFFER_TRACE)
-    iNumberofBytesRxRemain[iCurrentDrainingBufferIndex] -= thisPacketSz;
-#endif
-    // this can only be untrue if the "packet" is a conglomeration of smaller packets:
-    if (iExtractOffset == packetSz)
-        {
-        // packet consumed, advance to next packet in buffer
-#if defined(USBC_LDD_BUFFER_TRACE)
-        iNumberofPacketsRxRemain[iCurrentDrainingBufferIndex] -= 1;
-#endif
-        AdvancePacket();
-        }
-
-    TPtrC8 des(logicalSrc, thisPacketSz);
-    TInt r=Kern::ThreadBufWrite(aThread, aTcb, des, 0, 0, aThread);
-    if (r == KErrNone)
-        {
-        r = errorCode;
-        }
-    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxCopyPacketToClient 3"));
-
-    FreeDrainedBuffers();
-
-    // Use this error code to complete client read request:
-    return r;
-    }
-
-
-TInt TDmaBuf::RxCopyDataToClient(DThread* aThread, TClientBuffer *aTcb, TInt aLength, TUint32& aDestOffset,
-                                 TBool aRUS, TBool& aCompleteNow)
-    {
-    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxCopyDataToClient 1"));
-    aCompleteNow = ETrue;
-
-#if defined(USBC_LDD_BUFFER_TRACE)
-    const TInt numPkts = NoRxPackets();
-    const TInt numPktsAlt = NoRxPacketsAlt();
-    const TInt numBytes = RxBytesAvailable();
-    const TInt numBytesAlt = NoRxBytesAlt();
-
-    if (numPkts != numPktsAlt)
-        {
-        Kern::Printf(
-            "TDmaBuf::RxCopyDataToClient: Error: #pkts mismatch global=%d actual=%d",
-            numPkts, numPktsAlt);
-        }
-    if (numBytes != numBytesAlt)
-        {
-        Kern::Printf(
-            "TDmaBuf::RxCopyDataToClient: Error: #bytes mismatch global=%d actual=%d",
-            numBytes, numBytesAlt);
-        }
-    if ((numPkts == 0) && (numBytes != 0))
-        {
-        Kern::Printf(
-            "TDmaBuf::RxCopyDataToClient: Error: global bytes & pkts mismatch pkts=%d bytes=%d",
-            numPkts, numBytes);
-        }
-    if ((numPktsAlt == 0) && (numBytesAlt != 0))
-        {
-        Kern::Printf(
-            "TDmaBuf::RxCopyDataToClient: Error: actual bytes & pkts mismatch pkts=%d bytes=%d",
-            numPktsAlt, numBytesAlt);
-        }
-#endif
-
-    if (!NoRxPackets())
-        {
-        return KErrNotFound;
-        }
-
-    // coverity[var_tested_neg]
-    if (iCurrentDrainingBufferIndex == KUsbcInvalidBufferIndex)
-        {
-        // Marked as Coverity "Inentional" as the member variable
-        // iCurrentDrainingBufferIndex is attentionaly negative, from previous 
-        // initialization to KUsbcInvalidBufferIndex (which equals -1).
-
-        if (!NextDrainableBuffer())
-            {
-#if defined(USBC_LDD_BUFFER_TRACE)
-            Kern::Printf("TDmaBuf::RxCopyDataToClient: Error:  No buffer draining=%d, packets=%d",
-                         iCurrentDrainingBufferIndex, iTotalRxPacketsAvail);
-#endif
-            return KErrNotFound;
-            }
-        }
-#if defined(USBC_LDD_BUFFER_TRACE)
-
-    __ASSERT_DEBUG((iCurrentDrainingBufferIndex >= 0 ),
-                               Kern::Fault(KUsbPanicLdd, __LINE__));
-        
-    if (iDrainingOrder != iFillingOrderArray[iCurrentDrainingBufferIndex])
-        {
-        Kern::Printf("!!! Out of Order Draining TDmaBuf::RxCopyDataToClient 10 draining=%d",
-                     iCurrentDrainingBufferIndex);
-        }
-#endif
-    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::RxCopyDataToClient 2"));
-
-    TUint8* blockStartAddr = iCurrentDrainingBuffer + iCurrentPacketIndexArray[iCurrentPacket] + iExtractOffset;
-    TUint8* lastEndAddr = blockStartAddr;                    // going to track the contiguity of the memory
-    TUint8* thisStartAddr = blockStartAddr;
-    TInt toDo = Min(aLength - (TInt)aDestOffset, iTotalRxBytesAvail);
-#if defined(USBC_LDD_BUFFER_TRACE)
-    TInt bufnum = iCurrentDrainingBufferIndex;
-#endif
-    TInt errorCode = KErrNone;
-    TBool isShortPacket = EFalse;
-    const TInt maxPacketSizeMask = iMaxPacketSize - 1;
-    do
-        {
-#if defined(USBC_LDD_BUFFER_TRACE)
-        if (bufnum != iCurrentDrainingBufferIndex)
-            {
-            bufnum = iCurrentDrainingBufferIndex;
-            if (iDrainingOrder != iFillingOrderArray[iCurrentDrainingBufferIndex])
-                {
-                Kern::Printf("!!! Out of Order Draining TDmaBuf::RxCopyDataToClient 20 draining=%d",
-                             iCurrentDrainingBufferIndex);
-                }
-            }
-#endif
-        if (errorCode == KErrNone)
-            {
-            errorCode = GetCurrentError();
-            }
-        thisStartAddr = iCurrentDrainingBuffer + iCurrentPacketIndexArray[iCurrentPacket] + iExtractOffset;
-        const TInt thisPacketSize = iCurrentPacketSizeArray[iCurrentPacket];
-        const TInt size = thisPacketSize - iExtractOffset;
-        if (aRUS)
-            {
-            if (iEndpointType == UsbShai::KUsbEpTypeBulk)
-                {
-                isShortPacket = (size < iMaxPacketSize) || (size & maxPacketSizeMask);
-                }
-            else
-                {
-                // this 'if' block is arranged to avoid a division on packet sizes <= iMaxPacketSize
-                isShortPacket = (size < iMaxPacketSize) ||
-                    ((size > iMaxPacketSize) && (size % iMaxPacketSize));
-                }
-            }
-        TInt copySize = Min(size, toDo);
-        iExtractOffset += copySize;
-        toDo -= copySize;
-        if (thisStartAddr != lastEndAddr)
-            {
-            TInt bytesToCopy = lastEndAddr - blockStartAddr;
-            TInt r=CopyToUser(aThread, blockStartAddr, bytesToCopy, aTcb, aDestOffset);
-            if(r != KErrNone)
-                Kern::ThreadKill(aThread, EExitPanic, r, KUsbLDDKillCat);
-            blockStartAddr = thisStartAddr;
-            }
-
-        ModifyTotalRxBytesAvail(-copySize);
-#if defined(USBC_LDD_BUFFER_TRACE)
-        iNumberofBytesRxRemain[iCurrentDrainingBufferIndex] -= copySize;
-#endif
-        lastEndAddr = thisStartAddr + copySize;
-        if (iExtractOffset == thisPacketSize)
-            {
-            // More data to copy, so need to access new packet
-#if defined(USBC_LDD_BUFFER_TRACE)
-            iNumberofPacketsRxRemain[iCurrentDrainingBufferIndex] -= 1;
-#endif
-            if (!AdvancePacket())
-                {
-                break;                                        // no more packets left
-                }
-            }
-        } while (toDo > 0 && !isShortPacket);
-
-    if (thisStartAddr != lastEndAddr)
-        {
-        TInt bytesToCopy = lastEndAddr - blockStartAddr;
-        TInt r=CopyToUser(aThread, blockStartAddr, bytesToCopy, aTcb, aDestOffset);
-        if(r != KErrNone)
-            Kern::ThreadKill(aThread, EExitPanic, r, KUsbLDDKillCat);
-        }
-
-    // If we have transferred the requested amount of data it is still possible that
-    // the next packet is a zlp which needs to be bumped over
-
-    if (aRUS && (toDo == 0) && (iExtractOffset == 0) && (!isShortPacket) && (!IsReaderEmpty()) &&
-        (PeekNextPacketSize() == 0))
-        {
-        // swallow a zlp
-        isShortPacket = ETrue;
-#if defined(USBC_LDD_BUFFER_TRACE)
-        iNumberofPacketsRxRemain[iCurrentDrainingBufferIndex] -= 1;
-#endif
-        AdvancePacket();
-        }
-    aCompleteNow = isShortPacket || (((TInt)aDestOffset) == aLength) || (errorCode != KErrNone);
-
-    FreeDrainedBuffers();
-
-    // Use this error code to complete client read request
-    return errorCode;
-    }
-
-
-inline TInt TDmaBuf::CopyToUser(DThread* aThread, const TUint8* aSourceAddr,
-                                TInt aLength, TClientBuffer *aTcb, TUint32& aDestOffset)
-    {
-    TPtrC8 des(aSourceAddr, aLength);
-    TInt errorCode = Kern::ThreadBufWrite(aThread, aTcb, des, aDestOffset, KChunkShiftBy0, aThread);
-    if (errorCode == KErrNone)
-        {
-        aDestOffset += aLength;
-        }
-    return errorCode;
-    }
-
-
-inline TInt TDmaBuf::NoRxPackets() const
-    {
-    return iTotalRxPacketsAvail;
-    }
-
-
-inline void TDmaBuf::IncrementBufferIndex(TInt& aIndex)
-    {
-    if (++aIndex == iNumberofBuffers)
-        aIndex = 0;
-    }
-
-
-TBool TDmaBuf::NextDrainableBuffer()
-    {
-    TBool r = EFalse;
-    if (iCurrentDrainingBufferIndex != KUsbcInvalidBufferIndex)
-        {
-        iCanBeFreed[iCurrentDrainingBufferIndex] = ETrue;
-        iNumberofPacketsRx[iCurrentDrainingBufferIndex] = 0; // Current buffer is empty
-        iNumberofBytesRx[iCurrentDrainingBufferIndex] = 0;    // Current buffer is empty
-
-#if defined(USBC_LDD_BUFFER_TRACE)
-        TUint& bytesRemain = iNumberofBytesRxRemain[iCurrentDrainingBufferIndex];
-        TUint& pktsRemain = iNumberofPacketsRxRemain[iCurrentDrainingBufferIndex];
-        if ((bytesRemain != 0) || (pktsRemain != 0))
-            {
-            Kern::Printf(
-                "TDmaBuf::NextDrainableBuffer: Error: data discarded buffer=%d pkts=%d bytes=%d",
-                iCurrentDrainingBufferIndex, pktsRemain, bytesRemain);
-            bytesRemain = 0;
-            pktsRemain = 0;
-            }
-#endif
-
-        iCurrentDrainingBufferIndex = KUsbcInvalidBufferIndex;
-        iCurrentPacket = KUsbcInvalidPacketIndex;
-        }
-
-    if (iDrainQueueIndex != KUsbcInvalidDrainQueueIndex)
-        {
-        r = ETrue;
-        const TInt index = iDrainQueue[0];
-        iDrainQueueIndex--;
-        for (TInt i = 0; i < iNumberofBuffers; i++)
-            {
-            iDrainQueue[i] = iDrainQueue[i+1];
-            }
-
-#if defined(USBC_LDD_BUFFER_TRACE)
-        if (index != KUsbcInvalidBufferIndex)
-            iDrainingOrder++;
-#endif
-
-        iCurrentDrainingBufferIndex = index;
-        iCurrentDrainingBuffer = iBuffers[index];
-        iCurrentPacketIndexArray = iPacketIndex[index];
-        iCurrentPacketSizeArray = iPacketSize[index];
-        iCurrentPacket = 0;
-        }
-    return r;
-    }
-
-
-TInt TDmaBuf::PeekNextDrainableBuffer()
-    {
-    TInt r = KUsbcInvalidBufferIndex;
-    if (iDrainQueueIndex != KUsbcInvalidDrainQueueIndex)
-        {
-        r = iDrainQueue[0];
-        }
-    return r;
-    }
-
-
-TBool TDmaBuf::NextFillableBuffer()
-    {
-    TBool r = EFalse;
-    TInt index = iCurrentFillingBufferIndex;
-    IncrementBufferIndex(index);
-    // the sequence will restart at 0 if a buffer can't be found this time
-    iCurrentFillingBufferIndex = 0;
-    for (TInt i = 0; i < iNumberofBuffers; i++)
-        {
-        if (!iDrainable[index])
-            {
-            iCurrentFillingBufferIndex = index;
-            r = ETrue;
-            break;
-            }
-        IncrementBufferIndex(index);
-        }
-    return r;
-    }
-
-
-void TDmaBuf::FreeDrainedBuffers()
-    {
-    for (TInt i = 0; i < iNumberofBuffers; i++)
-        {
-        if (iDrainable[i] && iCanBeFreed[i])
-            {
-            iDrainable[i] = iCanBeFreed[i] = EFalse;
-            }
-        }
-    }
-
-
-TBool TDmaBuf::ShortPacketExists()
-    {
-    // Actually, a short packet or residue data
-    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::ShortPacketExists 1"));
-    TInt index = iCurrentDrainingBufferIndex;
-    TUsbcPacketArray* pktSizeArray = iCurrentPacketSizeArray;
-
-    if (iMaxPacketSize > 0)
-        {
-        // No buffers available for draining
-        if ((iCurrentDrainingBufferIndex == KUsbcInvalidBufferIndex) ||
-            (iCurrentPacket == KUsbcInvalidPacketIndex))
-            return EFalse;
-
-        // Zlp waiting at tail
-        if ((iTotalRxBytesAvail == 0) && (NoRxPackets() == 1))
-            return ETrue;
-
-        if (iEndpointType == UsbShai::KUsbEpTypeBulk)
-            {
-            const TInt mask = iMaxPacketSize - 1;
-            if (iTotalRxBytesAvail & mask)
-                return ETrue;
-
-            // residue==0; this can be because
-            // zlps exist, or short packets combine to n * max_packet_size
-            // This means spadework
-            const TInt s = iCurrentPacketSizeArray[iCurrentPacket] - iExtractOffset;
-            if ((s == 0) || (s & mask))
-                {
-                return ETrue;
-                }
-
-            for (TInt i = 0; i < iNumberofBuffers; i++)
-                {
-                if (index == KUsbcInvalidBufferIndex)
-                    break;
-                if (iDrainable[index])
-                    {
-                    const TInt packetCount = iNumberofPacketsRx[index];
-                    const TInt lastPacketSize=pktSizeArray[packetCount - 1];
-                    if ((lastPacketSize < iMaxPacketSize) || (lastPacketSize & mask))
-                        {
-                        return ETrue;
-                        }
-                    }
-                index = iDrainQueue[i];
-                pktSizeArray = iPacketSize[index];
-                }
-            }
-        else
-            {
-            if (iTotalRxBytesAvail % iMaxPacketSize)
-                return ETrue;
-
-            // residue==0; this can be because
-            // zlps exist, or short packets combine to n * max_packet_size
-            // This means spadework
-            const TInt s = iCurrentPacketSizeArray[iCurrentPacket] - iExtractOffset;
-            if ((s == 0) || (s % iMaxPacketSize))
-                {
-                return ETrue;
-                }
-
-            for (TInt i = 0; i < iNumberofBuffers; i++)
-                {
-                if (index == KUsbcInvalidBufferIndex)
-                    break;
-                if (iDrainable[index])
-                    {
-                    const TInt packetCount = iNumberofPacketsRx[index];
-                    const TInt lastPacketSize = pktSizeArray[packetCount - 1];
-                    if ((lastPacketSize < iMaxPacketSize) || (lastPacketSize % iMaxPacketSize))
-                        {
-                        return ETrue;
-                        }
-                    }
-                index = iDrainQueue[i];
-                pktSizeArray = iPacketSize[index];
-                }
-            }
-        }
-
-    return EFalse;
-    }
-
-
-void TDmaBuf::AddToDrainQueue(TInt aBufferIndex)
-    {
-    if (iDrainQueue[iDrainQueueIndex + 1] != KUsbcInvalidBufferIndex)
-        {
-#if defined(USBC_LDD_BUFFER_TRACE)
-        Kern::Printf("TDmaBuf::AddToDrainQueue: Error: invalid iDrainQueue[x]");
-#endif
-        }
-    iDrainQueue[++iDrainQueueIndex] = aBufferIndex;
-    }
-
-
-#if defined(USBC_LDD_BUFFER_TRACE)
-TInt TDmaBuf::NoRxPacketsAlt() const
-    {
-    TInt pktCount = 0;
-    for(TInt i = 0; i < iNumberofBuffers; i++)
-        {
-        if (iDrainable[i])
-            {
-            pktCount += iNumberofPacketsRxRemain[i];
-            }
-        }
-    return pktCount;
-    }
-
-
-TInt TDmaBuf::NoRxBytesAlt() const
-    {
-    TInt byteCount = 0;
-    for(TInt i = 0; i < iNumberofBuffers; i++)
-        {
-        if (iDrainable[i])
-            {
-            byteCount += iNumberofBytesRxRemain[i];
-            }
-        }
-    return byteCount;
-    }
-#endif
-
-
-// We only store 1 transaction, no other buffering is done
-TInt TDmaBuf::TxStoreData(DThread* aThread, TClientBuffer *aTcb, TInt aTxLength, TUint32 aBufferOffset)
-    {
-    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::TxStoreData 1"));
-    if (!IsReaderEmpty())
-        return KErrInUse;
-
-    __KTRACE_OPT(KUSB, Kern::Printf("TDmaBuf::TxStoreData 2"));
-    
-    TInt remainTxLength = aTxLength;
-    TUint32 bufferOffset = aBufferOffset;
-    // Store each buffer separately
-    for( TInt i=0;(i<iNumberofBuffers)&&(remainTxLength>0);i++)
-        {
-        TUint8* logicalDest = iBuffers[i];
-        TInt xferSz = Min(remainTxLength, iBufSz);
-        TPtr8 des(logicalDest, xferSz, xferSz);
-        TInt r = Kern::ThreadBufRead(aThread, aTcb, des, bufferOffset, KChunkShiftBy0);
-        if(r != KErrNone)
-            {
-            Kern::ThreadKill(aThread, EExitPanic, r, KUsbLDDKillCat);
-            return r;
-            }
-        remainTxLength -= iBufSz;
-        bufferOffset += iBufSz;
-        }
-
-    return KErrNone;
-    }
-
-
-TInt TDmaBuf::TxGetNextXfer(TUint8*& aBufferAddr, TInt& aTxLength, TPhysAddr& aBufferPhys)
-    {
-    if (iTxActive)
-        return KErrInUse;
-
-    aBufferAddr = iBuffers[0];                                // only 1 tx buffer
-    aBufferPhys = iBufferPhys[0];
-    aTxLength = BufferTotalSize();
-
-    return KErrNone;
-    }
-