Annotation of ntddk/src/network/tdi/stndis.c, revision 1.1.1.1

1.1       root        1: /*++
                      2: 
                      3: Copyright (c) 1989-1993  Microsoft Corporation
                      4: 
                      5: Module Name:
                      6: 
                      7:     stndis.c
                      8: 
                      9: Abstract:
                     10: 
                     11:     This module contains code which implements the routines used to interface
                     12:     ST and NDIS. All callback routines (except for Transfer Data,
                     13:     Send Complete, and ReceiveIndication) are here, as well as those routines
                     14:     called to initialize NDIS.
                     15: 
                     16: Environment:
                     17: 
                     18:     Kernel mode
                     19: 
                     20: --*/
                     21: 
                     22: #include "st.h"
                     23: 
                     24: 
                     25: //
                     26: // This is a one-per-driver variable used in binding
                     27: // to the NDIS interface.
                     28: //
                     29: 
                     30: NDIS_HANDLE StNdisProtocolHandle = (NDIS_HANDLE)NULL;
                     31: 
                     32: NDIS_STATUS
                     33: StSubmitNdisRequest(
                     34:     IN PDEVICE_CONTEXT DeviceContext,
                     35:     IN PNDIS_REQUEST NdisRequest,
                     36:     IN PNDIS_STRING AdapterString
                     37:     );
                     38: 
                     39: #ifdef ALLOC_PRAGMA
                     40: #pragma alloc_text(init,StRegisterProtocol)
                     41: #pragma alloc_text(init,StSubmitNdisRequest)
                     42: #pragma alloc_text(init,StInitializeNdis)
                     43: #endif
                     44: 
                     45: 
                     46: NTSTATUS
                     47: StRegisterProtocol (
                     48:     IN STRING *NameString
                     49:     )
                     50: 
                     51: /*++
                     52: 
                     53: Routine Description:
                     54: 
                     55:     This routine introduces this transport to the NDIS interface.
                     56: 
                     57: Arguments:
                     58: 
                     59:     Irp - Pointer to the request packet representing the I/O request.
                     60: 
                     61: Return Value:
                     62: 
                     63:     The function value is the status of the operation.
                     64:     STATUS_SUCCESS if all goes well,
                     65:     Failure status if we tried to register and couldn't,
                     66:     STATUS_INSUFFICIENT_RESOURCES if we couldn't even try to register.
                     67: 
                     68: --*/
                     69: 
                     70: {
                     71:     NDIS_STATUS ndisStatus;
                     72: 
                     73:     NDIS_PROTOCOL_CHARACTERISTICS ProtChars;    // Used temporarily to register
                     74: 
                     75: 
                     76:     //
                     77:     // Set up the characteristics of this protocol
                     78:     //
                     79: 
                     80:     ProtChars.MajorNdisVersion = 3;
                     81:     ProtChars.MinorNdisVersion = 0;
                     82: 
                     83:     ProtChars.Name.Length = NameString->Length;
                     84:     ProtChars.Name.Buffer = (PVOID)NameString->Buffer;
                     85: 
                     86:     ProtChars.OpenAdapterCompleteHandler = StOpenAdapterComplete;
                     87:     ProtChars.CloseAdapterCompleteHandler = StCloseAdapterComplete;
                     88:     ProtChars.ResetCompleteHandler = StResetComplete;
                     89:     ProtChars.RequestCompleteHandler = StRequestComplete;
                     90: 
                     91:     ProtChars.SendCompleteHandler = StSendCompletionHandler;
                     92:     ProtChars.TransferDataCompleteHandler = StTransferDataComplete;
                     93: 
                     94:     ProtChars.ReceiveHandler = StReceiveIndication;
                     95:     ProtChars.ReceiveCompleteHandler = StReceiveComplete;
                     96:     ProtChars.StatusHandler = StStatusIndication;
                     97:     ProtChars.StatusCompleteHandler = StStatusComplete;
                     98: 
                     99:     NdisRegisterProtocol (
                    100:         &ndisStatus,
                    101:         &StNdisProtocolHandle,
                    102:         &ProtChars,
                    103:         (UINT)sizeof(NDIS_PROTOCOL_CHARACTERISTICS) + NameString->Length);
                    104: 
                    105:     if (ndisStatus != NDIS_STATUS_SUCCESS) {
                    106:         return (NTSTATUS)ndisStatus;
                    107:     }
                    108: 
                    109:     return STATUS_SUCCESS;
                    110: }
                    111: 
                    112: 
                    113: VOID
                    114: StDeregisterProtocol (
                    115:     VOID
                    116:     )
                    117: 
                    118: /*++
                    119: 
                    120: Routine Description:
                    121: 
                    122:     This routine removes this transport to the NDIS interface.
                    123: 
                    124: Arguments:
                    125: 
                    126:     None.
                    127: 
                    128: Return Value:
                    129: 
                    130:     None.
                    131: 
                    132: --*/
                    133: 
                    134: {
                    135:     NDIS_STATUS ndisStatus;
                    136: 
                    137:     if (StNdisProtocolHandle != (NDIS_HANDLE)NULL) {
                    138:         NdisDeregisterProtocol (
                    139:             &ndisStatus,
                    140:             StNdisProtocolHandle);
                    141:         StNdisProtocolHandle = (NDIS_HANDLE)NULL;
                    142:     }
                    143: }
                    144: 
                    145: 
                    146: NDIS_STATUS
                    147: StSubmitNdisRequest(
                    148:     IN PDEVICE_CONTEXT DeviceContext,
                    149:     IN PNDIS_REQUEST NdisRequest,
                    150:     IN PNDIS_STRING AdapterString
                    151:     )
                    152: 
                    153: /*++
                    154: 
                    155: Routine Description:
                    156: 
                    157:     This routine passed an NDIS_REQUEST to the MAC and waits
                    158:     until it has completed before returning the final status.
                    159: 
                    160: Arguments:
                    161: 
                    162:     DeviceContext - Pointer to the device context for this driver.
                    163: 
                    164:     NdisRequest - Pointer to the NDIS_REQUEST to submit.
                    165: 
                    166:     AdapterString - The name of the adapter, in case an error needs
                    167:         to be logged.
                    168: 
                    169: Return Value:
                    170: 
                    171:     The function value is the status of the operation.
                    172: 
                    173: --*/
                    174: {
                    175:     NDIS_STATUS NdisStatus;
                    176: 
                    177:     NdisRequest(
                    178:         &NdisStatus,
                    179:         DeviceContext->NdisBindingHandle,
                    180:         NdisRequest);
                    181: 
                    182:     if (NdisStatus == NDIS_STATUS_PENDING) {
                    183: 
                    184:         //
                    185:         // The completion routine will set NdisRequestStatus.
                    186:         //
                    187: 
                    188:         KeWaitForSingleObject(
                    189:             &DeviceContext->NdisRequestEvent,
                    190:             Executive,
                    191:             KernelMode,
                    192:             TRUE,
                    193:             (PLARGE_INTEGER)NULL
                    194:             );
                    195: 
                    196:         NdisStatus = DeviceContext->NdisRequestStatus;
                    197: 
                    198:         KeResetEvent(
                    199:             &DeviceContext->NdisRequestEvent
                    200:             );
                    201: 
                    202:     }
                    203: 
                    204:     if (NdisStatus != NDIS_STATUS_SUCCESS) {
                    205: 
                    206:         StWriteOidErrorLog(
                    207:             DeviceContext,
                    208:             NdisRequest->RequestType == NdisRequestSetInformation ?
                    209:                 EVENT_TRANSPORT_SET_OID_FAILED : EVENT_TRANSPORT_QUERY_OID_FAILED,
                    210:             NdisStatus,
                    211:             AdapterString->Buffer,
                    212:             NdisRequest->DATA.QUERY_INFORMATION.Oid);
                    213:     }
                    214: 
                    215:     return NdisStatus;
                    216: }
                    217: 
                    218: 
                    219: NTSTATUS
                    220: StInitializeNdis (
                    221:     IN PDEVICE_CONTEXT DeviceContext,
                    222:     IN PCONFIG_DATA StConfig,
                    223:     IN UINT ConfigInfoNameIndex
                    224:     )
                    225: 
                    226: /*++
                    227: 
                    228: Routine Description:
                    229: 
                    230:     This routine introduces this transport to the NDIS interface and sets up
                    231:     any necessary NDIS data structures (Buffer pools and such). It will be
                    232:     called for each adapter opened by this transport.
                    233: 
                    234: Arguments:
                    235: 
                    236:     DeviceObject - Pointer to the device object for this driver.
                    237: 
                    238:     Irp - Pointer to the request packet representing the I/O request.
                    239: 
                    240: Return Value:
                    241: 
                    242:     The function value is the status of the operation.
                    243: 
                    244: --*/
                    245: {
                    246:     ULONG SendPacketReservedLength;
                    247:     ULONG ReceivePacketReservedLen;
                    248:     ULONG SendPacketPoolSize;
                    249:     ULONG ReceivePacketPoolSize;
                    250:     NDIS_STATUS NdisStatus;
                    251:     NDIS_STATUS OpenErrorStatus;
                    252:     NDIS_MEDIUM StSupportedMedia[] = { NdisMedium802_3, NdisMedium802_5, NdisMediumFddi };
                    253:     UINT SelectedMedium;
                    254:     NDIS_REQUEST StRequest;
                    255:     UCHAR StDataBuffer[6];
                    256:     NDIS_OID StOid;
                    257:     ULONG MinimumLookahead = 128 + sizeof(ST_HEADER);
                    258:     ULONG ProtocolOptions, MacOptions;
                    259:     PNDIS_STRING AdapterString;
                    260: 
                    261:     //
                    262:     // Initialize this adapter for ST use through NDIS
                    263:     //
                    264: 
                    265:     //
                    266:     // This event is used in case any of the NDIS requests
                    267:     // pend; we wait until it is set by the completion
                    268:     // routine, which also sets NdisRequestStatus.
                    269:     //
                    270: 
                    271:     KeInitializeEvent(
                    272:         &DeviceContext->NdisRequestEvent,
                    273:         NotificationEvent,
                    274:         FALSE
                    275:     );
                    276: 
                    277:     DeviceContext->NdisBindingHandle = NULL;
                    278:     AdapterString = (PNDIS_STRING)&StConfig->Names[ConfigInfoNameIndex];
                    279: 
                    280:     NdisOpenAdapter (
                    281:         &NdisStatus,
                    282:         &OpenErrorStatus,
                    283:         &DeviceContext->NdisBindingHandle,
                    284:         &SelectedMedium,
                    285:         StSupportedMedia,
                    286:         sizeof (StSupportedMedia) / sizeof(NDIS_MEDIUM),
                    287:         StNdisProtocolHandle,
                    288:         (NDIS_HANDLE)DeviceContext,
                    289:         AdapterString,
                    290:         0,
                    291:         NULL);
                    292: 
                    293:     if (NdisStatus == NDIS_STATUS_PENDING) {
                    294: 
                    295:         //
                    296:         // The completion routine will set NdisRequestStatus.
                    297:         //
                    298: 
                    299:         KeWaitForSingleObject(
                    300:             &DeviceContext->NdisRequestEvent,
                    301:             Executive,
                    302:             KernelMode,
                    303:             TRUE,
                    304:             (PLARGE_INTEGER)NULL
                    305:             );
                    306: 
                    307:         NdisStatus = DeviceContext->NdisRequestStatus;
                    308: 
                    309:         KeResetEvent(
                    310:             &DeviceContext->NdisRequestEvent
                    311:             );
                    312: 
                    313:     }
                    314: 
                    315:     if (NdisStatus != NDIS_STATUS_SUCCESS) {
                    316: 
                    317:         StWriteGeneralErrorLog(
                    318:             DeviceContext,
                    319:             EVENT_TRANSPORT_ADAPTER_NOT_FOUND,
                    320:             807,
                    321:             NdisStatus,
                    322:             AdapterString->Buffer,
                    323:             0,
                    324:             NULL);
                    325:         return STATUS_INSUFFICIENT_RESOURCES;
                    326:     }
                    327: 
                    328: 
                    329:     //
                    330:     // Get the information we need about the adapter, based on
                    331:     // the media type.
                    332:     //
                    333: 
                    334:     MacInitializeMacInfo(
                    335:         StSupportedMedia[SelectedMedium],
                    336:         &DeviceContext->MacInfo);
                    337: 
                    338: 
                    339:     //
                    340:     // Set the multicast/functional addresses first so we avoid windows where we
                    341:     // receive only part of the addresses.
                    342:     //
                    343: 
                    344:     MacSetMulticastAddress (
                    345:             DeviceContext->MacInfo.MediumType,
                    346:             DeviceContext->MulticastAddress.Address);
                    347: 
                    348: 
                    349:     switch (DeviceContext->MacInfo.MediumType) {
                    350: 
                    351:     case NdisMedium802_3:
                    352: 
                    353:         //
                    354:         // Fill in the data for our multicast list.
                    355:         //
                    356: 
                    357:         RtlCopyMemory(StDataBuffer, DeviceContext->MulticastAddress.Address, 6);
                    358: 
                    359:         //
                    360:         // Now fill in the NDIS_REQUEST.
                    361:         //
                    362: 
                    363:         StRequest.RequestType = NdisRequestSetInformation;
                    364:         StRequest.DATA.SET_INFORMATION.Oid = OID_802_3_MULTICAST_LIST;
                    365:         StRequest.DATA.SET_INFORMATION.InformationBuffer = &StDataBuffer;
                    366:         StRequest.DATA.SET_INFORMATION.InformationBufferLength = 6;
                    367: 
                    368:         break;
                    369: 
                    370:     case NdisMedium802_5:
                    371: 
                    372:         //
                    373:         // For token-ring, we pass the last four bytes of the
                    374:         // Netbios functional address.
                    375:         //
                    376: 
                    377:         //
                    378:         // Fill in the data for our functional address.
                    379:         //
                    380: 
                    381:         RtlCopyMemory(StDataBuffer, ((PUCHAR)(DeviceContext->MulticastAddress.Address)) + 2, 4);
                    382: 
                    383:         //
                    384:         // Now fill in the NDIS_REQUEST.
                    385:         //
                    386: 
                    387:         StRequest.RequestType = NdisRequestSetInformation;
                    388:         StRequest.DATA.SET_INFORMATION.Oid = OID_802_5_CURRENT_FUNCTIONAL;
                    389:         StRequest.DATA.SET_INFORMATION.InformationBuffer = &StDataBuffer;
                    390:         StRequest.DATA.SET_INFORMATION.InformationBufferLength = 4;
                    391: 
                    392:         break;
                    393: 
                    394:     case NdisMediumFddi:
                    395: 
                    396:         //
                    397:         // Fill in the data for our multicast list.
                    398:         //
                    399: 
                    400:         RtlCopyMemory(StDataBuffer, DeviceContext->MulticastAddress.Address, 6);
                    401: 
                    402:         //
                    403:         // Now fill in the NDIS_REQUEST.
                    404:         //
                    405: 
                    406:         StRequest.RequestType = NdisRequestSetInformation;
                    407:         StRequest.DATA.SET_INFORMATION.Oid = OID_FDDI_LONG_MULTICAST_LIST;
                    408:         StRequest.DATA.SET_INFORMATION.InformationBuffer = &StDataBuffer;
                    409:         StRequest.DATA.SET_INFORMATION.InformationBufferLength = 6;
                    410: 
                    411:         break;
                    412: 
                    413:     }
                    414: 
                    415:     NdisStatus = StSubmitNdisRequest (DeviceContext, &StRequest, AdapterString);
                    416: 
                    417:     if (NdisStatus != NDIS_STATUS_SUCCESS) {
                    418:         StCloseNdis (DeviceContext);
                    419:         return STATUS_INSUFFICIENT_RESOURCES;
                    420:     }
                    421: 
                    422: 
                    423: 
                    424:     switch (DeviceContext->MacInfo.MediumType) {
                    425: 
                    426:     case NdisMedium802_3:
                    427: 
                    428:         StOid = OID_802_3_CURRENT_ADDRESS;
                    429:         break;
                    430: 
                    431:     case NdisMedium802_5:
                    432: 
                    433:         StOid = OID_802_5_CURRENT_ADDRESS;
                    434:         break;
                    435: 
                    436:     case NdisMediumFddi:
                    437: 
                    438:         StOid = OID_FDDI_LONG_CURRENT_ADDR;
                    439:         break;
                    440: 
                    441:     default:
                    442: 
                    443:         NdisStatus = NDIS_STATUS_FAILURE;
                    444:         break;
                    445: 
                    446:     }
                    447: 
                    448:     StRequest.RequestType = NdisRequestQueryInformation;
                    449:     StRequest.DATA.QUERY_INFORMATION.Oid = StOid;
                    450:     StRequest.DATA.QUERY_INFORMATION.InformationBuffer = DeviceContext->LocalAddress.Address;
                    451:     StRequest.DATA.QUERY_INFORMATION.InformationBufferLength = 6;
                    452: 
                    453:     NdisStatus = StSubmitNdisRequest (DeviceContext, &StRequest, AdapterString);
                    454: 
                    455:     if (NdisStatus != NDIS_STATUS_SUCCESS) {
                    456:         StCloseNdis (DeviceContext);
                    457:         return STATUS_INSUFFICIENT_RESOURCES;
                    458:     }
                    459: 
                    460:     //
                    461:     // Set up the reserved Netbios address.
                    462:     //
                    463: 
                    464:     RtlZeroMemory(DeviceContext->ReservedNetBIOSAddress, 10);
                    465:     RtlCopyMemory(&DeviceContext->ReservedNetBIOSAddress[10], DeviceContext->LocalAddress.Address, 6);
                    466: 
                    467: 
                    468:     //
                    469:     // Now query the maximum packet sizes.
                    470:     //
                    471: 
                    472:     StRequest.RequestType = NdisRequestQueryInformation;
                    473:     StRequest.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_FRAME_SIZE;
                    474:     StRequest.DATA.QUERY_INFORMATION.InformationBuffer = &(DeviceContext->MaxReceivePacketSize);
                    475:     StRequest.DATA.QUERY_INFORMATION.InformationBufferLength = 4;
                    476: 
                    477:     NdisStatus = StSubmitNdisRequest (DeviceContext, &StRequest, AdapterString);
                    478: 
                    479:     if (NdisStatus != NDIS_STATUS_SUCCESS) {
                    480:         StCloseNdis (DeviceContext);
                    481:         return STATUS_INSUFFICIENT_RESOURCES;
                    482:     }
                    483: 
                    484: 
                    485:     StRequest.RequestType = NdisRequestQueryInformation;
                    486:     StRequest.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAXIMUM_TOTAL_SIZE;
                    487:     StRequest.DATA.QUERY_INFORMATION.InformationBuffer = &(DeviceContext->MaxSendPacketSize);
                    488:     StRequest.DATA.QUERY_INFORMATION.InformationBufferLength = 4;
                    489: 
                    490:     NdisStatus = StSubmitNdisRequest (DeviceContext, &StRequest, AdapterString);
                    491: 
                    492:     if (NdisStatus != NDIS_STATUS_SUCCESS) {
                    493:         StCloseNdis (DeviceContext);
                    494:         return STATUS_INSUFFICIENT_RESOURCES;
                    495:     }
                    496: 
                    497: 
                    498:     //
                    499:     // Now set the minimum lookahead size.
                    500:     //
                    501: 
                    502:     StRequest.RequestType = NdisRequestSetInformation;
                    503:     StRequest.DATA.QUERY_INFORMATION.Oid = OID_GEN_CURRENT_LOOKAHEAD;
                    504:     StRequest.DATA.QUERY_INFORMATION.InformationBuffer = &MinimumLookahead;
                    505:     StRequest.DATA.QUERY_INFORMATION.InformationBufferLength = 4;
                    506: 
                    507:     NdisStatus = StSubmitNdisRequest (DeviceContext, &StRequest, AdapterString);
                    508: 
                    509:     if (NdisStatus != NDIS_STATUS_SUCCESS) {
                    510:         StCloseNdis (DeviceContext);
                    511:         return STATUS_INSUFFICIENT_RESOURCES;
                    512:     }
                    513: 
                    514: 
                    515:     //
                    516:     // Now query the link speed
                    517:     //
                    518: 
                    519:     StRequest.RequestType = NdisRequestQueryInformation;
                    520:     StRequest.DATA.QUERY_INFORMATION.Oid = OID_GEN_LINK_SPEED;
                    521:     StRequest.DATA.QUERY_INFORMATION.InformationBuffer = &(DeviceContext->MediumSpeed);
                    522:     StRequest.DATA.QUERY_INFORMATION.InformationBufferLength = 4;
                    523: 
                    524:     NdisStatus = StSubmitNdisRequest (DeviceContext, &StRequest, AdapterString);
                    525: 
                    526:     if (NdisStatus != NDIS_STATUS_SUCCESS) {
                    527:         StCloseNdis (DeviceContext);
                    528:         return STATUS_INSUFFICIENT_RESOURCES;
                    529:     }
                    530: 
                    531: 
                    532:     //
                    533:     // Now query the MAC's optional characteristics.
                    534:     //
                    535: 
                    536:     StRequest.RequestType = NdisRequestQueryInformation;
                    537:     StRequest.DATA.QUERY_INFORMATION.Oid = OID_GEN_MAC_OPTIONS;
                    538:     StRequest.DATA.QUERY_INFORMATION.InformationBuffer = &MacOptions;
                    539:     StRequest.DATA.QUERY_INFORMATION.InformationBufferLength = 4;
                    540: 
                    541:     NdisStatus = StSubmitNdisRequest (DeviceContext, &StRequest, AdapterString);
                    542: 
                    543:     if (NdisStatus != NDIS_STATUS_SUCCESS) {
                    544:         StCloseNdis (DeviceContext);
                    545:         return STATUS_INSUFFICIENT_RESOURCES;
                    546:     }
                    547: 
                    548:     //
                    549:     // Since the sample transport does not try to optimize for the
                    550:     // cases where transfer data is always synchronous or indications
                    551:     // are not reentered, we ignore those bits in MacOptions.
                    552:     //
                    553: 
                    554:     DeviceContext->MacInfo.CopyLookahead =
                    555:         (BOOLEAN)((MacOptions & NDIS_MAC_OPTION_COPY_LOOKAHEAD_DATA) != 0);
                    556: 
                    557: 
                    558:     //
                    559:     // Now set our options if needed. We can only support
                    560:     // partial indications if running over 802.3 where the
                    561:     // real packet length can be obtained from the header.
                    562:     //
                    563: 
                    564:     if (DeviceContext->MacInfo.MediumType == NdisMedium802_3) {
                    565: 
                    566:         ProtocolOptions = NDIS_PROT_OPTION_ESTIMATED_LENGTH;
                    567: 
                    568:         StRequest.RequestType = NdisRequestSetInformation;
                    569:         StRequest.DATA.QUERY_INFORMATION.Oid = OID_GEN_PROTOCOL_OPTIONS;
                    570:         StRequest.DATA.QUERY_INFORMATION.InformationBuffer = &ProtocolOptions;
                    571:         StRequest.DATA.QUERY_INFORMATION.InformationBufferLength = 4;
                    572: 
                    573:         NdisStatus = StSubmitNdisRequest (DeviceContext, &StRequest, AdapterString);
                    574: 
                    575:         if (NdisStatus != NDIS_STATUS_SUCCESS) {
                    576:             StCloseNdis (DeviceContext);
                    577:             return STATUS_INSUFFICIENT_RESOURCES;
                    578:         }
                    579: 
                    580:     }
                    581: 
                    582: 
                    583:     //
                    584:     // Calculate the NDIS-related stuff.
                    585:     //
                    586: 
                    587:     SendPacketReservedLength = sizeof (SEND_PACKET_TAG);
                    588:     ReceivePacketReservedLen = sizeof (RECEIVE_PACKET_TAG);
                    589: 
                    590:     //
                    591:     // The send packet pool is used for UI frames and regular packets.
                    592:     //
                    593: 
                    594:     SendPacketPoolSize = StConfig->SendPacketPoolSize;
                    595: 
                    596:     //
                    597:     // The receive packet pool is used in transfer data.
                    598:     //
                    599: 
                    600:     ReceivePacketPoolSize = StConfig->ReceivePacketPoolSize;
                    601: 
                    602: 
                    603:     NdisAllocatePacketPool (
                    604:         &NdisStatus,
                    605:         &DeviceContext->SendPacketPoolHandle,
                    606:         SendPacketPoolSize,
                    607:         SendPacketReservedLength);
                    608: 
                    609:     if (NdisStatus != NDIS_STATUS_SUCCESS) {
                    610:         DeviceContext->SendPacketPoolHandle = NULL;
                    611:         StCloseNdis (DeviceContext);
                    612:         return STATUS_INSUFFICIENT_RESOURCES;
                    613:     }
                    614: 
                    615:     DeviceContext->MemoryUsage +=
                    616:         (SendPacketPoolSize *
                    617:          (sizeof(NDIS_PACKET) + SendPacketReservedLength));
                    618: 
                    619: 
                    620:     NdisAllocatePacketPool(
                    621:         &NdisStatus,
                    622:         &DeviceContext->ReceivePacketPoolHandle,
                    623:         ReceivePacketPoolSize,
                    624:         ReceivePacketReservedLen);
                    625: 
                    626:     if (NdisStatus != NDIS_STATUS_SUCCESS) {
                    627:         DeviceContext->ReceivePacketPoolHandle = NULL;
                    628:         StCloseNdis (DeviceContext);
                    629:         return STATUS_INSUFFICIENT_RESOURCES;
                    630:     }
                    631: 
                    632:     DeviceContext->MemoryUsage +=
                    633:         (ReceivePacketPoolSize *
                    634:          (sizeof(NDIS_PACKET) + ReceivePacketReservedLen));
                    635: 
                    636: 
                    637:     //
                    638:     // Allocate the buffer pool; as an estimate, allocate
                    639:     // one per send or receive packet.
                    640:     //
                    641: 
                    642:     NdisAllocateBufferPool (
                    643:         &NdisStatus,
                    644:         &DeviceContext->NdisBufferPoolHandle,
                    645:         SendPacketPoolSize + ReceivePacketPoolSize);
                    646: 
                    647:     if (NdisStatus != NDIS_STATUS_SUCCESS) {
                    648:         DeviceContext->NdisBufferPoolHandle = NULL;
                    649:         StCloseNdis (DeviceContext);
                    650:         return STATUS_INSUFFICIENT_RESOURCES;
                    651:     }
                    652: 
                    653: 
                    654:     //
                    655:     // Now that everything is set up, we enable the filter
                    656:     // for packet reception.
                    657:     //
                    658: 
                    659:     //
                    660:     // Fill in the OVB for packet filter.
                    661:     //
                    662: 
                    663:     switch (DeviceContext->MacInfo.MediumType) {
                    664: 
                    665:     case NdisMedium802_3:
                    666:     case NdisMediumFddi:
                    667: 
                    668:         RtlStoreUlong((PULONG)StDataBuffer,
                    669:             (NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_MULTICAST));
                    670:         break;
                    671: 
                    672:     case NdisMedium802_5:
                    673: 
                    674:         RtlStoreUlong((PULONG)StDataBuffer,
                    675:             (NDIS_PACKET_TYPE_DIRECTED | NDIS_PACKET_TYPE_FUNCTIONAL));
                    676:         break;
                    677: 
                    678:     default:
                    679: 
                    680:         ASSERT (FALSE);
                    681:         break;
                    682: 
                    683:     }
                    684: 
                    685:     //
                    686:     // Now fill in the NDIS_REQUEST.
                    687:     //
                    688: 
                    689:     StRequest.RequestType = NdisRequestSetInformation;
                    690:     StRequest.DATA.SET_INFORMATION.Oid = OID_GEN_CURRENT_PACKET_FILTER;
                    691:     StRequest.DATA.SET_INFORMATION.InformationBuffer = &StDataBuffer;
                    692:     StRequest.DATA.SET_INFORMATION.InformationBufferLength = sizeof(ULONG);
                    693: 
                    694:     NdisStatus = StSubmitNdisRequest (DeviceContext, &StRequest, AdapterString);
                    695: 
                    696:     if (NdisStatus != NDIS_STATUS_SUCCESS) {
                    697:         StCloseNdis (DeviceContext);
                    698:         return STATUS_INSUFFICIENT_RESOURCES;
                    699:     }
                    700: 
                    701: 
                    702:     return STATUS_SUCCESS;
                    703: 
                    704: }   /* StInitializeNdis */
                    705: 
                    706: 
                    707: VOID
                    708: StCloseNdis (
                    709:     IN PDEVICE_CONTEXT DeviceContext
                    710:     )
                    711: 
                    712: /*++
                    713: 
                    714: Routine Description:
                    715: 
                    716:     This routine unbinds the transport from the NDIS interface and does
                    717:     any other work required to undo what was done in StInitializeNdis.
                    718:     It is written so that it can be called from within StInitializeNdis
                    719:     if it fails partway through.
                    720: 
                    721: Arguments:
                    722: 
                    723:     DeviceObject - Pointer to the device object for this driver.
                    724: 
                    725: Return Value:
                    726: 
                    727:     The function value is the status of the operation.
                    728: 
                    729: --*/
                    730: {
                    731:     NDIS_STATUS ndisStatus;
                    732: 
                    733:     //
                    734:     // Close the NDIS binding.
                    735:     //
                    736: 
                    737:     if (DeviceContext->NdisBindingHandle != (NDIS_HANDLE)NULL) {
                    738: 
                    739:         //
                    740:         // This event is used in case any of the NDIS requests
                    741:         // pend; we wait until it is set by the completion
                    742:         // routine, which also sets NdisRequestStatus.
                    743:         //
                    744: 
                    745:         KeInitializeEvent(
                    746:             &DeviceContext->NdisRequestEvent,
                    747:             NotificationEvent,
                    748:             FALSE
                    749:         );
                    750: 
                    751:         NdisCloseAdapter(
                    752:             &ndisStatus,
                    753:             DeviceContext->NdisBindingHandle);
                    754: 
                    755:         if (ndisStatus == NDIS_STATUS_PENDING) {
                    756: 
                    757:             //
                    758:             // The completion routine will set NdisRequestStatus.
                    759:             //
                    760: 
                    761:             KeWaitForSingleObject(
                    762:                 &DeviceContext->NdisRequestEvent,
                    763:                 Executive,
                    764:                 KernelMode,
                    765:                 TRUE,
                    766:                 (PLARGE_INTEGER)NULL
                    767:                 );
                    768: 
                    769:             ndisStatus = DeviceContext->NdisRequestStatus;
                    770: 
                    771:             KeResetEvent(
                    772:                 &DeviceContext->NdisRequestEvent
                    773:                 );
                    774: 
                    775:         }
                    776: 
                    777:         //
                    778:         // We ignore ndisStatus.
                    779:         //
                    780: 
                    781:     }
                    782: 
                    783:     if (DeviceContext->SendPacketPoolHandle != NULL) {
                    784:         NdisFreePacketPool (DeviceContext->SendPacketPoolHandle);
                    785:     }
                    786: 
                    787:     if (DeviceContext->ReceivePacketPoolHandle != NULL) {
                    788:         NdisFreePacketPool (DeviceContext->ReceivePacketPoolHandle);
                    789:     }
                    790: 
                    791:     if (DeviceContext->NdisBufferPoolHandle != NULL) {
                    792:         NdisFreeBufferPool (DeviceContext->NdisBufferPoolHandle);
                    793:     }
                    794: 
                    795: }   /* StCloseNdis */
                    796: 
                    797: 
                    798: VOID
                    799: StOpenAdapterComplete (
                    800:     IN NDIS_HANDLE BindingContext,
                    801:     IN NDIS_STATUS NdisStatus,
                    802:     IN NDIS_STATUS OpenErrorStatus
                    803:     )
                    804: 
                    805: /*++
                    806: 
                    807: Routine Description:
                    808: 
                    809:     This routine is called by NDIS to indicate that an open adapter
                    810:     is complete. Since we only ever have one outstanding, and then only
                    811:     during initialization, all we do is record the status and set
                    812:     the event to signalled to unblock the initialization thread.
                    813: 
                    814: Arguments:
                    815: 
                    816:     BindingContext - Pointer to the device object for this driver.
                    817: 
                    818:     NdisStatus - The request completion code.
                    819: 
                    820:     OpenErrorStatus - More status information.
                    821: 
                    822: Return Value:
                    823: 
                    824:     None.
                    825: 
                    826: --*/
                    827: 
                    828: {
                    829:     PDEVICE_CONTEXT DeviceContext = (PDEVICE_CONTEXT)BindingContext;
                    830: 
                    831:     DeviceContext->NdisRequestStatus = NdisStatus;
                    832:     KeSetEvent(
                    833:         &DeviceContext->NdisRequestEvent,
                    834:         0L,
                    835:         FALSE);
                    836: 
                    837:     return;
                    838: }
                    839: 
                    840: VOID
                    841: StCloseAdapterComplete (
                    842:     IN NDIS_HANDLE BindingContext,
                    843:     IN NDIS_STATUS NdisStatus
                    844:     )
                    845: 
                    846: /*++
                    847: 
                    848: Routine Description:
                    849: 
                    850:     This routine is called by NDIS to indicate that a close adapter
                    851:     is complete. Currently we don't close adapters, so this is not
                    852:     a problem.
                    853: 
                    854: Arguments:
                    855: 
                    856:     BindingContext - Pointer to the device object for this driver.
                    857: 
                    858:     NdisStatus - The request completion code.
                    859: 
                    860: Return Value:
                    861: 
                    862:     None.
                    863: 
                    864: --*/
                    865: 
                    866: {
                    867:     PDEVICE_CONTEXT DeviceContext = (PDEVICE_CONTEXT)BindingContext;
                    868: 
                    869:     DeviceContext->NdisRequestStatus = NdisStatus;
                    870:     KeSetEvent(
                    871:         &DeviceContext->NdisRequestEvent,
                    872:         0L,
                    873:         FALSE);
                    874: 
                    875:     return;
                    876: }
                    877: 
                    878: VOID
                    879: StResetComplete (
                    880:     IN NDIS_HANDLE BindingContext,
                    881:     IN NDIS_STATUS NdisStatus
                    882:     )
                    883: 
                    884: /*++
                    885: 
                    886: Routine Description:
                    887: 
                    888:     This routine is called by NDIS to indicate that a reset adapter
                    889:     is complete. Currently we don't reset adapters, so this is not
                    890:     a problem.
                    891: 
                    892: Arguments:
                    893: 
                    894:     BindingContext - Pointer to the device object for this driver.
                    895: 
                    896:     NdisStatus - The request completion code.
                    897: 
                    898: Return Value:
                    899: 
                    900:     None.
                    901: 
                    902: --*/
                    903: 
                    904: {
                    905:     UNREFERENCED_PARAMETER(BindingContext);
                    906:     UNREFERENCED_PARAMETER(NdisStatus);
                    907: 
                    908:     return;
                    909: }
                    910: 
                    911: VOID
                    912: StRequestComplete (
                    913:     IN NDIS_HANDLE BindingContext,
                    914:     IN PNDIS_REQUEST NdisRequest,
                    915:     IN NDIS_STATUS NdisStatus
                    916:     )
                    917: 
                    918: /*++
                    919: 
                    920: Routine Description:
                    921: 
                    922:     This routine is called by NDIS to indicate that a request is complete.
                    923:     Since we only ever have one request outstanding, and then only
                    924:     during initialization, all we do is record the status and set
                    925:     the event to signalled to unblock the initialization thread.
                    926: 
                    927: Arguments:
                    928: 
                    929:     BindingContext - Pointer to the device object for this driver.
                    930: 
                    931:     NdisRequest - The object describing the request.
                    932: 
                    933:     NdisStatus - The request completion code.
                    934: 
                    935: Return Value:
                    936: 
                    937:     None.
                    938: 
                    939: --*/
                    940: 
                    941: {
                    942:     PDEVICE_CONTEXT DeviceContext = (PDEVICE_CONTEXT)BindingContext;
                    943: 
                    944:     DeviceContext->NdisRequestStatus = NdisStatus;
                    945:     KeSetEvent(
                    946:         &DeviceContext->NdisRequestEvent,
                    947:         0L,
                    948:         FALSE);
                    949: 
                    950:     return;
                    951: }
                    952: 
                    953: VOID
                    954: StStatusIndication (
                    955:     IN NDIS_HANDLE NdisBindingContext,
                    956:     IN NDIS_STATUS NdisStatus,
                    957:     IN PVOID StatusBuffer,
                    958:     IN UINT StatusBufferSize
                    959:     )
                    960: 
                    961: {
                    962:     PDEVICE_CONTEXT DeviceContext;
                    963: 
                    964:     DeviceContext = (PDEVICE_CONTEXT)NdisBindingContext;
                    965: 
                    966:     switch (NdisStatus) {
                    967: 
                    968:         //
                    969:         // Handle various status codes here.
                    970:         //
                    971: 
                    972:         default:
                    973:             break;
                    974: 
                    975:     }
                    976: }
                    977: 
                    978: 
                    979: VOID
                    980: StStatusComplete (
                    981:     IN NDIS_HANDLE NdisBindingContext
                    982:     )
                    983: {
                    984:     UNREFERENCED_PARAMETER (NdisBindingContext);
                    985: 
                    986: }

unix.superglobalmegacorp.com

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