Annotation of ntddk/src/network/lance/send.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1990  Microsoft Corporation
                      4: 
                      5: Module Name:
                      6: 
                      7:     send.c
                      8: 
                      9: Abstract:
                     10: 
                     11:     This file contains the code for putting a packet through the
                     12:     staged allocation for transmission.
                     13: 
                     14:     This is a process of
                     15: 
                     16:     1) Calculating the what would need to be done to the
                     17:     packet so that the packet can be transmitted on the hardware.
                     18: 
                     19:     2) Potentially allocating adapter buffers and copying user data
                     20:     to those buffers so that the packet data is transmitted under
                     21:     the hardware constraints.
                     22: 
                     23:     3) Allocating enough hardware ring entries so that the packet
                     24:     can be transmitted.
                     25: 
                     26:     4) Relinquish thos ring entries to the hardware.
                     27: 
                     28: Author:
                     29: 
                     30:     Anthony V. Ercolano (Tonye) 12-Sept-1990
                     31: 
                     32: Environment:
                     33: 
                     34:     Kernel Mode - Or whatever is the equivalent on OS/2 and DOS.
                     35: 
                     36: Revision History:
                     37: 
                     38:     31-Jul-1992  R.D. Lanser:
                     39: 
                     40:        Removed PhysicalBuffersContained and UsedLanceBuffer field from
                     41:        _ADAPTER structure.  SeanSe says that the code related to this
                     42:        field was used for adevice that is no longer supported.  I removed
                     43:        the dependent code(or at least what was obvious) from 'send.c'.
                     44:        This old code was generating an erroneous ring buffer count on the
                     45:        MIPS R3000.  I did not test it on the MIPS R4000.  The problem goes
                     46:        away with the removal of the offending code.
                     47: 
                     48: --*/
                     49: 
                     50: #include <ndis.h>
                     51: #include <efilter.h>
                     52: #include <lancehrd.h>
                     53: #include <lancesft.h>
                     54: 
                     55: 
                     56: //
                     57: // Minimum packet size that a transport can send.  We subtract 4 bytes
                     58: // because we add a 4 byte CRC on the end.
                     59: //
                     60: 
                     61: #define MIN_SINGLE_BUFFER ((UINT)LANCE_SMALL_BUFFER_SIZE - 4)
                     62: 
                     63: 
                     64: //
                     65: // It will poke the lance hardware into noticing that there is a packet
                     66: // available for transmit.
                     67: //
                     68: // Note that there is the assumption that the register address
                     69: // port (RAP) is already set to zero.
                     70: //
                     71: #define PROD_TRANSMIT(A) \
                     72:     LANCE_WRITE_RDP( \
                     73:     A, \
                     74:     LANCE_CSR0_TRANSMIT_DEMAND | LANCE_CSR0_INTERRUPT_ENABLE \
                     75:     );
                     76: 
                     77: VOID
                     78: SetupAllocate(
                     79:     IN PLANCE_ADAPTER Adapter,
                     80:     IN NDIS_HANDLE MacBindingHandle,
                     81:     IN PNDIS_PACKET Packet
                     82:     );
                     83: 
                     84: VOID
                     85: StagedAllocation(
                     86:     IN PLANCE_ADAPTER Adapter
                     87:     );
                     88: 
                     89: VOID
                     90: CopyPacketIntoBuffer(
                     91:     IN PLANCE_ADAPTER Adapter,
                     92:     IN PNDIS_PACKET Packet,
                     93:     IN PLANCE_BUFFER_DESCRIPTOR BufferDescriptor
                     94:     );
                     95: 
                     96: 
                     97: 
                     98: extern
                     99: NDIS_STATUS
                    100: LanceSend(
                    101:     IN NDIS_HANDLE MacBindingHandle,
                    102:     IN PNDIS_PACKET Packet
                    103:     )
                    104: 
                    105: /*++
                    106: 
                    107: Routine Description:
                    108: 
                    109:     The LanceSend request instructs a MAC to transmit a packet through
                    110:     the adapter onto the medium.
                    111: 
                    112: Arguments:
                    113: 
                    114:     MacBindingHandle - The context value returned by the MAC  when the
                    115:     adapter was opened.  In reality, it is a pointer to LANCE_OPEN.
                    116: 
                    117:     Packet - A pointer to a descriptor for the packet that is to be
                    118:     transmitted.
                    119: 
                    120: Return Value:
                    121: 
                    122:     The function value is the status of the operation.
                    123: 
                    124: 
                    125: --*/
                    126: 
                    127: {
                    128: 
                    129:     //
                    130:     // Holds the status that should be returned to the caller.
                    131:     //
                    132:     NDIS_STATUS StatusToReturn = NDIS_STATUS_PENDING;
                    133: 
                    134:     //
                    135:     // Pointer to the adapter.
                    136:     //
                    137:     PLANCE_ADAPTER Adapter;
                    138: 
                    139:     PLANCE_OPEN Open;
                    140: 
                    141:     Open = PLANCE_OPEN_FROM_BINDING_HANDLE(MacBindingHandle);
                    142: 
                    143: #if LANCE_TRACE
                    144:     DbgPrint("In LanceSend\n");
                    145: #endif
                    146: 
                    147:     Adapter = PLANCE_ADAPTER_FROM_BINDING_HANDLE(MacBindingHandle);
                    148: 
                    149:     if (Adapter->HardwareFailure) {
                    150: 
                    151:         return(NDIS_STATUS_FAILURE);
                    152: 
                    153:     }
                    154: 
                    155:     NdisAcquireSpinLock(&Adapter->Lock);
                    156:     Adapter->References++;
                    157: 
                    158:     LOG(IN_SEND);
                    159: 
                    160:     if (!Adapter->ResetInProgress) {
                    161: 
                    162:         if (!Open->BindingShuttingDown) {
                    163: 
                    164:             UINT TotalPacketSize;
                    165: 
                    166:             //
                    167:             // Increment the references on the open while we are
                    168:             // accessing it in the interface.
                    169:             //
                    170: 
                    171:             Open->References++;
                    172: 
                    173:             //
                    174:             // It is reasonable to do a quick check and fail if the packet
                    175:             // is larger than the maximum an ethernet can handle.
                    176:             //
                    177: 
                    178:             NdisQueryPacket(
                    179:                 Packet,
                    180:                 NULL,
                    181:                 NULL,
                    182:                 NULL,
                    183:                 &TotalPacketSize
                    184:                 );
                    185: 
                    186:             if ((!TotalPacketSize) ||
                    187:                 (TotalPacketSize > LANCE_LARGE_BUFFER_SIZE)) {
                    188: 
                    189:                 StatusToReturn = NDIS_STATUS_RESOURCES;
                    190: 
                    191:             } else {
                    192: 
                    193:                 //
                    194:                 // There is an assumption in the code that no pointer
                    195:                 // (which are really handles) to an ndis packet will have
                    196:                 // its low bit set. (Always have even byte alignment.)
                    197:                 //
                    198: 
                    199:                 ASSERT(!((UINT)Packet & 1));
                    200: 
                    201:                 SetupAllocate(
                    202:                     Adapter,
                    203:                     MacBindingHandle,
                    204:                     Packet
                    205:                     );
                    206: 
                    207:                 //
                    208:                 // Add a reference for the pending send
                    209:                 //
                    210: 
                    211:                 Open->References++;
                    212: 
                    213:                 //
                    214:                 // Only try to push it through the stage queues
                    215:                 // if somebody else isn't already doing it and
                    216:                 // there is some hope of moving some packets
                    217:                 // ahead.
                    218:                 //
                    219: 
                    220:                 while ((!Adapter->AlreadyProcessingStage
                    221:                        ) &&
                    222:                        (Adapter->FirstStage1Packet &&
                    223:                         Adapter->StageOpen
                    224:                        )
                    225:                       ) {
                    226: 
                    227:                     LanceStagedAllocation(Adapter);
                    228: 
                    229:                 }
                    230: 
                    231:             }
                    232: 
                    233:             //
                    234:             // The interface is no longer referencing the open.
                    235:             //
                    236: 
                    237:             Open->References--;
                    238: 
                    239:         } else {
                    240: 
                    241:             StatusToReturn = NDIS_STATUS_CLOSING;
                    242: 
                    243:         }
                    244: 
                    245:     } else if (Adapter->ResetRequestType == NdisRequestGeneric1) {
                    246: 
                    247:         StatusToReturn = NDIS_STATUS_RESET_IN_PROGRESS;
                    248: 
                    249:     } else {
                    250: 
                    251:         //
                    252:         // Reset is from a SetInfo or internal call and this packet needs
                    253:         // to be pended.
                    254:         //
                    255: 
                    256:         SetupAllocate(
                    257:                         Adapter,
                    258:                         MacBindingHandle,
                    259:                         Packet
                    260:                         );
                    261: 
                    262:         //
                    263:         // Add one to reference fore pending send
                    264:         //
                    265:         Open->References++;
                    266: 
                    267:         StatusToReturn = NDIS_STATUS_PENDING;
                    268: 
                    269:     }
                    270: 
                    271:     LOG(OUT_SEND);
                    272: 
                    273:     LANCE_DO_DEFERRED(Adapter);
                    274: 
                    275: #if LANCE_TRACE
                    276:     DbgPrint("Out LanceSend\n");
                    277: #endif
                    278: 
                    279:     return StatusToReturn;
                    280: }
                    281: 
                    282: VOID
                    283: SetupAllocate(
                    284:     IN PLANCE_ADAPTER Adapter,
                    285:     IN NDIS_HANDLE MacBindingHandle,
                    286:     IN PNDIS_PACKET Packet
                    287:     )
                    288: 
                    289: /*++
                    290: 
                    291: Routine Description:
                    292: 
                    293:     This sets up the MAC reserved portion of the packet so that
                    294:     later allocation routines can determine what is left to be
                    295:     done in the allocation cycle.
                    296: 
                    297:     NOTE: This assumes it is called with the spinlock held!!
                    298: 
                    299: Arguments:
                    300: 
                    301:     Adapter - The adapter that this packet is coming through.
                    302: 
                    303:     MacBindingHandle - Points to the open binding structure.
                    304: 
                    305:     Packet - The packet that is to be transmitted.
                    306: 
                    307: Return Value:
                    308: 
                    309:     None.
                    310: 
                    311: --*/
                    312: 
                    313: {
                    314: 
                    315:     //
                    316:     // Points to the MAC reserved portion of this packet.  This
                    317:     // interpretation of the reserved section is only valid during
                    318:     // the allocation phase of the packet.
                    319:     //
                    320:     PLANCE_RESERVED Reserved = PLANCE_RESERVED_FROM_PACKET(Packet);
                    321: 
                    322: 
                    323:     ASSERT(sizeof(LANCE_RESERVED) <=
                    324:            sizeof(Packet->MacReserved));
                    325: 
                    326:     Reserved->LanceBuffersIndex = 0;
                    327:     Reserved->MacBindingHandle = MacBindingHandle;
                    328: 
                    329:     //
                    330:     // Put on the stage 1 queue.
                    331:     //
                    332: 
                    333:     if (!Adapter->LastStage1Packet) {
                    334: 
                    335:         Adapter->FirstStage1Packet = Packet;
                    336: 
                    337:     } else {
                    338: 
                    339:         PLANCE_RESERVED_FROM_PACKET(Adapter->LastStage1Packet)->Next = Packet;
                    340: 
                    341:     }
                    342: 
                    343:     Adapter->LastStage1Packet = Packet;
                    344: 
                    345:     Reserved->Next = NULL;
                    346: 
                    347: }
                    348: 
                    349: extern
                    350: VOID
                    351: LanceStagedAllocation(
                    352:     IN PLANCE_ADAPTER Adapter
                    353:     )
                    354: 
                    355: /*++
                    356: 
                    357: Routine Description:
                    358: 
                    359:     This routine attempts to take a packet through a stage of allocation.
                    360: 
                    361:     NOTE: THIS IS CALLED WITH THE LOCK HELD!!
                    362: 
                    363:     NOTE: MUST BE CALLED WITH
                    364: 
                    365:         Adapter->StageOpen &&
                    366:         !Adapter->AlreadyProcessingStage &&
                    367:         Adapter->FirstStage1Packet
                    368: 
                    369: 
                    370: 
                    371: Arguments:
                    372: 
                    373:     Adapter - The adapter that the packets are coming through.
                    374: 
                    375: Return Value:
                    376: 
                    377:     None.
                    378: 
                    379: --*/
                    380: 
                    381: {
                    382:     //
                    383:     // Pointer to the ring entry to be filled with buffer information.
                    384:     //
                    385:     PLANCE_TRANSMIT_ENTRY CurrentRingElement;
                    386: 
                    387:     //
                    388:     // Pointer to the ring to packet entry that records the info about
                    389:     // this packet.
                    390:     //
                    391:     PLANCE_RING_TO_PACKET RingToPacket;
                    392: 
                    393:     //
                    394:     // Length of the packet
                    395:     //
                    396:     ULONG TotalVirtualLength;
                    397: 
                    398:     //
                    399:     // Holds the adapter buffer index available for allocation.
                    400:     //
                    401:     INT LanceBuffersIndex;
                    402: 
                    403:     //
                    404:     // Points to a successfully allocated adapter buffer descriptor.
                    405:     //
                    406:     PLANCE_BUFFER_DESCRIPTOR BufferDescriptor;
                    407: 
                    408:     //
                    409:     // Simple iteration variable.
                    410:     //
                    411:     INT i;
                    412: 
                    413:     //
                    414:     // Size of Lance Buffer needed (1==Small, 2==Medium, 3==Large)
                    415:     //
                    416:     UCHAR BufferSize;
                    417: 
                    418:     //
                    419:     // If we successfully acquire some ring entries, this
                    420:     // is the index of the first one.
                    421:     //
                    422:     UINT RingIndex;
                    423: 
                    424:     PNDIS_PACKET FirstPacket;
                    425: 
                    426:     PLANCE_RESERVED Reserved;
                    427: 
                    428: 
                    429:     if (Adapter->NumberOfAvailableRings == 0) {
                    430: 
                    431:         Adapter->StageOpen = FALSE;
                    432:         return ;
                    433: 
                    434:     }
                    435: 
                    436:     Adapter->AlreadyProcessingStage = TRUE;
                    437: 
                    438:     FirstPacket = Adapter->FirstStage1Packet;
                    439: 
                    440:     //
                    441:     // Determine if and how much adapter space would need to be allocated
                    442:     // to meet hardware constraints.
                    443:     //
                    444: 
                    445:     NdisQueryPacket(
                    446:         FirstPacket,
                    447:         NULL,
                    448:         NULL,
                    449:         NULL,
                    450:         &TotalVirtualLength
                    451:         );
                    452: 
                    453:     //
                    454:     // Certain hardware implementation (Decstation) use a dual ported
                    455:     // memory to communicate with the hardware.  This is reasonable since
                    456:     // it reduces bus contention.  When using the dual ported memory, all
                    457:     // send data must be moved to buffers allocated from the dual ported
                    458:     // memory.
                    459:     //
                    460: 
                    461:     if (TotalVirtualLength <= LANCE_SMALL_BUFFER_SIZE) {
                    462: 
                    463:         BufferSize = 1;
                    464: 
                    465:     } else if (TotalVirtualLength <= LANCE_MEDIUM_BUFFER_SIZE) {
                    466: 
                    467:         BufferSize = 2;
                    468: 
                    469:     } else {
                    470: 
                    471:         BufferSize = 3;
                    472: 
                    473:     }
                    474: 
                    475:     //
                    476:     // Find a buffer
                    477:     //
                    478:     for (
                    479:         i = BufferSize;
                    480:         i <= 3;
                    481:         i++
                    482:         ) {
                    483: 
                    484:         if ((LanceBuffersIndex = Adapter->LanceBufferListHeads[i]) != -1) {
                    485: 
                    486:             BufferDescriptor = Adapter->LanceBuffers + LanceBuffersIndex;
                    487:             Adapter->LanceBufferListHeads[i] = BufferDescriptor->Next;
                    488:             break;
                    489: 
                    490:         }
                    491: 
                    492:     }
                    493: 
                    494:     if (LanceBuffersIndex == -1) {
                    495: 
                    496:         //
                    497:         // Nothing available for the packet.
                    498:         //
                    499: 
                    500:         Adapter->StageOpen = FALSE;
                    501:         Adapter->AlreadyProcessingStage = FALSE;
                    502: 
                    503:         return;
                    504: 
                    505:     }
                    506: 
                    507:     //
                    508:     // We need to save in the packet which adapter buffere descriptor
                    509:     // it is using so that we can deallocate it later.  We also store
                    510:     // the number of buffers contained so that we can allocate ring
                    511:     // entries.
                    512:     //
                    513: 
                    514:     Reserved = PLANCE_RESERVED_FROM_PACKET(FirstPacket);
                    515: 
                    516:     Reserved->LanceBuffersIndex = LanceBuffersIndex;
                    517: 
                    518:     //
                    519:     // Now remove this packet from the queue
                    520:     //
                    521: 
                    522:     Adapter->FirstStage1Packet = Reserved->Next;
                    523: 
                    524:     if (Adapter->FirstStage1Packet == NULL) {
                    525: 
                    526:         Adapter->LastStage1Packet = NULL;
                    527: 
                    528:     }
                    529: 
                    530:     //
                    531:     // Save the list head index in the buffer descriptor
                    532:     // to permit easy deallocation later.
                    533:     //
                    534:     BufferDescriptor->Next = i;
                    535: 
                    536:     //
                    537:     // Now Acquire the ring
                    538:     //
                    539:     RingIndex = Adapter->AllocateableRing - Adapter->TransmitRing;
                    540: 
                    541:     //
                    542:     // Store the info
                    543:     //
                    544:     CurrentRingElement = Adapter->AllocateableRing;
                    545: 
                    546:     //
                    547:     // NOTE NOTE NOTE NOTE NOTE NOTE
                    548:     //
                    549:     // We can do the next calculation because we know that the number
                    550:     // or ring entries is a power of two!
                    551:     //
                    552: 
                    553:     Adapter->AllocateableRing = Adapter->TransmitRing +
                    554:             (((RingIndex) + 1) &
                    555:              (Adapter->NumberOfTransmitRings-1));
                    556: 
                    557:     Adapter->NumberOfAvailableRings--;
                    558: 
                    559:     //
                    560:     // Copy into buffer
                    561:     //
                    562:     CopyPacketIntoBuffer(Adapter, FirstPacket, BufferDescriptor);
                    563: 
                    564:     //
                    565:     // Get the position for mapping ring entries to packets.
                    566:     // We record the owning packet information in the ring packet packet
                    567:     // structure.
                    568:     //
                    569:     RingToPacket = Adapter->RingToPacket + RingIndex;
                    570:     RingToPacket->OwningPacket = FirstPacket;
                    571:     RingToPacket->LanceBuffersIndex = Reserved->LanceBuffersIndex;
                    572:     RingToPacket->RingIndex = RingIndex;
                    573: 
                    574:     //
                    575:     // Make sure that the ring descriptor is clean.
                    576:     //
                    577: 
                    578:     LANCE_ZERO_MEMORY_FOR_HARDWARE(CurrentRingElement,sizeof(LANCE_TRANSMIT_ENTRY));
                    579: 
                    580:     LANCE_SET_TRANSMIT_BUFFER_LENGTH(
                    581:         CurrentRingElement,
                    582:         BufferDescriptor->DataLength
                    583:         );
                    584: 
                    585: 
                    586:     LANCE_SET_TRANSMIT_BUFFER_ADDRESS(
                    587:             Adapter,
                    588:             CurrentRingElement,
                    589:             BufferDescriptor->VirtualLanceBuffer
                    590:             );
                    591: 
                    592:     LOG(TRANSMIT);
                    593: 
                    594:     //
                    595:     // We update the ring ownership of the last packet under
                    596:     // the protection of the lock so that the uncommitted packet
                    597:     // pointer can be updated before the transmit post processing
                    598:     // can examine it.
                    599:     //
                    600: 
                    601:     LANCE_SET_RING_BITS(
                    602:       CurrentRingElement->TransmitSummaryBits,
                    603:       LANCE_TRANSMIT_START_OF_PACKET |
                    604:       LANCE_TRANSMIT_OWNED_BY_CHIP |
                    605:       LANCE_TRANSMIT_END_OF_PACKET
                    606:       );
                    607: 
                    608: 
                    609:     if (RingIndex == (Adapter->NumberOfTransmitRings-1)) {
                    610: 
                    611:         Adapter->FirstUncommittedRing = Adapter->TransmitRing ;
                    612: 
                    613:     } else {
                    614: 
                    615:         Adapter->FirstUncommittedRing = Adapter->TransmitRing + RingIndex + 1;
                    616: 
                    617:     }
                    618: 
                    619:     //
                    620:     // Prod the chip into checking for packets to send.
                    621:     //
                    622: 
                    623:     PROD_TRANSMIT(Adapter);
                    624: 
                    625:     if (Adapter->LastFinishTransmit) {
                    626: 
                    627:         PLANCE_RESERVED LastReserved =
                    628:            PLANCE_RESERVED_FROM_PACKET(Adapter->LastFinishTransmit);
                    629: 
                    630:         LastReserved->Next = FirstPacket;
                    631: 
                    632:     }
                    633: 
                    634:     Reserved->Next = NULL;
                    635: 
                    636:     Adapter->LastFinishTransmit = FirstPacket;
                    637: 
                    638:     if (!Adapter->FirstFinishTransmit) {
                    639: 
                    640:         Adapter->FirstFinishTransmit = FirstPacket;
                    641: 
                    642:     }
                    643: 
                    644:     Adapter->AlreadyProcessingStage = FALSE;
                    645: 
                    646: }
                    647: 
                    648: 
                    649: VOID
                    650: CopyPacketIntoBuffer(
                    651:     IN PLANCE_ADAPTER Adapter,
                    652:     IN PNDIS_PACKET Packet,
                    653:     IN PLANCE_BUFFER_DESCRIPTOR BufferDescriptor
                    654:     )
                    655: 
                    656: /*++
                    657: 
                    658: Routine Description:
                    659: 
                    660:     Copy a packet down to the hardware.
                    661: 
                    662:     Note : MUST BE CALLED WITH LOCK HELD!
                    663: 
                    664: Arguments:
                    665: 
                    666:     Adapter - The adapter the packet is coming through.
                    667: 
                    668:     Packet - The packet whose buffers are to be copied.
                    669: 
                    670: Return Value:
                    671: 
                    672:     none
                    673: 
                    674: --*/
                    675: 
                    676: {
                    677:     //
                    678:     // Will point into the virtual address space addressed
                    679:     // by the adapter buffer if one was successfully allocated.
                    680:     //
                    681:     PCHAR CurrentDestination;
                    682: 
                    683:     //
                    684:     // Will hold the total amount of data copied to the
                    685:     // adapter buffer.
                    686:     //
                    687:     UINT TotalVirtualLength;
                    688: 
                    689:     //
                    690:     // Will point to the current source buffer.
                    691:     //
                    692:     PNDIS_BUFFER SourceBuffer;
                    693: 
                    694:     //
                    695:     // Points to the virtual address of the source buffers data.
                    696:     //
                    697:     PVOID SourceData;
                    698: 
                    699:     //
                    700:     // Will point to the number of bytes of data in the source
                    701:     // buffer.
                    702:     //
                    703:     UINT SourceLength;
                    704: 
                    705:     NdisReleaseSpinLock(&Adapter->Lock);
                    706: 
                    707:     //
                    708:     // Fill in the adapter buffer with the data from the users
                    709:     // buffers.
                    710:     //
                    711: 
                    712:     CurrentDestination = BufferDescriptor->VirtualLanceBuffer;
                    713: 
                    714:     NdisQueryPacket(
                    715:         Packet,
                    716:         NULL,
                    717:         NULL,
                    718:         &SourceBuffer,
                    719:         &TotalVirtualLength
                    720:         );
                    721: 
                    722:     while ( SourceBuffer != NULL ) {
                    723: 
                    724:         NdisQueryBuffer(
                    725:                 SourceBuffer,
                    726:                 &SourceData,
                    727:                 &SourceLength
                    728:                 );
                    729: 
                    730:         LANCE_MOVE_MEMORY_TO_HARDWARE(
                    731:             CurrentDestination,
                    732:             SourceData,
                    733:             SourceLength
                    734:             );
                    735: 
                    736:         CurrentDestination = (PCHAR)CurrentDestination + SourceLength;
                    737: 
                    738:         NdisGetNextBuffer(
                    739:                 SourceBuffer,
                    740:                 &SourceBuffer
                    741:                 );
                    742: 
                    743:     }
                    744: 
                    745:     //
                    746:     // If the packet is less then the minimum size then we
                    747:     // need to zero out the rest of the packet.
                    748:     //
                    749: 
                    750:     if (TotalVirtualLength < MIN_SINGLE_BUFFER) {
                    751: 
                    752:         LANCE_ZERO_MEMORY_FOR_HARDWARE(
                    753:             CurrentDestination,
                    754:             MIN_SINGLE_BUFFER - TotalVirtualLength
                    755:             );
                    756: 
                    757:         BufferDescriptor->DataLength = MIN_SINGLE_BUFFER;
                    758: 
                    759:     } else {
                    760: 
                    761:         BufferDescriptor->DataLength = TotalVirtualLength;
                    762: 
                    763:     }
                    764: 
                    765:     NdisAcquireSpinLock(&Adapter->Lock);
                    766: 
                    767:     return;
                    768: }
                    769: 

unix.superglobalmegacorp.com

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