Annotation of ntddk/src/network/sonic/loopback.c, revision 1.1.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.