Annotation of ntddk/src/network/sonic/loopback.c, revision 1.1

1.1     ! root        1: /*++
        !             2: 
        !             3: Copyright (c) 1990-1992  Microsoft Corporation
        !             4: 
        !             5: Module Name:
        !             6: 
        !             7:     loopback.c
        !             8: 
        !             9: Abstract:
        !            10: 
        !            11:     The routines here indicate packets on the loopback queue and are
        !            12:     responsible for inserting and removing packets from the loopback
        !            13:     queue and the send finishing queue.
        !            14: 
        !            15: Author:
        !            16: 
        !            17:     Anthony V. Ercolano (Tonye) 12-Sept-1990
        !            18: 
        !            19: Environment:
        !            20: 
        !            21:     Operates at dpc level - or the equivalent.
        !            22: 
        !            23: Revision History:
        !            24: 
        !            25: 
        !            26: --*/
        !            27: 
        !            28: #include <ndis.h>
        !            29: #include <efilter.h>
        !            30: 
        !            31: #include <sonichrd.h>
        !            32: #include <sonicsft.h>
        !            33: 
        !            34: 
        !            35: extern
        !            36: VOID
        !            37: SonicProcessLoopback(
        !            38:     IN PSONIC_ADAPTER Adapter
        !            39:     )
        !            40: 
        !            41: /*++
        !            42: 
        !            43: Routine Description:
        !            44: 
        !            45:     This routine is responsible for indicating *one* packet on
        !            46:     the loopback queue either completing it or moving on to the
        !            47:     finish send queue.
        !            48: 
        !            49:     NOTE : This routine is called with the lock held!
        !            50: 
        !            51: Arguments:
        !            52: 
        !            53:     Adapter - The adapter whose loopback queue we are processing.
        !            54: 
        !            55: Return Value:
        !            56: 
        !            57:     None.
        !            58: 
        !            59: --*/
        !            60: 
        !            61: {
        !            62: 
        !            63:     //
        !            64:     // Packet at the head of the loopback list.
        !            65:     //
        !            66:     PNDIS_PACKET PacketToMove;
        !            67: 
        !            68:     //
        !            69:     // The reserved portion of the above packet.
        !            70:     //
        !            71:     PSONIC_PACKET_RESERVED Reserved;
        !            72: 
        !            73:     //
        !            74:     // The first buffer in the ndis packet to be loopbacked.
        !            75:     //
        !            76:     PNDIS_BUFFER FirstBuffer;
        !            77: 
        !            78:     //
        !            79:     // The total amount of user data in the packet to be
        !            80:     // loopbacked.
        !            81:     //
        !            82:     UINT TotalPacketLength;
        !            83: 
        !            84:     //
        !            85:     // The address of the first buffer in the packet.
        !            86:     //
        !            87: 
        !            88:     PVOID BufferAddress;
        !            89: 
        !            90:     //
        !            91:     // The address of the data to be indicated
        !            92:     // to the transport.
        !            93:     //
        !            94:     PVOID DataAddress;
        !            95: 
        !            96:     //
        !            97:     // Eventually the length of the data to be indicated
        !            98:     // to the transport.
        !            99:     //
        !           100:     UINT BufferLength;
        !           101: 
        !           102:     //
        !           103:     // Open that submitted the packet
        !           104:     //
        !           105:     PSONIC_OPEN Open;
        !           106: 
        !           107:     ASSERT(Adapter->FirstLoopBack != NULL);
        !           108: 
        !           109:     PacketToMove = Adapter->FirstLoopBack;
        !           110: 
        !           111:     Reserved = PSONIC_RESERVED_FROM_PACKET(PacketToMove);
        !           112: 
        !           113:     if (Reserved->Next == NULL) {
        !           114: 
        !           115:         Adapter->LastLoopBack = NULL;
        !           116: 
        !           117:     }
        !           118: 
        !           119:     Adapter->FirstLoopBack = Reserved->Next;
        !           120: 
        !           121:     Open = PSONIC_OPEN_FROM_BINDING_HANDLE(Reserved->MacBindingHandle);
        !           122: 
        !           123:     Adapter->CurrentLoopbackPacket = PacketToMove;
        !           124: 
        !           125:     NdisReleaseSpinLock(&Adapter->Lock);
        !           126: 
        !           127:     //
        !           128:     // See if we need to copy the data from the packet
        !           129:     // into the loopback buffer.
        !           130:     //
        !           131:     // We need to copy to the local loopback buffer if
        !           132:     // the first buffer of the packet is less than the
        !           133:     // minimum loopback size AND the first buffer isn't
        !           134:     // the total packet.
        !           135:     //
        !           136: 
        !           137:     NdisQueryPacket(
        !           138:         PacketToMove,
        !           139:         NULL,
        !           140:         NULL,
        !           141:         &FirstBuffer,
        !           142:         &TotalPacketLength
        !           143:         );
        !           144: 
        !           145:     NdisQueryBuffer(
        !           146:         FirstBuffer,
        !           147:         &BufferAddress,
        !           148:         &BufferLength
        !           149:         );
        !           150: 
        !           151:     //
        !           152:     // Indicate the packet to every open binding
        !           153:     // that could want it. Since loopback indications
        !           154:     // are seralized, we store the packet here
        !           155:     // and use a NULL handle to indicate that it
        !           156:     // is for a loopback packet.
        !           157:     //
        !           158: 
        !           159:     if (BufferLength < 14) {
        !           160: 
        !           161:         //
        !           162:         // Must have at least the destination address
        !           163:         //
        !           164: 
        !           165:         if (BufferLength >= ETH_LENGTH_OF_ADDRESS) {
        !           166: 
        !           167:             //
        !           168:             // Runt packet
        !           169:             //
        !           170: 
        !           171:             EthFilterIndicateReceive(
        !           172:                 Adapter->FilterDB,
        !           173:                 (NDIS_HANDLE)NULL,
        !           174:                 ((PCHAR)BufferAddress),
        !           175:                 BufferAddress,                  // header
        !           176:                 BufferLength,                   // header size
        !           177:                 NULL,                           // lookahead
        !           178:                 0,                              // lookahead size
        !           179:                 0                               // packet size
        !           180:                 );
        !           181: 
        !           182:         }
        !           183: 
        !           184:     } else {
        !           185: 
        !           186:         //
        !           187:         // Copy the data if the first buffer does not hold
        !           188:         // the header plus the loopback amount required.
        !           189:         //
        !           190:         // NOTE: We could copy less if all the bindings had
        !           191:         // a shorted lookahead length set.
        !           192:         //
        !           193: 
        !           194:         if ((BufferLength < SONIC_LOOPBACK_MAXIMUM+14) &&
        !           195:             (BufferLength != TotalPacketLength)) {
        !           196: 
        !           197:             SonicCopyFromPacketToBuffer(
        !           198:                 PacketToMove,
        !           199:                 14,
        !           200:                 SONIC_LOOPBACK_MAXIMUM,
        !           201:                 Adapter->Loopback,
        !           202:                 &BufferLength
        !           203:                 );
        !           204: 
        !           205:             DataAddress = Adapter->Loopback;
        !           206: 
        !           207:         } else {
        !           208: 
        !           209:             DataAddress = (PUCHAR)BufferAddress + 14;
        !           210:             BufferLength -= 14;
        !           211: 
        !           212:         }
        !           213: 
        !           214:         EthFilterIndicateReceive(
        !           215:             Adapter->FilterDB,
        !           216:             (NDIS_HANDLE)NULL,
        !           217:             ((PCHAR)BufferAddress),
        !           218:             BufferAddress,                  // header
        !           219:             14,                             // header size
        !           220:             DataAddress,                    // lookahead
        !           221:             BufferLength,                   // lookahead size
        !           222:             TotalPacketLength - 14          // packet size
        !           223:             );
        !           224: 
        !           225:     }
        !           226: 
        !           227:     //
        !           228:     // Remove the packet from the loopback queue and
        !           229:     // either indicate that it is finished or put
        !           230:     // it on the finishing up queue for the real transmits.
        !           231:     //
        !           232: 
        !           233:     NdisCompleteSend(
        !           234:             Open->NdisBindingContext,
        !           235:             PacketToMove,
        !           236:             ((Reserved->SuccessfulTransmit)?
        !           237:              (NDIS_STATUS_SUCCESS):(NDIS_STATUS_FAILURE))
        !           238:             );
        !           239: 
        !           240:     NdisAcquireSpinLock(&Adapter->Lock);
        !           241: 
        !           242: #ifdef CHECK_DUP_SENDS
        !           243:     {
        !           244:         VOID SonicRemovePacketFromList(PSONIC_ADAPTER, PNDIS_PACKET);
        !           245:         SonicRemovePacketFromList(Adapter, PacketToMove);
        !           246:     }
        !           247: #endif
        !           248: 
        !           249:     //
        !           250:     // We can decrement the reference count on the open
        !           251:     // since it is no longer being "referenced" by the
        !           252:     // packet on the loopback queue.
        !           253:     //
        !           254: 
        !           255:     Open->References--;
        !           256: 
        !           257:     //
        !           258:     // If there is nothing else on the loopback queue
        !           259:     // then indicate that reception is "done".
        !           260:     //
        !           261: 
        !           262:     if (!Adapter->FirstLoopBack) {
        !           263: 
        !           264:         //
        !           265:         // Indicate to every open binding that "receives"
        !           266:         // are complete.
        !           267:         //
        !           268: 
        !           269:         NdisReleaseSpinLock(&Adapter->Lock);
        !           270: 
        !           271:         EthFilterIndicateReceiveComplete(Adapter->FilterDB);
        !           272: 
        !           273:         NdisAcquireSpinLock(&Adapter->Lock);
        !           274: 
        !           275:     }
        !           276: 
        !           277: }
        !           278: #ifdef CHECK_FINISH_TRANS
        !           279: VOID
        !           280: SonicShowFinishTrans(
        !           281:     IN PSONIC_ADAPTER Adapter,
        !           282:     IN UINT CheckLocation,
        !           283:     IN PVOID PacketPointer
        !           284:     )
        !           285: {
        !           286:     PNDIS_PACKET CurPointer;
        !           287:     PSONIC_PACKET_RESERVED Reserved;
        !           288: 
        !           289:     DbgPrint("SONIC: at %d for %lx:  %lx to %lx\n", CheckLocation, PacketPointer,
        !           290:                     Adapter->FirstFinishTransmit, Adapter->LastFinishTransmit);
        !           291: 
        !           292:     CurPointer = Adapter->FirstFinishTransmit;
        !           293: 
        !           294:     while (CurPointer) {
        !           295: 
        !           296:         Reserved = PSONIC_RESERVED_FROM_PACKET(CurPointer);
        !           297:         DbgPrint("%lx:   %lx ->\n", CurPointer, Reserved->Next);
        !           298: 
        !           299:         CurPointer = Reserved->Next;
        !           300: 
        !           301:     }
        !           302: }
        !           303: VOID
        !           304: SonicCheckFinishTrans(
        !           305:     IN PSONIC_ADAPTER Adapter,
        !           306:     IN UINT CheckLocation,
        !           307:     IN PVOID PacketPointer
        !           308:     )
        !           309: {
        !           310:     PNDIS_PACKET CurPointer, PrevPointer;
        !           311:     PSONIC_PACKET_RESERVED Reserved;
        !           312:     BOOLEAN BadQueue = FALSE;
        !           313: 
        !           314:     CurPointer = Adapter->FirstFinishTransmit;
        !           315:     PrevPointer = (PNDIS_PACKET)NULL;
        !           316: 
        !           317: 
        !           318:     while (CurPointer) {
        !           319: 
        !           320:         Reserved = PSONIC_RESERVED_FROM_PACKET(CurPointer);
        !           321: 
        !           322:         PrevPointer = CurPointer;
        !           323:         CurPointer = Reserved->Next;
        !           324: 
        !           325:     }
        !           326: 
        !           327:     if (Adapter->LastFinishTransmit != PrevPointer) {
        !           328: 
        !           329:         BadQueue = TRUE;
        !           330: 
        !           331:     }
        !           332: 
        !           333:     if (BadQueue) {
        !           334: 
        !           335:         SonicShowFinishTrans(Adapter, CheckLocation, PacketPointer);
        !           336: 
        !           337:     }
        !           338: }
        !           339: #endif  // CHECK_FINISH_TRANS
        !           340: 
        !           341: extern
        !           342: VOID
        !           343: SonicPutPacketOnLoopBack(
        !           344:     IN PSONIC_ADAPTER Adapter,
        !           345:     IN PNDIS_PACKET Packet,
        !           346:     IN BOOLEAN SuccessfulTransmit
        !           347:     )
        !           348: 
        !           349: /*++
        !           350: 
        !           351: Routine Description:
        !           352: 
        !           353:     Put the packet on the adapter wide loop back list.
        !           354: 
        !           355:     NOTE: This routine assumes that the lock is held.
        !           356: 
        !           357: Arguments:
        !           358: 
        !           359:     Adapter - The adapter that contains the loop back list.
        !           360: 
        !           361:     Packet - The packet to be put on loop back.
        !           362: 
        !           363:     SuccessfulTransmit - This value should be placed in the
        !           364:     reserved section.
        !           365: 
        !           366:     NOTE: If ReadyToComplete == TRUE then the packets completion status
        !           367:     field will also be set TRUE.
        !           368: 
        !           369: Return Value:
        !           370: 
        !           371:     None.
        !           372: 
        !           373: --*/
        !           374: 
        !           375: {
        !           376: 
        !           377:     PSONIC_PACKET_RESERVED Reserved = PSONIC_RESERVED_FROM_PACKET(Packet);
        !           378: 
        !           379:     if (!Adapter->FirstLoopBack) {
        !           380: 
        !           381:         Adapter->FirstLoopBack = Packet;
        !           382: 
        !           383:     } else {
        !           384: 
        !           385:         PSONIC_RESERVED_FROM_PACKET(Adapter->LastLoopBack)->Next = Packet;
        !           386: 
        !           387:     }
        !           388: 
        !           389:     Reserved->SuccessfulTransmit = SuccessfulTransmit;
        !           390: 
        !           391:     Reserved->Next = NULL;
        !           392:     Adapter->LastLoopBack = Packet;
        !           393: 
        !           394: }
        !           395: 

unix.superglobalmegacorp.com

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