Annotation of ntddk/src/network/ibmtok/transfer.c, revision 1.1

1.1     ! root        1: /*++
        !             2: 
        !             3: Copyright (c) 1990  Microsoft Corporation
        !             4: 
        !             5: Module Name:
        !             6: 
        !             7:     transfer.c
        !             8: 
        !             9: Abstract:
        !            10: 
        !            11:     This file contains the code to implement the MacTransferData
        !            12:     API for the ndis 3.0 interface.
        !            13: 
        !            14: Author:
        !            15: 
        !            16:     Anthony V. Ercolano (Tonye) 12-Sept-1990
        !            17:     Adam Barr (adamba) 15-Mar-1991
        !            18: 
        !            19: Environment:
        !            20: 
        !            21:     Kernel Mode - Or whatever is the equivalent.
        !            22: 
        !            23: Revision History:
        !            24: 
        !            25: 
        !            26: --*/
        !            27: 
        !            28: #pragma optimize("",off)
        !            29: 
        !            30: #include <ndis.h>
        !            31: 
        !            32: #include <tfilter.h>
        !            33: #include <tokhrd.h>
        !            34: #include <toksft.h>
        !            35: 
        !            36: 
        !            37: extern
        !            38: NDIS_STATUS
        !            39: IbmtokTransferData(
        !            40:     IN NDIS_HANDLE MacBindingHandle,
        !            41:     IN NDIS_HANDLE MacReceiveContext,
        !            42:     IN UINT ByteOffset,
        !            43:     IN UINT BytesToTransfer,
        !            44:     OUT PNDIS_PACKET Packet,
        !            45:     OUT PUINT BytesTransferred
        !            46:     )
        !            47: 
        !            48: /*++
        !            49: 
        !            50: Routine Description:
        !            51: 
        !            52:     A protocol calls the IbmtokTransferData request (indirectly via
        !            53:     NdisTransferData) from within its Receive event handler
        !            54:     to instruct the MAC to copy the contents of the received packet
        !            55:     a specified packet buffer.
        !            56: 
        !            57: Arguments:
        !            58: 
        !            59:     MacBindingHandle - The context value returned by the MAC when the
        !            60:     adapter was opened.  In reality this is a pointer to IBMTOK.
        !            61: 
        !            62:     MacReceiveContext - The context value passed by the MAC on its call
        !            63:     to NdisIndicateReceive.  The MAC can use this value to determine
        !            64:     which packet, on which adapter, is being received.
        !            65: 
        !            66:     ByteOffset - An unsigned integer specifying the offset within the
        !            67:     received packet at which the copy is to begin.  If the entire packet
        !            68:     is to be copied, ByteOffset must be zero.
        !            69: 
        !            70:     BytesToTransfer - An unsigned integer specifying the number of bytes
        !            71:     to copy.  It is legal to transfer zero bytes; this has no effect.  If
        !            72:     the sum of ByteOffset and BytesToTransfer is greater than the size
        !            73:     of the received packet, then the remainder of the packet (starting from
        !            74:     ByteOffset) is transferred, and the trailing portion of the receive
        !            75:     buffer is not modified.
        !            76: 
        !            77:     Packet - A pointer to a descriptor for the packet storage into which
        !            78:     the MAC is to copy the received packet.
        !            79: 
        !            80:     BytesTransfered - A pointer to an unsigned integer.  The MAC writes
        !            81:     the actual number of bytes transferred into this location.  This value
        !            82:     is not valid if the return status is STATUS_PENDING.
        !            83: 
        !            84: Return Value:
        !            85: 
        !            86:     The function value is the status of the operation.
        !            87: 
        !            88: 
        !            89: --*/
        !            90: 
        !            91: {
        !            92: 
        !            93:     PIBMTOK_ADAPTER Adapter;
        !            94: 
        !            95:     NDIS_STATUS StatusToReturn;
        !            96: 
        !            97:     Adapter = PIBMTOK_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
        !            98: 
        !            99:     NdisAcquireSpinLock(&Adapter->Lock);
        !           100:     Adapter->References++;
        !           101: 
        !           102:     if (!Adapter->NotAcceptingRequests) {
        !           103: 
        !           104:         PIBMTOK_OPEN Open = PIBMTOK_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
        !           105: 
        !           106:         if (!Open->BindingShuttingDown) {
        !           107: 
        !           108:             //
        !           109:             // The code in this section is quite similar to the
        !           110:             // code in CopyFromPacketToPacket.  It could easily go
        !           111:             // into its own routine, except that it is not likely
        !           112:             // to be used in any other implementation.
        !           113:             //
        !           114:             SRAM_PTR SourceReceiveBuffer =
        !           115:                 Adapter->IndicatedReceiveBuffer;
        !           116: 
        !           117:             //
        !           118:             // Holds the count of the number of ndis buffers comprising
        !           119:             // the destination packet.
        !           120:             //
        !           121:             UINT DestinationBufferCount;
        !           122: 
        !           123:             //
        !           124:             // Points to the buffer into which we are putting data.
        !           125:             //
        !           126:             PNDIS_BUFFER DestinationCurrentBuffer;
        !           127: 
        !           128:             //
        !           129:             // Holds the virtual address of the current destination
        !           130:             // buffer.
        !           131:             //
        !           132:             PVOID DestinationVirtualAddress;
        !           133: 
        !           134:             //
        !           135:             // Holds the virtual address of the current source buffer.
        !           136:             //
        !           137:             PRECEIVE_BUFFER SourceBufferAddress;
        !           138: 
        !           139:             //
        !           140:             // Holds the address of the data in the current source buffer.
        !           141:             //
        !           142:             PVOID SourceVirtualAddress;
        !           143: 
        !           144:             //
        !           145:             // Holds the length of the current destination buffer.
        !           146:             //
        !           147:             UINT DestinationCurrentLength;
        !           148: 
        !           149:             //
        !           150:             // Holds the length of the current source buffer.
        !           151:             //
        !           152:             UINT SourceCurrentLength;
        !           153: 
        !           154:             //
        !           155:             // Keep a local variable of BytesTransferred so we aren't
        !           156:             // referencing through a pointer.
        !           157:             //
        !           158:             UINT LocalBytesTransferred = 0;
        !           159: 
        !           160:             USHORT PortValue;
        !           161: 
        !           162:             Open->References++;
        !           163: 
        !           164:             NdisReleaseSpinLock(&Adapter->Lock);
        !           165: 
        !           166:             *BytesTransferred = 0;
        !           167: 
        !           168:             ASSERT(sizeof(UINT) >= 2);
        !           169:             ASSERT(sizeof(UINT) == sizeof(NDIS_HANDLE));
        !           170: 
        !           171:             //
        !           172:             // Get the first buffer of the destination.
        !           173:             //
        !           174: 
        !           175:             NdisQueryPacket(
        !           176:                 Packet,
        !           177:                 NULL,
        !           178:                 &DestinationBufferCount,
        !           179:                 &DestinationCurrentBuffer,
        !           180:                 NULL
        !           181:                 );
        !           182: 
        !           183:             //
        !           184:             // Could have a null packet.
        !           185:             //
        !           186: 
        !           187:             if (DestinationBufferCount != 0) {
        !           188: 
        !           189:                 NdisQueryBuffer(
        !           190:                     DestinationCurrentBuffer,
        !           191:                     &DestinationVirtualAddress,
        !           192:                     &DestinationCurrentLength
        !           193:                     );
        !           194: 
        !           195:                 //
        !           196:                 // Get the information for the first buffer of the source.
        !           197:                 //
        !           198: 
        !           199:                 SourceBufferAddress = (PRECEIVE_BUFFER)
        !           200:                     ((PUCHAR)SRAM_PTR_TO_PVOID(Adapter,
        !           201:                             SourceReceiveBuffer) + 2);
        !           202: 
        !           203:                 //
        !           204:                 // Adjust the address and length to account for the
        !           205:                 // header for this frame.
        !           206:                 //
        !           207: 
        !           208:                 SourceVirtualAddress =
        !           209:                     SourceBufferAddress->FrameData +
        !           210:                     Adapter->IndicatedHeaderLength;
        !           211: 
        !           212:                 NdisReadRegisterUshort(&SourceBufferAddress->BufferLength,
        !           213:                                        &PortValue
        !           214:                                       );
        !           215: 
        !           216:                 SourceCurrentLength = IBMSHORT_TO_USHORT(PortValue) -
        !           217:                                       Adapter->IndicatedHeaderLength;
        !           218: 
        !           219: 
        !           220: 
        !           221:                 //
        !           222:                 // Take care of boundary condition of zero length copy.
        !           223:                 //
        !           224: 
        !           225:                 while (LocalBytesTransferred < BytesToTransfer) {
        !           226: 
        !           227:                     //
        !           228:                     // Check to see whether we've exhausted the current
        !           229:                     // destination buffer.  If so, move onto the next one.
        !           230:                     //
        !           231: 
        !           232:                     if (!DestinationCurrentLength) {
        !           233: 
        !           234:                         NdisGetNextBuffer(
        !           235:                             DestinationCurrentBuffer,
        !           236:                             &DestinationCurrentBuffer
        !           237:                             );
        !           238: 
        !           239:                         if (!DestinationCurrentBuffer) {
        !           240: 
        !           241:                             //
        !           242:                             // We've reached the end of the packet.  We
        !           243:                             // return with what we've done so far. (Which
        !           244:                             // must be shorter than requested.)
        !           245:                             //
        !           246: 
        !           247:                             break;
        !           248: 
        !           249:                         }
        !           250: 
        !           251:                         NdisQueryBuffer(
        !           252:                             DestinationCurrentBuffer,
        !           253:                             &DestinationVirtualAddress,
        !           254:                             &DestinationCurrentLength
        !           255:                             );
        !           256:                         continue;
        !           257: 
        !           258:                     }
        !           259: 
        !           260: 
        !           261:                     //
        !           262:                     // Check to see whether we've exhausted the current
        !           263:                     // source buffer.  If so, move onto the next one.
        !           264:                     //
        !           265: 
        !           266:                     if (!SourceCurrentLength) {
        !           267: 
        !           268:                         NdisReadRegisterUshort(
        !           269:                                      &SourceBufferAddress->NextBuffer,
        !           270:                                      &SourceReceiveBuffer
        !           271:                                      );
        !           272: 
        !           273:                         if (SourceReceiveBuffer == NULL_SRAM_PTR) {
        !           274: 
        !           275:                             //
        !           276:                             // We've reached the end of the frame.  We
        !           277:                             // return with what we've done so far. (Which
        !           278:                             // must be shorter than requested.)
        !           279:                             //
        !           280: 
        !           281:                             break;
        !           282: 
        !           283:                         }
        !           284: 
        !           285:                         SourceBufferAddress = (PRECEIVE_BUFFER)
        !           286:                           SRAM_PTR_TO_PVOID(Adapter, SourceReceiveBuffer);
        !           287: 
        !           288:                         SourceVirtualAddress =
        !           289:                             (PVOID)SourceBufferAddress->FrameData;
        !           290: 
        !           291:                         NdisReadRegisterUshort(
        !           292:                                 &SourceBufferAddress->BufferLength,
        !           293:                                 &SourceCurrentLength
        !           294:                                 );
        !           295: 
        !           296:                         SourceCurrentLength = IBMSHORT_TO_USHORT(
        !           297:                                                 SourceCurrentLength
        !           298:                                                 );
        !           299: 
        !           300:                         continue;
        !           301: 
        !           302:                     }
        !           303: 
        !           304:                     //
        !           305:                     // Try to get us up to the point to start the copy.
        !           306:                     //
        !           307: 
        !           308:                     if (ByteOffset) {
        !           309: 
        !           310:                         if (ByteOffset > SourceCurrentLength) {
        !           311: 
        !           312:                             //
        !           313:                             // What we want isn't in this buffer.
        !           314:                             //
        !           315: 
        !           316:                             ByteOffset -= SourceCurrentLength;
        !           317:                             SourceCurrentLength = 0;
        !           318:                             continue;
        !           319: 
        !           320:                         } else {
        !           321: 
        !           322:                             SourceVirtualAddress =
        !           323:                                 (PCHAR)SourceVirtualAddress + ByteOffset;
        !           324:                             SourceCurrentLength -= ByteOffset;
        !           325:                             ByteOffset = 0;
        !           326: 
        !           327:                         }
        !           328: 
        !           329:                     }
        !           330: 
        !           331:                     //
        !           332:                     // Copy the data.
        !           333:                     //
        !           334: 
        !           335:                     {
        !           336: 
        !           337:                         //
        !           338:                         // Holds the amount of data to move.
        !           339:                         //
        !           340:                         UINT AmountToMove;
        !           341: 
        !           342:                         //
        !           343:                         // Holds the amount desired remaining.
        !           344:                         //
        !           345:                         UINT Remaining = BytesToTransfer
        !           346:                                          - LocalBytesTransferred;
        !           347: 
        !           348:                         AmountToMove =
        !           349:                       ((SourceCurrentLength <= DestinationCurrentLength)?
        !           350:                        (SourceCurrentLength):(DestinationCurrentLength));
        !           351: 
        !           352:                         AmountToMove = ((Remaining < AmountToMove)?
        !           353:                                         (Remaining):(AmountToMove));
        !           354: 
        !           355:                         IBMTOK_MOVE_FROM_MAPPED_MEMORY(
        !           356:                             DestinationVirtualAddress,
        !           357:                             SourceVirtualAddress,
        !           358:                             AmountToMove
        !           359:                             );
        !           360: 
        !           361:                         DestinationVirtualAddress =
        !           362:                           (PCHAR)DestinationVirtualAddress + AmountToMove;
        !           363:                         SourceVirtualAddress =
        !           364:                             (PCHAR)SourceVirtualAddress + AmountToMove;
        !           365: 
        !           366:                         LocalBytesTransferred += AmountToMove;
        !           367:                         SourceCurrentLength -= AmountToMove;
        !           368:                         DestinationCurrentLength -= AmountToMove;
        !           369: 
        !           370:                     }
        !           371: 
        !           372:                 }
        !           373: 
        !           374:                 *BytesTransferred = LocalBytesTransferred;
        !           375: 
        !           376:             }
        !           377: 
        !           378:             NdisAcquireSpinLock(&Adapter->Lock);
        !           379:             Open->References--;
        !           380:             StatusToReturn = NDIS_STATUS_SUCCESS;
        !           381: 
        !           382:         } else {
        !           383: 
        !           384:             StatusToReturn = NDIS_STATUS_REQUEST_ABORTED;
        !           385: 
        !           386:         }
        !           387: 
        !           388:     } else {
        !           389: 
        !           390:         if (Adapter->ResetInProgress) {
        !           391: 
        !           392:             StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS;
        !           393: 
        !           394:         } else if (Adapter->OpenInProgress) {
        !           395: 
        !           396:             StatusToReturn = NDIS_STATUS_FAILURE;
        !           397: 
        !           398:         } else {
        !           399: 
        !           400:             NdisWriteErrorLogEntry(
        !           401:                 Adapter->NdisAdapterHandle,
        !           402:                 NDIS_ERROR_CODE_DRIVER_FAILURE,
        !           403:                 2,
        !           404:                 IBMTOK_ERRMSG_INVALID_STATE,
        !           405:                 1
        !           406:                 );
        !           407: 
        !           408:         }
        !           409: 
        !           410:     }
        !           411: 
        !           412:     IBMTOK_DO_DEFERRED(Adapter);
        !           413:     return StatusToReturn;
        !           414: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.