2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS NDIS library
4 * FILE: ndis/miniport.c
5 * PURPOSE: Routines used by NDIS miniport drivers
6 * PROGRAMMERS: Casper S. Hornstrup (chorns@users.sourceforge.net)
7 * Vizzini (vizzini@plasmic.com)
9 * CSH 01/08-2000 Created
10 * 20 Aug 2003 vizzini - DMA support
11 * 3 Oct 2003 vizzini - SendPackets support
19 * Define to 1 to get a debugger breakpoint at the end of NdisInitializeWrapper
20 * for each new miniport starting up
22 #define BREAK_ON_MINIPORT_INIT 0
25 * This has to be big enough to hold the results of querying the Route value
26 * from the Linkage key. Please re-code me to determine this dynamically.
28 #define ROUTE_DATA_SIZE 256
30 /* Number of media we know */
31 #define MEDIA_ARRAY_SIZE 15
33 static NDIS_MEDIUM MediaArray
[MEDIA_ARRAY_SIZE
] =
42 NdisMediumArcnet878_2
,
44 NdisMediumWirelessWan
,
52 /* global list and lock of Miniports NDIS has registered */
53 LIST_ENTRY MiniportListHead
;
54 KSPIN_LOCK MiniportListLock
;
56 /* global list and lock of adapters NDIS has registered */
57 LIST_ENTRY AdapterListHead
;
58 KSPIN_LOCK AdapterListLock
;
67 if ((DebugTraceLevel
& DEBUG_PACKET
) > 0) {
68 Length
= CopyPacketToBuffer(
74 DbgPrint("*** PACKET START ***");
76 for (i
= 0; i
< Length
; i
++) {
78 DbgPrint("\n%04X ", i
);
79 DbgPrint("%02X ", Buffer
[i
]);
82 DbgPrint("*** PACKET STOP ***\n");
90 UINT HeaderBufferSize
,
91 PVOID LookaheadBuffer
,
92 UINT LookaheadBufferSize
)
95 if ((DebugTraceLevel
& DEBUG_PACKET
) > 0) {
99 DbgPrint("*** RECEIVE PACKET START ***\n");
102 for (i
= 0; i
< HeaderBufferSize
; i
++) {
104 DbgPrint("\n%04X ", i
);
105 DbgPrint("%02X ", *p
++);
108 DbgPrint("\nFRAME:");
111 Length
= (LookaheadBufferSize
< 64)? LookaheadBufferSize
: 64;
112 for (i
= 0; i
< Length
; i
++) {
114 DbgPrint("\n%04X ", i
);
115 DbgPrint("%02X ", *p
++);
118 DbgPrint("\n*** RECEIVE PACKET STOP ***\n");
123 PNDIS_MINIPORT_WORK_ITEM
124 MiniGetFirstWorkItem(
125 PLOGICAL_ADAPTER Adapter
,
126 NDIS_WORK_ITEM_TYPE Type
)
128 PNDIS_MINIPORT_WORK_ITEM CurrentEntry
= Adapter
->WorkQueueHead
;
132 if (CurrentEntry
->WorkItemType
== Type
|| Type
== NdisMaxWorkItems
)
135 CurrentEntry
= (PNDIS_MINIPORT_WORK_ITEM
)CurrentEntry
->Link
.Next
;
143 PLOGICAL_ADAPTER Adapter
,
144 NDIS_WORK_ITEM_TYPE Type
)
146 BOOLEAN Busy
= FALSE
;
149 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
151 if (MiniGetFirstWorkItem(Adapter
, Type
))
155 else if (Type
== NdisWorkItemRequest
&& Adapter
->NdisMiniportBlock
.PendingRequest
)
159 else if (Type
== NdisWorkItemSend
&& Adapter
->NdisMiniportBlock
.FirstPendingPacket
)
163 else if (Type
== NdisWorkItemResetRequested
&&
164 Adapter
->NdisMiniportBlock
.ResetStatus
== NDIS_STATUS_PENDING
)
169 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
176 PLOGICAL_ADAPTER Adapter
,
177 NDIS_HANDLE MacReceiveContext
,
179 UINT HeaderBufferSize
,
180 PVOID LookaheadBuffer
,
181 UINT LookaheadBufferSize
,
184 * FUNCTION: Indicate received data to bound protocols
186 * Adapter = Pointer to logical adapter
187 * MacReceiveContext = MAC receive context handle
188 * HeaderBuffer = Pointer to header buffer
189 * HeaderBufferSize = Size of header buffer
190 * LookaheadBuffer = Pointer to lookahead buffer
191 * LookaheadBufferSize = Size of lookahead buffer
192 * PacketSize = Total size of received packet
196 PLIST_ENTRY CurrentEntry
;
197 PADAPTER_BINDING AdapterBinding
;
199 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called. Adapter (0x%X) HeaderBuffer (0x%X) "
200 "HeaderBufferSize (0x%X) LookaheadBuffer (0x%X) LookaheadBufferSize (0x%X).\n",
201 Adapter
, HeaderBuffer
, HeaderBufferSize
, LookaheadBuffer
, LookaheadBufferSize
));
203 MiniDisplayPacket2(HeaderBuffer
, HeaderBufferSize
, LookaheadBuffer
, LookaheadBufferSize
);
205 NDIS_DbgPrint(MAX_TRACE
, ("acquiring miniport block lock\n"));
206 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
208 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
209 NDIS_DbgPrint(DEBUG_MINIPORT
, ("CurrentEntry = %x\n", CurrentEntry
));
211 if (CurrentEntry
== &Adapter
->ProtocolListHead
)
213 NDIS_DbgPrint(MIN_TRACE
, ("WARNING: No upper protocol layer.\n"));
216 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
218 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
219 NDIS_DbgPrint(DEBUG_MINIPORT
, ("AdapterBinding = %x\n", AdapterBinding
));
223 ("XXX (%x) %x %x %x %x %x %x %x XXX\n",
224 *AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
,
225 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
233 /* call the receive handler */
234 (*AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
)(
235 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
243 CurrentEntry
= CurrentEntry
->Flink
;
246 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
248 NDIS_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
257 IN PNDIS_PACKET
*PacketsToReturn
,
258 IN UINT NumberOfPackets
)
260 * FUNCTION: Releases ownership of one or more packets
262 * PacketsToReturn = Pointer to an array of pointers to packet descriptors
263 * NumberOfPackets = Number of pointers in descriptor pointer array
267 PLOGICAL_ADAPTER Adapter
;
270 NDIS_DbgPrint(MID_TRACE
, ("Returning %d packets\n", NumberOfPackets
));
272 for (i
= 0; i
< NumberOfPackets
; i
++)
274 PacketsToReturn
[i
]->WrapperReserved
[0]--;
275 if (PacketsToReturn
[i
]->WrapperReserved
[0] == 0)
277 Adapter
= (PVOID
)(ULONG_PTR
)PacketsToReturn
[i
]->Reserved
[1];
279 NDIS_DbgPrint(MAX_TRACE
, ("Freeing packet %d (adapter = 0x%p)\n", i
, Adapter
));
281 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
282 Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ReturnPacketHandler(
283 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
285 KeLowerIrql(OldIrql
);
291 MiniIndicateReceivePacket(
292 IN NDIS_HANDLE MiniportAdapterHandle
,
293 IN PPNDIS_PACKET PacketArray
,
294 IN UINT NumberOfPackets
)
296 * FUNCTION: receives miniport packet array indications
298 * MiniportAdapterHandle: Miniport handle for the adapter
299 * PacketArray: pointer to a list of packet pointers to indicate
300 * NumberOfPackets: number of packets to indicate
304 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
305 PLIST_ENTRY CurrentEntry
;
306 PADAPTER_BINDING AdapterBinding
;
310 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
312 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
314 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
316 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
318 for (i
= 0; i
< NumberOfPackets
; i
++)
320 /* Store the indicating miniport in the packet */
321 PacketArray
[i
]->Reserved
[1] = (ULONG_PTR
)Adapter
;
323 if (AdapterBinding
->ProtocolBinding
->Chars
.ReceivePacketHandler
&&
324 NDIS_GET_PACKET_STATUS(PacketArray
[i
]) != NDIS_STATUS_RESOURCES
)
326 NDIS_DbgPrint(MID_TRACE
, ("Indicating packet to protocol's ReceivePacket handler\n"));
327 PacketArray
[i
]->WrapperReserved
[0] += (*AdapterBinding
->ProtocolBinding
->Chars
.ReceivePacketHandler
)(
328 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
330 NDIS_DbgPrint(MID_TRACE
, ("Protocol is holding %d references to the packet\n", PacketArray
[i
]->WrapperReserved
[0]));
334 UINT FirstBufferLength
, TotalBufferLength
, LookAheadSize
, HeaderSize
;
335 PNDIS_BUFFER NdisBuffer
;
336 PVOID NdisBufferVA
, LookAheadBuffer
;
338 NdisGetFirstBufferFromPacket(PacketArray
[i
],
344 HeaderSize
= NDIS_GET_PACKET_HEADER_SIZE(PacketArray
[i
]);
346 LookAheadSize
= TotalBufferLength
- HeaderSize
;
348 LookAheadBuffer
= ExAllocatePool(NonPagedPool
, LookAheadSize
);
349 if (!LookAheadBuffer
)
351 NDIS_DbgPrint(MIN_TRACE
, ("Failed to allocate lookahead buffer!\n"));
352 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
356 CopyBufferChainToBuffer(LookAheadBuffer
,
361 NDIS_DbgPrint(MID_TRACE
, ("Indicating packet to protocol's legacy Receive handler\n"));
362 (*AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
)(
363 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
364 AdapterBinding
->NdisOpenBlock
.MacHandle
,
369 TotalBufferLength
- HeaderSize
);
371 ExFreePool(LookAheadBuffer
);
375 CurrentEntry
= CurrentEntry
->Flink
;
378 /* Loop the packet array to get everything
379 * set up for return the packets to the miniport */
380 for (i
= 0; i
< NumberOfPackets
; i
++)
382 /* First, check the initial packet status */
383 if (NDIS_GET_PACKET_STATUS(PacketArray
[i
]) == NDIS_STATUS_RESOURCES
)
385 /* The miniport driver gets it back immediately so nothing to do here */
386 NDIS_DbgPrint(MID_TRACE
, ("Miniport needs the packet back immediately\n"));
390 /* Different behavior depending on whether it's serialized or not */
391 if (Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
393 /* We need to check the reference count */
394 if (PacketArray
[i
]->WrapperReserved
[0] == 0)
396 /* NOTE: Unlike serialized miniports, this is REQUIRED to be called for each
397 * packet received that can be reused immediately, it is not implied! */
398 Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ReturnPacketHandler(
399 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
401 NDIS_DbgPrint(MID_TRACE
, ("Packet has been returned to miniport (Deserialized)\n"));
405 /* Packet will be returned by the protocol's call to NdisReturnPackets */
406 NDIS_DbgPrint(MID_TRACE
, ("Packet will be returned to miniport later (Deserialized)\n"));
411 /* Check the reference count */
412 if (PacketArray
[i
]->WrapperReserved
[0] == 0)
414 /* NDIS_STATUS_SUCCESS means the miniport can have the packet back immediately */
415 NDIS_SET_PACKET_STATUS(PacketArray
[i
], NDIS_STATUS_SUCCESS
);
417 NDIS_DbgPrint(MID_TRACE
, ("Packet has been returned to miniport (Serialized)\n"));
421 /* NDIS_STATUS_PENDING means the miniport needs to wait for MiniportReturnPacket */
422 NDIS_SET_PACKET_STATUS(PacketArray
[i
], NDIS_STATUS_PENDING
);
424 NDIS_DbgPrint(MID_TRACE
, ("Packet will be returned to miniport later (Serialized)\n"));
429 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
434 IN NDIS_HANDLE MiniportAdapterHandle
,
435 IN NDIS_STATUS Status
,
436 IN BOOLEAN AddressingReset
)
438 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
439 PLIST_ENTRY CurrentEntry
;
440 PADAPTER_BINDING AdapterBinding
;
444 MiniDoAddressingReset(Adapter
);
446 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
447 NdisMIndicateStatusComplete(Adapter
);
449 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
451 if (Adapter
->NdisMiniportBlock
.ResetStatus
!= NDIS_STATUS_PENDING
)
453 KeBugCheckEx(BUGCODE_ID_DRIVER
,
454 (ULONG_PTR
)MiniportAdapterHandle
,
456 (ULONG_PTR
)AddressingReset
,
460 Adapter
->NdisMiniportBlock
.ResetStatus
= Status
;
462 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
464 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
466 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
468 (*AdapterBinding
->ProtocolBinding
->Chars
.ResetCompleteHandler
)(
469 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
472 CurrentEntry
= CurrentEntry
->Flink
;
475 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
480 IN NDIS_HANDLE MiniportAdapterHandle
,
481 IN NDIS_STATUS Status
)
483 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
484 PNDIS_REQUEST Request
;
485 PNDIS_REQUEST_MAC_BLOCK MacBlock
;
488 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
490 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
492 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
493 Request
= Adapter
->NdisMiniportBlock
.PendingRequest
;
494 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
496 MacBlock
= (PNDIS_REQUEST_MAC_BLOCK
)Request
->MacReserved
;
498 if( MacBlock
->Binding
->RequestCompleteHandler
) {
499 (*MacBlock
->Binding
->RequestCompleteHandler
)(
500 MacBlock
->Binding
->ProtocolBindingContext
,
505 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
506 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
507 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
508 KeLowerIrql(OldIrql
);
510 MiniWorkItemComplete(Adapter
, NdisWorkItemRequest
);
515 IN NDIS_HANDLE MiniportAdapterHandle
,
516 IN PNDIS_PACKET Packet
,
517 IN NDIS_STATUS Status
)
519 * FUNCTION: Forwards a message to the initiating protocol saying
520 * that a packet was handled
522 * NdisAdapterHandle = Handle input to MiniportInitialize
523 * Packet = Pointer to NDIS packet that was sent
524 * Status = Status of send operation
527 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
528 PADAPTER_BINDING AdapterBinding
;
530 PSCATTER_GATHER_LIST SGList
;
532 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
534 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
536 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
538 if (Adapter
->NdisMiniportBlock
.ScatterGatherListSize
!= 0)
540 NDIS_DbgPrint(MAX_TRACE
, ("Freeing Scatter/Gather list\n"));
542 SGList
= NDIS_PER_PACKET_INFO_FROM_PACKET(Packet
,
543 ScatterGatherListPacketInfo
);
545 Adapter
->NdisMiniportBlock
.SystemAdapterObject
->
546 DmaOperations
->PutScatterGatherList(
547 Adapter
->NdisMiniportBlock
.SystemAdapterObject
,
551 NDIS_PER_PACKET_INFO_FROM_PACKET(Packet
,
552 ScatterGatherListPacketInfo
) = NULL
;
555 (*AdapterBinding
->ProtocolBinding
->Chars
.SendCompleteHandler
)(
556 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
560 KeLowerIrql(OldIrql
);
562 MiniWorkItemComplete(Adapter
, NdisWorkItemSend
);
567 MiniSendResourcesAvailable(
568 IN NDIS_HANDLE MiniportAdapterHandle
)
570 /* Run the work if anything is waiting */
571 MiniWorkItemComplete((PLOGICAL_ADAPTER
)MiniportAdapterHandle
, NdisWorkItemSend
);
576 MiniTransferDataComplete(
577 IN NDIS_HANDLE MiniportAdapterHandle
,
578 IN PNDIS_PACKET Packet
,
579 IN NDIS_STATUS Status
,
580 IN UINT BytesTransferred
)
582 PADAPTER_BINDING AdapterBinding
;
585 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
587 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
589 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
590 (*AdapterBinding
->ProtocolBinding
->Chars
.TransferDataCompleteHandler
)(
591 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
595 KeLowerIrql(OldIrql
);
600 MiniAdapterHasAddress(
601 PLOGICAL_ADAPTER Adapter
,
604 * FUNCTION: Determines whether a packet has the same destination address as an adapter
606 * Adapter = Pointer to logical adapter object
607 * Packet = Pointer to NDIS packet
609 * TRUE if the destination address is that of the adapter, FALSE if not
615 PNDIS_BUFFER NdisBuffer
;
618 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
623 NDIS_DbgPrint(MIN_TRACE
, ("Adapter object was null\n"));
629 NDIS_DbgPrint(MIN_TRACE
, ("Packet was null\n"));
634 NdisQueryPacket(Packet
, NULL
, NULL
, &NdisBuffer
, NULL
);
638 NDIS_DbgPrint(MIN_TRACE
, ("Packet contains no buffers.\n"));
642 NdisQueryBuffer(NdisBuffer
, (PVOID
)&Start2
, &BufferLength
);
644 /* FIXME: Should handle fragmented packets */
646 switch (Adapter
->NdisMiniportBlock
.MediaType
)
648 case NdisMedium802_3
:
649 Length
= ETH_LENGTH_OF_ADDRESS
;
650 /* Destination address is the first field */
654 NDIS_DbgPrint(MIN_TRACE
, ("Adapter has unsupported media type (0x%X).\n", Adapter
->NdisMiniportBlock
.MediaType
));
658 if (BufferLength
< Length
)
660 NDIS_DbgPrint(MIN_TRACE
, ("Buffer is too small.\n"));
664 Start1
= (PUCHAR
)&Adapter
->Address
;
665 NDIS_DbgPrint(MAX_TRACE
, ("packet address: %x:%x:%x:%x:%x:%x adapter address: %x:%x:%x:%x:%x:%x\n",
666 *((char *)Start1
), *(((char *)Start1
)+1), *(((char *)Start1
)+2), *(((char *)Start1
)+3), *(((char *)Start1
)+4), *(((char *)Start1
)+5),
667 *((char *)Start2
), *(((char *)Start2
)+1), *(((char *)Start2
)+2), *(((char *)Start2
)+3), *(((char *)Start2
)+4), *(((char *)Start2
)+5)));
669 return (RtlCompareMemory((PVOID
)Start1
, (PVOID
)Start2
, Length
) == Length
);
675 PNDIS_STRING AdapterName
)
677 * FUNCTION: Finds an adapter object by name
679 * AdapterName = Pointer to name of adapter
681 * Pointer to logical adapter object, or NULL if none was found.
682 * If found, the adapter is referenced for the caller. The caller
683 * is responsible for dereferencing after use
687 PLIST_ENTRY CurrentEntry
;
688 PLOGICAL_ADAPTER Adapter
= 0;
692 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
694 if(IsListEmpty(&AdapterListHead
))
696 NDIS_DbgPrint(MIN_TRACE
, ("No registered miniports for protocol to bind to\n"));
700 NDIS_DbgPrint(DEBUG_MINIPORT
, ("AdapterName = %wZ\n", AdapterName
));
702 KeAcquireSpinLock(&AdapterListLock
, &OldIrql
);
704 CurrentEntry
= AdapterListHead
.Flink
;
706 while (CurrentEntry
!= &AdapterListHead
)
708 Adapter
= CONTAINING_RECORD(CurrentEntry
, LOGICAL_ADAPTER
, ListEntry
);
712 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Examining adapter 0x%lx\n", Adapter
));
714 /* We're technically not allowed to call this above PASSIVE_LEVEL, but it doesn't break
715 * right now and I'd rather use a working API than reimplement it here */
716 if (RtlCompareUnicodeString(AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
, TRUE
) == 0)
722 CurrentEntry
= CurrentEntry
->Flink
;
725 KeReleaseSpinLock(&AdapterListLock
, OldIrql
);
729 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Leaving. Adapter found at 0x%x\n", Adapter
));
733 NDIS_DbgPrint(MIN_TRACE
, ("Leaving (adapter not found for %wZ).\n", AdapterName
));
741 PLOGICAL_ADAPTER Adapter
,
747 NDIS_STATUS NdisStatus
;
748 PNDIS_REQUEST NdisRequest
;
750 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
752 NdisRequest
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_REQUEST
));
754 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
755 return NDIS_STATUS_RESOURCES
;
758 RtlZeroMemory(NdisRequest
, sizeof(NDIS_REQUEST
));
760 NdisRequest
->RequestType
= NdisRequestSetInformation
;
761 NdisRequest
->DATA
.SET_INFORMATION
.Oid
= Oid
;
762 NdisRequest
->DATA
.SET_INFORMATION
.InformationBuffer
= Buffer
;
763 NdisRequest
->DATA
.SET_INFORMATION
.InformationBufferLength
= Size
;
765 NdisStatus
= MiniDoRequest(Adapter
, NdisRequest
);
767 /* FIXME: Wait in pending case! */
769 ASSERT(NdisStatus
!= NDIS_STATUS_PENDING
);
771 *BytesRead
= NdisRequest
->DATA
.SET_INFORMATION
.BytesRead
;
773 ExFreePool(NdisRequest
);
779 MiniQueryInformation(
780 PLOGICAL_ADAPTER Adapter
,
786 * FUNCTION: Queries a logical adapter for properties
788 * Adapter = Pointer to the logical adapter object to query
789 * Oid = Specifies the Object ID to query for
790 * Size = Size of the passed buffer
791 * Buffer = Buffer for the output
792 * BytesWritten = Address of buffer to place number of bytes written
794 * Status of operation
797 NDIS_STATUS NdisStatus
;
798 PNDIS_REQUEST NdisRequest
;
800 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
802 NdisRequest
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_REQUEST
));
804 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
805 return NDIS_STATUS_RESOURCES
;
808 RtlZeroMemory(NdisRequest
, sizeof(NDIS_REQUEST
));
810 NdisRequest
->RequestType
= NdisRequestQueryInformation
;
811 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
= Oid
;
812 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
= Buffer
;
813 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
= Size
;
815 NdisStatus
= MiniDoRequest(Adapter
, NdisRequest
);
817 /* FIXME: Wait in pending case! */
819 ASSERT(NdisStatus
!= NDIS_STATUS_PENDING
);
821 *BytesWritten
= NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
;
823 ExFreePool(NdisRequest
);
829 MiniCheckForHang( PLOGICAL_ADAPTER Adapter
)
831 * FUNCTION: Checks to see if the miniport is hung
833 * Adapter = Pointer to the logical adapter object
835 * TRUE if the miniport is hung
836 * FALSE if the miniport is not hung
842 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
843 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)
844 Ret
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)(
845 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
);
846 KeLowerIrql(OldIrql
);
852 MiniDoAddressingReset(PLOGICAL_ADAPTER Adapter
)
856 MiniSetInformation(Adapter
,
857 OID_GEN_CURRENT_LOOKAHEAD
,
859 &Adapter
->NdisMiniportBlock
.CurrentLookahead
,
862 /* FIXME: Set more stuff */
867 PLOGICAL_ADAPTER Adapter
)
869 * FUNCTION: Resets the miniport
871 * Adapter = Pointer to the logical adapter object
873 * Status of the operation
878 BOOLEAN AddressingReset
= TRUE
;
880 if (MiniIsBusy(Adapter
, NdisWorkItemResetRequested
)) {
881 MiniQueueWorkItem(Adapter
, NdisWorkItemResetRequested
, NULL
, FALSE
);
882 return NDIS_STATUS_PENDING
;
885 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
886 NdisMIndicateStatusComplete(Adapter
);
888 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
889 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
890 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
893 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
894 Adapter
->NdisMiniportBlock
.ResetStatus
= Status
;
895 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
897 KeLowerIrql(OldIrql
);
899 if (Status
!= NDIS_STATUS_PENDING
) {
901 MiniDoAddressingReset(Adapter
);
903 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
904 NdisMIndicateStatusComplete(Adapter
);
906 MiniWorkItemComplete(Adapter
, NdisWorkItemResetRequested
);
915 PVOID DeferredContext
,
916 PVOID SystemArgument1
,
917 PVOID SystemArgument2
)
919 PLOGICAL_ADAPTER Adapter
= DeferredContext
;
921 if (MiniCheckForHang(Adapter
)) {
922 NDIS_DbgPrint(MIN_TRACE
, ("Miniport detected adapter hang\n"));
928 MiniWorkItemComplete(
929 PLOGICAL_ADAPTER Adapter
,
930 NDIS_WORK_ITEM_TYPE WorkItemType
)
932 PIO_WORKITEM IoWorkItem
;
934 /* Check if there's anything queued to run after this work item */
935 if (!MiniIsBusy(Adapter
, WorkItemType
))
938 /* There is, so fire the worker */
939 IoWorkItem
= IoAllocateWorkItem(Adapter
->NdisMiniportBlock
.DeviceObject
);
941 IoQueueWorkItem(IoWorkItem
, MiniportWorker
, DelayedWorkQueue
, IoWorkItem
);
947 PLOGICAL_ADAPTER Adapter
,
948 NDIS_WORK_ITEM_TYPE WorkItemType
,
949 PVOID WorkItemContext
,
952 * FUNCTION: Queues a work item for execution at a later time
954 * Adapter = Pointer to the logical adapter object to queue work item on
955 * WorkItemType = Type of work item to queue
956 * WorkItemContext = Pointer to context information for work item
958 * Status of operation
961 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
964 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
968 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
971 if (WorkItemType
== NdisWorkItemSend
)
973 NDIS_DbgPrint(MIN_TRACE
, ("Requeuing failed packet (%x).\n", WorkItemContext
));
974 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= WorkItemContext
;
978 //This should never happen
984 MiniportWorkItem
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_MINIPORT_WORK_ITEM
));
985 if (!MiniportWorkItem
)
987 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
988 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
992 MiniportWorkItem
->WorkItemType
= WorkItemType
;
993 MiniportWorkItem
->WorkItemContext
= WorkItemContext
;
995 /* safe due to adapter lock held */
996 MiniportWorkItem
->Link
.Next
= NULL
;
997 if (!Adapter
->WorkQueueHead
)
999 Adapter
->WorkQueueHead
= MiniportWorkItem
;
1000 Adapter
->WorkQueueTail
= MiniportWorkItem
;
1004 Adapter
->WorkQueueTail
->Link
.Next
= (PSINGLE_LIST_ENTRY
)MiniportWorkItem
;
1005 Adapter
->WorkQueueTail
= MiniportWorkItem
;
1009 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1014 MiniDequeueWorkItem(
1015 PLOGICAL_ADAPTER Adapter
,
1016 NDIS_WORK_ITEM_TYPE
*WorkItemType
,
1017 PVOID
*WorkItemContext
)
1019 * FUNCTION: Dequeues a work item from the work queue of a logical adapter
1021 * Adapter = Pointer to the logical adapter object to dequeue work item from
1022 * AdapterBinding = Address of buffer for adapter binding for this request
1023 * WorkItemType = Address of buffer for work item type
1024 * WorkItemContext = Address of buffer for pointer to context information
1026 * Adapter lock must be held when called
1028 * Status of operation
1031 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
1032 PNDIS_PACKET Packet
;
1034 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1036 MiniportWorkItem
= Adapter
->WorkQueueHead
;
1038 if ((Packet
= Adapter
->NdisMiniportBlock
.FirstPendingPacket
))
1040 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= NULL
;
1042 *WorkItemType
= NdisWorkItemSend
;
1043 *WorkItemContext
= Packet
;
1045 return NDIS_STATUS_SUCCESS
;
1047 else if (MiniportWorkItem
)
1049 /* safe due to adapter lock held */
1050 Adapter
->WorkQueueHead
= (PNDIS_MINIPORT_WORK_ITEM
)MiniportWorkItem
->Link
.Next
;
1052 if (MiniportWorkItem
== Adapter
->WorkQueueTail
)
1053 Adapter
->WorkQueueTail
= NULL
;
1055 *WorkItemType
= MiniportWorkItem
->WorkItemType
;
1056 *WorkItemContext
= MiniportWorkItem
->WorkItemContext
;
1058 ExFreePool(MiniportWorkItem
);
1060 return NDIS_STATUS_SUCCESS
;
1064 NDIS_DbgPrint(MIN_TRACE
, ("No work item to dequeue\n"));
1066 return NDIS_STATUS_FAILURE
;
1072 PLOGICAL_ADAPTER Adapter
,
1073 PNDIS_REQUEST NdisRequest
)
1075 * FUNCTION: Sends a request to a miniport
1077 * AdapterBinding = Pointer to binding used in the request
1078 * NdisRequest = Pointer to NDIS request structure describing request
1080 * Status of operation
1085 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1087 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1089 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1090 Adapter
->NdisMiniportBlock
.PendingRequest
= NdisRequest
;
1091 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1093 if (!Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CoRequestHandler
)
1095 switch (NdisRequest
->RequestType
)
1097 case NdisRequestQueryInformation
:
1098 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.QueryInformationHandler
)(
1099 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1100 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
,
1101 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
,
1102 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
,
1103 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
,
1104 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesNeeded
);
1107 case NdisRequestSetInformation
:
1108 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SetInformationHandler
)(
1109 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1110 NdisRequest
->DATA
.SET_INFORMATION
.Oid
,
1111 NdisRequest
->DATA
.SET_INFORMATION
.InformationBuffer
,
1112 NdisRequest
->DATA
.SET_INFORMATION
.InformationBufferLength
,
1113 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesRead
,
1114 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesNeeded
);
1118 NDIS_DbgPrint(MIN_TRACE
, ("Bad request type\n"));
1119 Status
= NDIS_STATUS_FAILURE
;
1124 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CoRequestHandler
)(
1125 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1130 if (Status
!= NDIS_STATUS_PENDING
) {
1131 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1132 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
1133 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1136 KeLowerIrql(OldIrql
);
1138 if (Status
!= NDIS_STATUS_PENDING
) {
1139 MiniWorkItemComplete(Adapter
, NdisWorkItemRequest
);
1148 #undef NdisMSetInformationComplete
1151 NdisMSetInformationComplete(
1152 IN NDIS_HANDLE MiniportAdapterHandle
,
1153 IN NDIS_STATUS Status
)
1155 PLOGICAL_ADAPTER Adapter
=
1156 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
1159 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1160 if (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)
1161 (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)(MiniportAdapterHandle
, Status
);
1162 KeLowerIrql(OldIrql
);
1168 #undef NdisMQueryInformationComplete
1171 NdisMQueryInformationComplete(
1172 IN NDIS_HANDLE MiniportAdapterHandle
,
1173 IN NDIS_STATUS Status
)
1175 PLOGICAL_ADAPTER Adapter
=
1176 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
1179 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1180 if( Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)
1181 (Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)(MiniportAdapterHandle
, Status
);
1182 KeLowerIrql(OldIrql
);
1187 MiniportWorker(IN PDEVICE_OBJECT DeviceObject
, IN PVOID Context
)
1189 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
1190 KIRQL OldIrql
, RaiseOldIrql
;
1191 NDIS_STATUS NdisStatus
;
1192 PVOID WorkItemContext
;
1193 NDIS_WORK_ITEM_TYPE WorkItemType
;
1194 BOOLEAN AddressingReset
;
1196 IoFreeWorkItem((PIO_WORKITEM
)Context
);
1198 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1202 (Adapter
, &WorkItemType
, &WorkItemContext
);
1204 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1206 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1208 switch (WorkItemType
)
1210 case NdisWorkItemSend
:
1212 * called by ProSend when protocols want to send packets to the miniport
1215 if(Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)
1217 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1219 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1220 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1221 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1222 NdisStatus
= NDIS_STATUS_PENDING
;
1226 /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */
1227 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1229 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1230 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1231 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1233 KeLowerIrql(RaiseOldIrql
);
1235 NdisStatus
= NDIS_GET_PACKET_STATUS((PNDIS_PACKET
)WorkItemContext
);
1236 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1237 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1244 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1246 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1247 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1248 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1249 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1250 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1254 /* Send is called at DISPATCH_LEVEL for all serialized miniports */
1255 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1256 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1257 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1258 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1259 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1260 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1261 KeLowerIrql(RaiseOldIrql
);
1262 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1263 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1269 if( NdisStatus
!= NDIS_STATUS_PENDING
) {
1271 ( Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1275 case NdisWorkItemSendLoopback
:
1277 * called by ProSend when protocols want to send loopback packets
1279 /* XXX atm ProIndicatePacket sends a packet up via the loopback adapter only */
1280 NdisStatus
= ProIndicatePacket(Adapter
, (PNDIS_PACKET
)WorkItemContext
);
1282 if( NdisStatus
!= NDIS_STATUS_PENDING
)
1283 MiniSendComplete((NDIS_HANDLE
)Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1286 case NdisWorkItemReturnPackets
:
1289 case NdisWorkItemResetRequested
:
1290 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
1291 NdisMIndicateStatusComplete(Adapter
);
1293 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1294 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
1295 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1298 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1299 Adapter
->NdisMiniportBlock
.ResetStatus
= NdisStatus
;
1300 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1302 KeLowerIrql(OldIrql
);
1304 if (NdisStatus
!= NDIS_STATUS_PENDING
)
1305 MiniResetComplete(Adapter
, NdisStatus
, AddressingReset
);
1308 case NdisWorkItemResetInProgress
:
1311 case NdisWorkItemMiniportCallback
:
1314 case NdisWorkItemRequest
:
1315 NdisStatus
= MiniDoRequest(Adapter
, (PNDIS_REQUEST
)WorkItemContext
);
1317 if (NdisStatus
== NDIS_STATUS_PENDING
)
1320 Adapter
->NdisMiniportBlock
.PendingRequest
= (PNDIS_REQUEST
)WorkItemContext
;
1321 switch (((PNDIS_REQUEST
)WorkItemContext
)->RequestType
)
1323 case NdisRequestQueryInformation
:
1324 NdisMQueryInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1327 case NdisRequestSetInformation
:
1328 NdisMSetInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1332 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS request type.\n"));
1335 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
1339 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS work item type (%d).\n", WorkItemType
));
1349 IN NDIS_HANDLE MiniportHandle
,
1350 IN NDIS_STATUS GeneralStatus
,
1351 IN PVOID StatusBuffer
,
1352 IN UINT StatusBufferSize
)
1354 PLOGICAL_ADAPTER Adapter
= MiniportHandle
;
1355 PLIST_ENTRY CurrentEntry
;
1356 PADAPTER_BINDING AdapterBinding
;
1359 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1361 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1363 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1365 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1367 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusHandler
)(
1368 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
1373 CurrentEntry
= CurrentEntry
->Flink
;
1376 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1382 IN NDIS_HANDLE MiniportAdapterHandle
)
1384 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1385 PLIST_ENTRY CurrentEntry
;
1386 PADAPTER_BINDING AdapterBinding
;
1389 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1391 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1393 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1395 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1397 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusCompleteHandler
)(
1398 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
);
1400 CurrentEntry
= CurrentEntry
->Flink
;
1403 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1412 IN NDIS_HANDLE LogHandle
)
1414 PNDIS_LOG Log
= (PNDIS_LOG
)LogHandle
;
1415 PNDIS_MINIPORT_BLOCK Miniport
= Log
->Miniport
;
1418 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1420 KeAcquireSpinLock(&(Miniport
)->Lock
, &OldIrql
);
1421 Miniport
->Log
= NULL
;
1422 KeReleaseSpinLock(&(Miniport
)->Lock
, OldIrql
);
1433 IN NDIS_HANDLE MiniportAdapterHandle
,
1435 OUT PNDIS_HANDLE LogHandle
)
1437 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1441 NDIS_DbgPrint(MAX_TRACE
, ("called: MiniportAdapterHandle 0x%x, Size %ld\n", MiniportAdapterHandle
, Size
));
1443 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1445 if (Adapter
->NdisMiniportBlock
.Log
)
1448 return NDIS_STATUS_FAILURE
;
1451 Log
= ExAllocatePool(NonPagedPool
, Size
+ sizeof(NDIS_LOG
));
1455 return NDIS_STATUS_RESOURCES
;
1458 Adapter
->NdisMiniportBlock
.Log
= Log
;
1460 KeInitializeSpinLock(&Log
->LogLock
);
1462 Log
->Miniport
= &Adapter
->NdisMiniportBlock
;
1463 Log
->TotalSize
= Size
;
1464 Log
->CurrentSize
= 0;
1471 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1473 return NDIS_STATUS_SUCCESS
;
1481 NdisMDeregisterAdapterShutdownHandler(
1482 IN NDIS_HANDLE MiniportHandle
)
1484 * FUNCTION: de-registers a shutdown handler
1485 * ARGUMENTS: MiniportHandle: Handle passed into MiniportInitialize
1488 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1490 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1492 if(Adapter
->BugcheckContext
->ShutdownHandler
) {
1493 KeDeregisterBugCheckCallback(Adapter
->BugcheckContext
->CallbackRecord
);
1494 IoUnregisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1504 IN NDIS_HANDLE LogHandle
)
1506 PNDIS_LOG Log
= (PNDIS_LOG
) LogHandle
;
1509 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1512 KeAcquireSpinLock(&Log
->LogLock
, &OldIrql
);
1514 /* Set buffers size */
1515 Log
->CurrentSize
= 0;
1520 KeReleaseSpinLock(&Log
->LogLock
, OldIrql
);
1526 #undef NdisMIndicateStatus
1529 NdisMIndicateStatus(
1530 IN NDIS_HANDLE MiniportAdapterHandle
,
1531 IN NDIS_STATUS GeneralStatus
,
1532 IN PVOID StatusBuffer
,
1533 IN UINT StatusBufferSize
)
1535 MiniStatus(MiniportAdapterHandle
, GeneralStatus
, StatusBuffer
, StatusBufferSize
);
1541 #undef NdisMIndicateStatusComplete
1544 NdisMIndicateStatusComplete(
1545 IN NDIS_HANDLE MiniportAdapterHandle
)
1547 MiniStatusComplete(MiniportAdapterHandle
);
1555 NdisInitializeWrapper(
1556 OUT PNDIS_HANDLE NdisWrapperHandle
,
1557 IN PVOID SystemSpecific1
,
1558 IN PVOID SystemSpecific2
,
1559 IN PVOID SystemSpecific3
)
1561 * FUNCTION: Notifies the NDIS library that a new miniport is initializing
1563 * NdisWrapperHandle = Address of buffer to place NDIS wrapper handle
1564 * SystemSpecific1 = Pointer to the driver's driver object
1565 * SystemSpecific2 = Pointer to the driver's registry path
1566 * SystemSpecific3 = Always NULL
1568 * - SystemSpecific2 goes invalid so we copy it
1571 PNDIS_M_DRIVER_BLOCK Miniport
;
1572 PUNICODE_STRING RegistryPath
;
1573 WCHAR
*RegistryBuffer
;
1575 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1577 ASSERT(NdisWrapperHandle
);
1579 *NdisWrapperHandle
= NULL
;
1581 #if BREAK_ON_MINIPORT_INIT
1585 Miniport
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DRIVER_BLOCK
));
1589 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1593 RtlZeroMemory(Miniport
, sizeof(NDIS_M_DRIVER_BLOCK
));
1595 KeInitializeSpinLock(&Miniport
->Lock
);
1597 Miniport
->DriverObject
= (PDRIVER_OBJECT
)SystemSpecific1
;
1599 /* set the miniport's driver registry path */
1600 RegistryPath
= ExAllocatePool(PagedPool
, sizeof(UNICODE_STRING
));
1603 ExFreePool(Miniport
);
1604 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1608 RegistryPath
->Length
= ((PUNICODE_STRING
)SystemSpecific2
)->Length
;
1609 RegistryPath
->MaximumLength
= RegistryPath
->Length
+ sizeof(WCHAR
); /* room for 0-term */
1611 RegistryBuffer
= ExAllocatePool(PagedPool
, RegistryPath
->MaximumLength
);
1614 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1615 ExFreePool(Miniport
);
1616 ExFreePool(RegistryPath
);
1620 RtlCopyMemory(RegistryBuffer
, ((PUNICODE_STRING
)SystemSpecific2
)->Buffer
, RegistryPath
->Length
);
1621 RegistryBuffer
[RegistryPath
->Length
/sizeof(WCHAR
)] = 0;
1623 RegistryPath
->Buffer
= RegistryBuffer
;
1624 Miniport
->RegistryPath
= RegistryPath
;
1626 InitializeListHead(&Miniport
->DeviceList
);
1628 /* Put miniport in global miniport list */
1629 ExInterlockedInsertTailList(&MiniportListHead
, &Miniport
->ListEntry
, &MiniportListLock
);
1631 *NdisWrapperHandle
= Miniport
;
1634 VOID NTAPI
NdisIBugcheckCallback(
1638 * FUNCTION: Internal callback for handling bugchecks - calls adapter's shutdown handler
1640 * Buffer: Pointer to a bugcheck callback context
1644 PMINIPORT_BUGCHECK_CONTEXT Context
= (PMINIPORT_BUGCHECK_CONTEXT
)Buffer
;
1645 ADAPTER_SHUTDOWN_HANDLER sh
= (ADAPTER_SHUTDOWN_HANDLER
)Context
->ShutdownHandler
;
1647 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1650 sh(Context
->DriverContext
);
1658 NdisMRegisterAdapterShutdownHandler(
1659 IN NDIS_HANDLE MiniportHandle
,
1660 IN PVOID ShutdownContext
,
1661 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
1663 * FUNCTION: Register a shutdown handler for an adapter
1665 * MiniportHandle: Handle originally passed into MiniportInitialize
1666 * ShutdownContext: Pre-initialized bugcheck context
1667 * ShutdownHandler: Function to call to handle the bugcheck
1669 * - I'm not sure about ShutdownContext
1672 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1673 PMINIPORT_BUGCHECK_CONTEXT BugcheckContext
;
1675 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1677 BugcheckContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_BUGCHECK_CONTEXT
));
1678 if(!BugcheckContext
)
1680 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1684 BugcheckContext
->ShutdownHandler
= ShutdownHandler
;
1685 BugcheckContext
->DriverContext
= ShutdownContext
;
1687 BugcheckContext
->CallbackRecord
= ExAllocatePool(NonPagedPool
, sizeof(KBUGCHECK_CALLBACK_RECORD
));
1688 if (!BugcheckContext
->CallbackRecord
) {
1689 ExFreePool(BugcheckContext
);
1693 Adapter
->BugcheckContext
= BugcheckContext
;
1695 KeInitializeCallbackRecord(BugcheckContext
->CallbackRecord
);
1697 KeRegisterBugCheckCallback(BugcheckContext
->CallbackRecord
, NdisIBugcheckCallback
,
1698 BugcheckContext
, sizeof(*BugcheckContext
), (PUCHAR
)"Ndis Miniport");
1700 IoRegisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1705 PLOGICAL_ADAPTER Adapter
,
1706 NDIS_OID AddressOID
)
1708 * FUNCTION: Queries miniport for information
1710 * Adapter = Pointer to logical adapter
1711 * AddressOID = OID to use to query for current address
1713 * Status of operation
1717 NDIS_STATUS NdisStatus
;
1719 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1721 /* Get MAC options for adapter */
1722 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAC_OPTIONS
, sizeof(UINT
),
1723 &Adapter
->NdisMiniportBlock
.MacOptions
,
1726 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1728 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAC_OPTIONS failed. NdisStatus (0x%X).\n", NdisStatus
));
1732 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MacOptions (0x%X).\n", Adapter
->NdisMiniportBlock
.MacOptions
));
1734 /* Get current hardware address of adapter */
1735 NdisStatus
= MiniQueryInformation(Adapter
, AddressOID
, Adapter
->AddressLength
,
1736 &Adapter
->Address
, &BytesWritten
);
1738 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1740 NDIS_DbgPrint(MIN_TRACE
, ("Address OID (0x%X) failed. NdisStatus (0x%X).\n", AddressOID
, NdisStatus
));
1748 PUCHAR A
= (PUCHAR
)&Adapter
->Address
.Type
.Medium802_3
;
1750 NDIS_DbgPrint(MAX_TRACE
, ("Adapter address is (%02X %02X %02X %02X %02X %02X).\n", A
[0], A
[1], A
[2], A
[3], A
[4], A
[5]));
1754 /* Get maximum lookahead buffer size of adapter */
1755 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_LOOKAHEAD
, sizeof(ULONG
),
1756 &Adapter
->NdisMiniportBlock
.MaximumLookahead
, &BytesWritten
);
1758 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1760 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1764 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MaxLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.MaximumLookahead
));
1766 /* Get current lookahead buffer size of adapter */
1767 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_CURRENT_LOOKAHEAD
, sizeof(ULONG
),
1768 &Adapter
->NdisMiniportBlock
.CurrentLookahead
, &BytesWritten
);
1770 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1772 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_CURRENT_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1776 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_SEND_PACKETS
, sizeof(ULONG
),
1777 &Adapter
->NdisMiniportBlock
.MaxSendPackets
, &BytesWritten
);
1779 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1781 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_SEND_PACKETS failed. NdisStatus (0x%X).\n", NdisStatus
));
1783 /* Set it to 1 if it fails because some drivers don't support this (?)*/
1784 Adapter
->NdisMiniportBlock
.MaxSendPackets
= 1;
1787 NDIS_DbgPrint(DEBUG_MINIPORT
, ("CurLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.CurrentLookahead
));
1789 return STATUS_SUCCESS
;
1794 NdisIForwardIrpAndWaitCompletionRoutine(
1799 PKEVENT Event
= Context
;
1801 if (Irp
->PendingReturned
)
1802 KeSetEvent(Event
, IO_NO_INCREMENT
, FALSE
);
1804 return STATUS_MORE_PROCESSING_REQUIRED
;
1809 NdisIForwardIrpAndWait(PLOGICAL_ADAPTER Adapter
, PIRP Irp
)
1814 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1815 IoCopyCurrentIrpStackLocationToNext(Irp
);
1816 IoSetCompletionRoutine(Irp
, NdisIForwardIrpAndWaitCompletionRoutine
, &Event
,
1818 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
1819 if (Status
== STATUS_PENDING
)
1821 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1822 Status
= Irp
->IoStatus
.Status
;
1830 IN PDEVICE_OBJECT DeviceObject
,
1833 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1834 Irp
->IoStatus
.Information
= 0;
1836 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1838 return STATUS_SUCCESS
;
1843 NdisIPnPStartDevice(
1844 IN PDEVICE_OBJECT DeviceObject
,
1847 * FUNCTION: Handle the PnP start device event
1849 * DeviceObejct = Functional Device Object
1850 * Irp = IRP_MN_START_DEVICE I/O request packet
1852 * Status of operation
1855 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
1856 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1857 NDIS_WRAPPER_CONTEXT WrapperContext
;
1858 NDIS_STATUS NdisStatus
;
1859 NDIS_STATUS OpenErrorStatus
;
1861 UINT SelectedMediumIndex
= 0;
1862 NDIS_OID AddressOID
;
1863 BOOLEAN Success
= FALSE
;
1864 ULONG ResourceCount
;
1865 ULONG ResourceListSize
;
1866 UNICODE_STRING ParamName
;
1867 PNDIS_CONFIGURATION_PARAMETER ConfigParam
;
1868 NDIS_HANDLE ConfigHandle
;
1870 LARGE_INTEGER Timeout
;
1871 UINT MaxMulticastAddresses
;
1873 PLIST_ENTRY CurrentEntry
;
1874 PPROTOCOL_BINDING ProtocolBinding
;
1877 * Prepare wrapper context used by HW and configuration routines.
1880 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Start Device %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
1882 NDIS_DbgPrint(MAX_TRACE
, ("Inserting adapter 0x%x into adapter list\n", Adapter
));
1884 /* Put adapter in global adapter list */
1885 ExInterlockedInsertTailList(&AdapterListHead
, &Adapter
->ListEntry
, &AdapterListLock
);
1887 Status
= IoOpenDeviceRegistryKey(
1888 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
, PLUGPLAY_REGKEY_DRIVER
,
1889 KEY_ALL_ACCESS
, &WrapperContext
.RegistryHandle
);
1890 if (!NT_SUCCESS(Status
))
1892 NDIS_DbgPrint(MIN_TRACE
,("failed to open adapter-specific reg key\n"));
1893 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1897 NDIS_DbgPrint(MAX_TRACE
, ("opened device reg key\n"));
1899 WrapperContext
.DeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
1902 * Store the adapter resources used by HW routines such as
1903 * NdisMQueryAdapterResources.
1906 if (Stack
->Parameters
.StartDevice
.AllocatedResources
!= NULL
)
1908 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResources
->List
[0].
1909 PartialResourceList
.Count
;
1911 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1912 PartialDescriptors
[ResourceCount
]);
1914 Adapter
->NdisMiniportBlock
.AllocatedResources
=
1915 ExAllocatePool(PagedPool
, ResourceListSize
);
1916 if (Adapter
->NdisMiniportBlock
.AllocatedResources
== NULL
)
1918 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1919 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1920 return STATUS_INSUFFICIENT_RESOURCES
;
1923 Adapter
->NdisMiniportBlock
.Resources
=
1924 ExAllocatePool(PagedPool
, ResourceListSize
);
1925 if (!Adapter
->NdisMiniportBlock
.Resources
)
1927 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1928 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
1929 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
1930 return STATUS_INSUFFICIENT_RESOURCES
;
1933 RtlCopyMemory(Adapter
->NdisMiniportBlock
.Resources
,
1934 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1937 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResources
,
1938 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1942 if (Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
!= NULL
)
1944 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
->List
[0].
1945 PartialResourceList
.Count
;
1947 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1948 PartialDescriptors
[ResourceCount
]);
1950 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
=
1951 ExAllocatePool(PagedPool
, ResourceListSize
);
1952 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
== NULL
)
1954 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1955 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1956 return STATUS_INSUFFICIENT_RESOURCES
;
1959 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
,
1960 Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
,
1965 * Store the Bus Type, Bus Number and Slot information. It's used by
1966 * the hardware routines then.
1969 NdisOpenConfiguration(&NdisStatus
, &ConfigHandle
, (NDIS_HANDLE
)&WrapperContext
);
1970 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1972 NDIS_DbgPrint(MIN_TRACE
, ("Failed to open configuration key\n"));
1973 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1977 Size
= sizeof(ULONG
);
1978 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1979 DevicePropertyLegacyBusType
, Size
,
1980 &Adapter
->NdisMiniportBlock
.BusType
, &Size
);
1981 if (!NT_SUCCESS(Status
) || (INTERFACE_TYPE
)Adapter
->NdisMiniportBlock
.BusType
== InterfaceTypeUndefined
)
1983 NdisInitUnicodeString(&ParamName
, L
"BusType");
1984 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1985 &ParamName
, NdisParameterInteger
);
1986 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1987 Adapter
->NdisMiniportBlock
.BusType
= ConfigParam
->ParameterData
.IntegerData
;
1989 Adapter
->NdisMiniportBlock
.BusType
= Isa
;
1992 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1993 DevicePropertyBusNumber
, Size
,
1994 &Adapter
->NdisMiniportBlock
.BusNumber
, &Size
);
1995 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.BusNumber
== 0xFFFFFFF0)
1997 NdisInitUnicodeString(&ParamName
, L
"BusNumber");
1998 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1999 &ParamName
, NdisParameterInteger
);
2000 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
2001 Adapter
->NdisMiniportBlock
.BusNumber
= ConfigParam
->ParameterData
.IntegerData
;
2003 Adapter
->NdisMiniportBlock
.BusNumber
= 0;
2005 WrapperContext
.BusNumber
= Adapter
->NdisMiniportBlock
.BusNumber
;
2007 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
2008 DevicePropertyAddress
, Size
,
2009 &Adapter
->NdisMiniportBlock
.SlotNumber
, &Size
);
2010 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.SlotNumber
== (NDIS_INTERFACE_TYPE
)-1)
2012 NdisInitUnicodeString(&ParamName
, L
"SlotNumber");
2013 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
2014 &ParamName
, NdisParameterInteger
);
2015 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
2016 Adapter
->NdisMiniportBlock
.SlotNumber
= ConfigParam
->ParameterData
.IntegerData
;
2018 Adapter
->NdisMiniportBlock
.SlotNumber
= 0;
2022 /* Convert slotnumber to PCI_SLOT_NUMBER */
2023 ULONG PciSlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
2024 PCI_SLOT_NUMBER SlotNumber
;
2026 SlotNumber
.u
.AsULONG
= 0;
2027 SlotNumber
.u
.bits
.DeviceNumber
= (PciSlotNumber
>> 16) & 0xFFFF;
2028 SlotNumber
.u
.bits
.FunctionNumber
= PciSlotNumber
& 0xFFFF;
2030 Adapter
->NdisMiniportBlock
.SlotNumber
= SlotNumber
.u
.AsULONG
;
2032 WrapperContext
.SlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
2034 NdisCloseConfiguration(ConfigHandle
);
2036 /* Set handlers (some NDIS macros require these) */
2037 Adapter
->NdisMiniportBlock
.EthRxCompleteHandler
= EthFilterDprIndicateReceiveComplete
;
2038 Adapter
->NdisMiniportBlock
.EthRxIndicateHandler
= EthFilterDprIndicateReceive
;
2039 Adapter
->NdisMiniportBlock
.SendCompleteHandler
= MiniSendComplete
;
2040 Adapter
->NdisMiniportBlock
.SendResourcesHandler
= MiniSendResourcesAvailable
;
2041 Adapter
->NdisMiniportBlock
.ResetCompleteHandler
= MiniResetComplete
;
2042 Adapter
->NdisMiniportBlock
.TDCompleteHandler
= MiniTransferDataComplete
;
2043 Adapter
->NdisMiniportBlock
.PacketIndicateHandler
= MiniIndicateReceivePacket
;
2044 Adapter
->NdisMiniportBlock
.StatusHandler
= MiniStatus
;
2045 Adapter
->NdisMiniportBlock
.StatusCompleteHandler
= MiniStatusComplete
;
2046 Adapter
->NdisMiniportBlock
.SendPacketsHandler
= ProSendPackets
;
2047 Adapter
->NdisMiniportBlock
.QueryCompleteHandler
= MiniRequestComplete
;
2048 Adapter
->NdisMiniportBlock
.SetCompleteHandler
= MiniRequestComplete
;
2051 * Call MiniportInitialize.
2054 NDIS_DbgPrint(MID_TRACE
, ("calling MiniportInitialize\n"));
2055 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.InitializeHandler
)(
2056 &OpenErrorStatus
, &SelectedMediumIndex
, &MediaArray
[0],
2057 MEDIA_ARRAY_SIZE
, Adapter
, (NDIS_HANDLE
)&WrapperContext
);
2059 ZwClose(WrapperContext
.RegistryHandle
);
2061 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2063 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() failed for an adapter.\n"));
2064 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
2065 if (Adapter
->NdisMiniportBlock
.Interrupt
)
2067 KeBugCheckEx(BUGCODE_ID_DRIVER
,
2069 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.Interrupt
,
2070 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.TimerQueue
,
2073 if (Adapter
->NdisMiniportBlock
.TimerQueue
)
2075 KeBugCheckEx(BUGCODE_ID_DRIVER
,
2077 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.Interrupt
,
2078 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.TimerQueue
,
2084 if (SelectedMediumIndex
>= MEDIA_ARRAY_SIZE
)
2086 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() selected a bad index\n"));
2087 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
2088 return NDIS_STATUS_UNSUPPORTED_MEDIA
;
2091 Adapter
->NdisMiniportBlock
.MediaType
= MediaArray
[SelectedMediumIndex
];
2093 switch (Adapter
->NdisMiniportBlock
.MediaType
)
2095 case NdisMedium802_3
:
2096 Adapter
->MediumHeaderSize
= 14; /* XXX figure out what to do about LLC */
2097 AddressOID
= OID_802_3_CURRENT_ADDRESS
;
2098 Adapter
->AddressLength
= ETH_LENGTH_OF_ADDRESS
;
2099 NdisStatus
= DoQueries(Adapter
, AddressOID
);
2100 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
2102 NdisStatus
= MiniQueryInformation(Adapter
, OID_802_3_MAXIMUM_LIST_SIZE
, sizeof(UINT
),
2103 &MaxMulticastAddresses
, &BytesWritten
);
2105 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2107 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
2108 NDIS_DbgPrint(MIN_TRACE
, ("MiniQueryInformation failed (%x)\n", NdisStatus
));
2112 Success
= EthCreateFilter(MaxMulticastAddresses
,
2113 Adapter
->Address
.Type
.Medium802_3
,
2114 &Adapter
->NdisMiniportBlock
.EthDB
);
2116 ((PETHI_FILTER
)Adapter
->NdisMiniportBlock
.EthDB
)->Miniport
= (PNDIS_MINIPORT_BLOCK
)Adapter
;
2118 NdisStatus
= NDIS_STATUS_RESOURCES
;
2123 /* FIXME: Support other types of media */
2124 NDIS_DbgPrint(MIN_TRACE
, ("error: unsupported media\n"));
2126 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
2127 return STATUS_UNSUCCESSFUL
;
2130 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2132 NDIS_DbgPrint(MIN_TRACE
, ("couldn't create filter (%x)\n", NdisStatus
));
2136 /* Check for a hang every two seconds if it wasn't set in MiniportInitialize */
2137 if (Adapter
->NdisMiniportBlock
.CheckForHangSeconds
== 0)
2138 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= 2;
2140 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
2141 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStarted
;
2143 IoSetDeviceInterfaceState(&Adapter
->NdisMiniportBlock
.SymbolicLinkName
, TRUE
);
2145 Timeout
.QuadPart
= Int32x32To64(Adapter
->NdisMiniportBlock
.CheckForHangSeconds
, -1000000);
2146 KeSetTimerEx(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
, Timeout
,
2147 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
* 1000,
2148 &Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
);
2150 /* Put adapter in adapter list for this miniport */
2151 ExInterlockedInsertTailList(&Adapter
->NdisMiniportBlock
.DriverHandle
->DeviceList
, &Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
2153 /* Refresh bindings for all protocols */
2154 CurrentEntry
= ProtocolListHead
.Flink
;
2155 while (CurrentEntry
!= &ProtocolListHead
)
2157 ProtocolBinding
= CONTAINING_RECORD(CurrentEntry
, PROTOCOL_BINDING
, ListEntry
);
2159 ndisBindMiniportsToProtocol(&NdisStatus
, ProtocolBinding
);
2161 CurrentEntry
= CurrentEntry
->Flink
;
2164 return STATUS_SUCCESS
;
2170 IN PDEVICE_OBJECT DeviceObject
,
2173 * FUNCTION: Handle the PnP stop device event
2175 * DeviceObejct = Functional Device Object
2176 * Irp = IRP_MN_STOP_DEVICE I/O request packet
2178 * Status of operation
2181 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2183 /* Remove adapter from adapter list for this miniport */
2184 ExInterlockedRemoveEntryList(&Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
2186 /* Remove adapter from global adapter list */
2187 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
2189 KeCancelTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
2191 /* Set this here so MiniportISR will be forced to run for interrupts generated in MiniportHalt */
2192 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
2193 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStopped
;
2195 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.HaltHandler
)(Adapter
);
2197 IoSetDeviceInterfaceState(&Adapter
->NdisMiniportBlock
.SymbolicLinkName
, FALSE
);
2199 if (Adapter
->NdisMiniportBlock
.AllocatedResources
)
2201 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
2202 Adapter
->NdisMiniportBlock
.AllocatedResources
= NULL
;
2204 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
)
2206 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
);
2207 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
= NULL
;
2210 if (Adapter
->NdisMiniportBlock
.Resources
)
2212 ExFreePool(Adapter
->NdisMiniportBlock
.Resources
);
2213 Adapter
->NdisMiniportBlock
.Resources
= NULL
;
2216 if (Adapter
->NdisMiniportBlock
.EthDB
)
2218 EthDeleteFilter(Adapter
->NdisMiniportBlock
.EthDB
);
2219 Adapter
->NdisMiniportBlock
.EthDB
= NULL
;
2222 return STATUS_SUCCESS
;
2228 IN PDEVICE_OBJECT DeviceObject
,
2231 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
2232 PMINIPORT_BUGCHECK_CONTEXT Context
= Adapter
->BugcheckContext
;
2233 ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
= Context
->ShutdownHandler
;
2235 ASSERT(ShutdownHandler
);
2237 ShutdownHandler(Context
->DriverContext
);
2239 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2240 Irp
->IoStatus
.Information
= 0;
2242 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2244 return STATUS_SUCCESS
;
2249 NdisIDeviceIoControl(
2250 IN PDEVICE_OBJECT DeviceObject
,
2253 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2254 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2255 NDIS_STATUS Status
= STATUS_NOT_SUPPORTED
;
2258 Irp
->IoStatus
.Information
= 0;
2262 switch (Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
2264 case IOCTL_NDIS_QUERY_GLOBAL_STATS
:
2265 Status
= MiniQueryInformation(Adapter
,
2266 *(PNDIS_OID
)Irp
->AssociatedIrp
.SystemBuffer
,
2267 Stack
->Parameters
.DeviceIoControl
.OutputBufferLength
,
2268 MmGetSystemAddressForMdl(Irp
->MdlAddress
),
2270 Irp
->IoStatus
.Information
= Written
;
2278 if (Status
!= NDIS_STATUS_PENDING
)
2280 Irp
->IoStatus
.Status
= Status
;
2281 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2284 IoMarkIrpPending(Irp
);
2292 IN PDEVICE_OBJECT DeviceObject
,
2295 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2296 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2299 switch (Stack
->MinorFunction
)
2301 case IRP_MN_START_DEVICE
:
2302 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2303 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2305 Status
= NdisIPnPStartDevice(DeviceObject
, Irp
);
2308 NDIS_DbgPrint(MIN_TRACE
, ("Lower driver failed device start\n"));
2309 Irp
->IoStatus
.Status
= Status
;
2310 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2313 case IRP_MN_STOP_DEVICE
:
2314 Status
= NdisIPnPStopDevice(DeviceObject
, Irp
);
2315 if (!NT_SUCCESS(Status
))
2316 NDIS_DbgPrint(MIN_TRACE
, ("WARNING: Ignoring halt device failure! Passing the IRP down anyway\n"));
2317 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2320 case IRP_MN_QUERY_REMOVE_DEVICE
:
2321 case IRP_MN_QUERY_STOP_DEVICE
:
2322 Status
= NdisIPnPQueryStopDevice(DeviceObject
, Irp
);
2323 Irp
->IoStatus
.Status
= Status
;
2324 if (Status
!= STATUS_SUCCESS
)
2326 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2327 NDIS_DbgPrint(MIN_TRACE
, ("Failing miniport halt request\n"));
2332 case IRP_MN_CANCEL_REMOVE_DEVICE
:
2333 case IRP_MN_CANCEL_STOP_DEVICE
:
2334 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2335 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2337 Status
= NdisIPnPCancelStopDevice(DeviceObject
, Irp
);
2341 NDIS_DbgPrint(MIN_TRACE
, ("Lower driver failed cancel stop/remove request\n"));
2343 Irp
->IoStatus
.Status
= Status
;
2344 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2347 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
2348 Status
= NDIS_STATUS_SUCCESS
;
2349 Irp
->IoStatus
.Status
= Status
;
2350 Irp
->IoStatus
.Information
|= Adapter
->NdisMiniportBlock
.PnPFlags
;
2357 IoSkipCurrentIrpStackLocation(Irp
);
2358 return IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
2364 IN PDRIVER_OBJECT DriverObject
,
2365 IN PDEVICE_OBJECT PhysicalDeviceObject
)
2367 * FUNCTION: Create a device for an adapter found using PnP
2369 * DriverObject = Pointer to the miniport driver object
2370 * PhysicalDeviceObject = Pointer to the PDO for our adapter
2373 static const WCHAR ClassKeyName
[] = {'C','l','a','s','s','\\'};
2374 static const WCHAR LinkageKeyName
[] = {'\\','L','i','n','k','a','g','e',0};
2375 PNDIS_M_DRIVER_BLOCK Miniport
;
2376 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2377 WCHAR
*LinkageKeyBuffer
;
2378 ULONG DriverKeyLength
;
2379 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
2380 UNICODE_STRING ExportName
;
2381 PDEVICE_OBJECT DeviceObject
;
2382 PLOGICAL_ADAPTER Adapter
;
2386 * Gain the access to the miniport data structure first.
2389 MiniportPtr
= IoGetDriverObjectExtension(DriverObject
, (PVOID
)'NMID');
2390 if (MiniportPtr
== NULL
)
2392 NDIS_DbgPrint(MIN_TRACE
, ("Can't get driver object extension.\n"));
2393 return NDIS_STATUS_FAILURE
;
2395 Miniport
= *MiniportPtr
;
2398 * Get name of the Linkage registry key for our adapter. It's located under
2399 * the driver key for our driver and so we have basicly two ways to do it.
2400 * Either we can use IoOpenDriverRegistryKey or compose it using information
2401 * gathered by IoGetDeviceProperty. I choosed the second because
2402 * IoOpenDriverRegistryKey wasn't implemented at the time of writing.
2405 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2406 0, NULL
, &DriverKeyLength
);
2407 if (Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
&& Status
!= STATUS_SUCCESS
)
2409 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport driver key length.\n"));
2413 LinkageKeyBuffer
= ExAllocatePool(PagedPool
, DriverKeyLength
+
2414 sizeof(ClassKeyName
) + sizeof(LinkageKeyName
));
2415 if (LinkageKeyBuffer
== NULL
)
2417 NDIS_DbgPrint(MIN_TRACE
, ("Can't allocate memory for driver key name.\n"));
2418 return STATUS_INSUFFICIENT_RESOURCES
;
2421 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2422 DriverKeyLength
, LinkageKeyBuffer
+
2423 (sizeof(ClassKeyName
) / sizeof(WCHAR
)),
2425 if (!NT_SUCCESS(Status
))
2427 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport driver key.\n"));
2428 ExFreePool(LinkageKeyBuffer
);
2432 /* Compose the linkage key name. */
2433 RtlCopyMemory(LinkageKeyBuffer
, ClassKeyName
, sizeof(ClassKeyName
));
2434 RtlCopyMemory(LinkageKeyBuffer
+ ((sizeof(ClassKeyName
) + DriverKeyLength
) /
2435 sizeof(WCHAR
)) - 1, LinkageKeyName
, sizeof(LinkageKeyName
));
2437 NDIS_DbgPrint(DEBUG_MINIPORT
, ("LinkageKey: %S.\n", LinkageKeyBuffer
));
2440 * Now open the linkage key and read the "Export" and "RootDevice" values
2441 * which contains device name and root service respectively.
2444 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
2445 RtlInitUnicodeString(&ExportName
, NULL
);
2446 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
| RTL_QUERY_REGISTRY_DIRECT
;
2447 QueryTable
[0].Name
= L
"Export";
2448 QueryTable
[0].EntryContext
= &ExportName
;
2450 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
, LinkageKeyBuffer
,
2451 QueryTable
, NULL
, NULL
);
2452 ExFreePool(LinkageKeyBuffer
);
2453 if (!NT_SUCCESS(Status
))
2455 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport device name. (%x)\n", Status
));
2460 * Create the device object.
2463 NDIS_DbgPrint(MAX_TRACE
, ("creating device %wZ\n", &ExportName
));
2465 Status
= IoCreateDevice(Miniport
->DriverObject
, sizeof(LOGICAL_ADAPTER
),
2466 &ExportName
, FILE_DEVICE_PHYSICAL_NETCARD
,
2467 0, FALSE
, &DeviceObject
);
2468 if (!NT_SUCCESS(Status
))
2470 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device object.\n"));
2471 RtlFreeUnicodeString(&ExportName
);
2476 * Initialize the adapter structure.
2479 Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2480 KeInitializeSpinLock(&Adapter
->NdisMiniportBlock
.Lock
);
2481 InitializeListHead(&Adapter
->ProtocolListHead
);
2483 Status
= IoRegisterDeviceInterface(PhysicalDeviceObject
,
2484 &GUID_DEVINTERFACE_NET
,
2486 &Adapter
->NdisMiniportBlock
.SymbolicLinkName
);
2488 if (!NT_SUCCESS(Status
))
2490 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device interface.\n"));
2491 IoDeleteDevice(DeviceObject
);
2492 RtlFreeUnicodeString(&ExportName
);
2496 Adapter
->NdisMiniportBlock
.DriverHandle
= Miniport
;
2497 Adapter
->NdisMiniportBlock
.MiniportName
= ExportName
;
2498 Adapter
->NdisMiniportBlock
.DeviceObject
= DeviceObject
;
2499 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
= PhysicalDeviceObject
;
2500 Adapter
->NdisMiniportBlock
.NextDeviceObject
=
2501 IoAttachDeviceToDeviceStack(Adapter
->NdisMiniportBlock
.DeviceObject
,
2502 PhysicalDeviceObject
);
2504 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= 0;
2505 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceAdded
;
2507 KeInitializeTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
2508 KeInitializeDpc(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
, MiniportHangDpc
, Adapter
);
2510 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
2512 return STATUS_SUCCESS
;
2517 NdisGenericIrpHandler(
2518 IN PDEVICE_OBJECT DeviceObject
,
2521 PIO_STACK_LOCATION IrpSp
= IoGetCurrentIrpStackLocation(Irp
);
2523 /* Use the characteristics to classify the device */
2524 if (DeviceObject
->DeviceType
== FILE_DEVICE_PHYSICAL_NETCARD
)
2526 if ((IrpSp
->MajorFunction
== IRP_MJ_CREATE
) ||
2527 (IrpSp
->MajorFunction
== IRP_MJ_CLOSE
))
2529 return NdisICreateClose(DeviceObject
, Irp
);
2531 else if (IrpSp
->MajorFunction
== IRP_MJ_PNP
)
2533 return NdisIDispatchPnp(DeviceObject
, Irp
);
2535 else if (IrpSp
->MajorFunction
== IRP_MJ_SHUTDOWN
)
2537 return NdisIShutdown(DeviceObject
, Irp
);
2539 else if (IrpSp
->MajorFunction
== IRP_MJ_DEVICE_CONTROL
)
2541 return NdisIDeviceIoControl(DeviceObject
, Irp
);
2544 else if (DeviceObject
->DeviceType
== FILE_DEVICE_NETWORK
)
2546 PNDIS_M_DEVICE_BLOCK DeviceBlock
= DeviceObject
->DeviceExtension
;
2548 ASSERT(DeviceBlock
->DeviceObject
== DeviceObject
);
2550 if (DeviceBlock
->MajorFunction
[IrpSp
->MajorFunction
] != NULL
)
2552 return DeviceBlock
->MajorFunction
[IrpSp
->MajorFunction
](DeviceObject
, Irp
);
2560 Irp
->IoStatus
.Status
= STATUS_INVALID_DEVICE_REQUEST
;
2561 Irp
->IoStatus
.Information
= 0;
2563 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2565 return STATUS_INVALID_DEVICE_REQUEST
;
2573 NdisMRegisterMiniport(
2574 IN NDIS_HANDLE NdisWrapperHandle
,
2575 IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics
,
2576 IN UINT CharacteristicsLength
)
2578 * FUNCTION: Registers a miniport's MiniportXxx entry points with the NDIS library
2580 * NdisWrapperHandle = Pointer to handle returned by NdisMInitializeWrapper
2581 * MiniportCharacteristics = Pointer to a buffer with miniport characteristics
2582 * CharacteristicsLength = Number of bytes in characteristics buffer
2584 * Status of operation
2588 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2589 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2593 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2595 switch (MiniportCharacteristics
->MajorNdisVersion
)
2598 MinSize
= sizeof(NDIS30_MINIPORT_CHARACTERISTICS
);
2602 MinSize
= sizeof(NDIS40_MINIPORT_CHARACTERISTICS
);
2606 switch (MiniportCharacteristics
->MinorNdisVersion
)
2609 MinSize
= sizeof(NDIS50_MINIPORT_CHARACTERISTICS
);
2613 MinSize
= sizeof(NDIS51_MINIPORT_CHARACTERISTICS
);
2617 NDIS_DbgPrint(MIN_TRACE
, ("Bad 5.x minor characteristics version.\n"));
2618 return NDIS_STATUS_BAD_VERSION
;
2623 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics version.\n"));
2624 return NDIS_STATUS_BAD_VERSION
;
2627 NDIS_DbgPrint(MIN_TRACE
, ("Initializing an NDIS %u.%u miniport\n",
2628 MiniportCharacteristics
->MajorNdisVersion
,
2629 MiniportCharacteristics
->MinorNdisVersion
));
2631 if (CharacteristicsLength
< MinSize
)
2633 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics length.\n"));
2634 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2637 /* Check if mandatory MiniportXxx functions are specified */
2638 if ((!MiniportCharacteristics
->HaltHandler
) ||
2639 (!MiniportCharacteristics
->InitializeHandler
)||
2640 (!MiniportCharacteristics
->ResetHandler
))
2642 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics.\n"));
2643 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2646 if (MiniportCharacteristics
->MajorNdisVersion
< 0x05)
2648 if ((!MiniportCharacteristics
->QueryInformationHandler
) ||
2649 (!MiniportCharacteristics
->SetInformationHandler
))
2651 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (Set/Query)\n"));
2652 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2657 if (((!MiniportCharacteristics
->QueryInformationHandler
) ||
2658 (!MiniportCharacteristics
->SetInformationHandler
)) &&
2659 (!MiniportCharacteristics
->CoRequestHandler
))
2661 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (Set/Query)\n"));
2662 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2666 if (MiniportCharacteristics
->MajorNdisVersion
== 0x03)
2668 if (!MiniportCharacteristics
->SendHandler
)
2670 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 3.0)\n"));
2671 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2674 else if (MiniportCharacteristics
->MajorNdisVersion
== 0x04)
2677 if ((!MiniportCharacteristics
->SendHandler
) &&
2678 (!MiniportCharacteristics
->SendPacketsHandler
))
2680 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 4.0)\n"));
2681 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2684 else if (MiniportCharacteristics
->MajorNdisVersion
== 0x05)
2686 /* TODO: Add more checks here */
2688 if ((!MiniportCharacteristics
->SendHandler
) &&
2689 (!MiniportCharacteristics
->SendPacketsHandler
) &&
2690 (!MiniportCharacteristics
->CoSendPacketsHandler
))
2692 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 5.0)\n"));
2693 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2697 RtlCopyMemory(&Miniport
->MiniportCharacteristics
, MiniportCharacteristics
, MinSize
);
2700 * NOTE: This is VERY unoptimal! Should we store the NDIS_M_DRIVER_BLOCK
2701 * structure in the driver extension or what?
2704 Status
= IoAllocateDriverObjectExtension(Miniport
->DriverObject
, (PVOID
)'NMID',
2705 sizeof(PNDIS_M_DRIVER_BLOCK
), (PVOID
*)&MiniportPtr
);
2706 if (!NT_SUCCESS(Status
))
2708 NDIS_DbgPrint(MIN_TRACE
, ("Can't allocate driver object extension.\n"));
2709 return NDIS_STATUS_RESOURCES
;
2712 *MiniportPtr
= Miniport
;
2714 /* We have to register for all of these so handler registered in NdisMRegisterDevice work */
2715 for (i
= 0; i
<= IRP_MJ_MAXIMUM_FUNCTION
; i
++)
2717 Miniport
->DriverObject
->MajorFunction
[i
] = NdisGenericIrpHandler
;
2720 Miniport
->DriverObject
->DriverExtension
->AddDevice
= NdisIAddDevice
;
2722 return NDIS_STATUS_SUCCESS
;
2728 #undef NdisMResetComplete
2732 IN NDIS_HANDLE MiniportAdapterHandle
,
2733 IN NDIS_STATUS Status
,
2734 IN BOOLEAN AddressingReset
)
2736 MiniResetComplete(MiniportAdapterHandle
, Status
, AddressingReset
);
2742 #undef NdisMSendComplete
2746 IN NDIS_HANDLE MiniportAdapterHandle
,
2747 IN PNDIS_PACKET Packet
,
2748 IN NDIS_STATUS Status
)
2750 * FUNCTION: Forwards a message to the initiating protocol saying
2751 * that a packet was handled
2753 * NdisAdapterHandle = Handle input to MiniportInitialize
2754 * Packet = Pointer to NDIS packet that was sent
2755 * Status = Status of send operation
2758 MiniSendComplete(MiniportAdapterHandle
, Packet
, Status
);
2764 #undef NdisMSendResourcesAvailable
2767 NdisMSendResourcesAvailable(
2768 IN NDIS_HANDLE MiniportAdapterHandle
)
2770 MiniSendResourcesAvailable(MiniportAdapterHandle
);
2776 #undef NdisMTransferDataComplete
2779 NdisMTransferDataComplete(
2780 IN NDIS_HANDLE MiniportAdapterHandle
,
2781 IN PNDIS_PACKET Packet
,
2782 IN NDIS_STATUS Status
,
2783 IN UINT BytesTransferred
)
2785 MiniTransferDataComplete(MiniportAdapterHandle
, Packet
, Status
, BytesTransferred
);
2791 #undef NdisMSetAttributes
2795 IN NDIS_HANDLE MiniportAdapterHandle
,
2796 IN NDIS_HANDLE MiniportAdapterContext
,
2797 IN BOOLEAN BusMaster
,
2798 IN NDIS_INTERFACE_TYPE AdapterType
)
2800 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2802 * MiniportAdapterHandle = Handle input to MiniportInitialize
2803 * MiniportAdapterContext = Pointer to context information
2804 * BusMaster = Specifies TRUE if the caller's NIC is a busmaster DMA device
2805 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2808 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2809 NdisMSetAttributesEx(MiniportAdapterHandle
, MiniportAdapterContext
, 0,
2810 BusMaster
? NDIS_ATTRIBUTE_BUS_MASTER
: 0,
2819 NdisMSetAttributesEx(
2820 IN NDIS_HANDLE MiniportAdapterHandle
,
2821 IN NDIS_HANDLE MiniportAdapterContext
,
2822 IN UINT CheckForHangTimeInSeconds OPTIONAL
,
2823 IN ULONG AttributeFlags
,
2824 IN NDIS_INTERFACE_TYPE AdapterType
)
2826 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2828 * MiniportAdapterHandle = Handle input to MiniportInitialize
2829 * MiniportAdapterContext = Pointer to context information
2830 * CheckForHangTimeInSeconds = Specifies interval in seconds at which
2831 * MiniportCheckForHang should be called
2832 * AttributeFlags = Bitmask that indicates specific attributes
2833 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2836 PLOGICAL_ADAPTER Adapter
= GET_LOGICAL_ADAPTER(MiniportAdapterHandle
);
2838 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2840 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
= MiniportAdapterContext
;
2841 Adapter
->NdisMiniportBlock
.Flags
= AttributeFlags
;
2842 Adapter
->NdisMiniportBlock
.AdapterType
= AdapterType
;
2843 if (CheckForHangTimeInSeconds
> 0)
2844 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= CheckForHangTimeInSeconds
;
2845 if (AttributeFlags
& NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER
)
2846 NDIS_DbgPrint(MIN_TRACE
, ("Intermediate drivers not supported yet.\n"));
2848 NDIS_DbgPrint(MIN_TRACE
, ("Miniport attribute flags: 0x%x\n", AttributeFlags
));
2850 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.AdapterShutdownHandler
)
2852 NDIS_DbgPrint(MAX_TRACE
, ("Miniport set AdapterShutdownHandler in MiniportCharacteristics\n"));
2853 NdisMRegisterAdapterShutdownHandler(Adapter
,
2854 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
2855 Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.AdapterShutdownHandler
);
2865 IN ULONG MicrosecondsToSleep
)
2867 * FUNCTION: delay the thread's execution for MicrosecondsToSleep
2869 * MicrosecondsToSleep: duh...
2871 * - Because this is a blocking call, current IRQL must be < DISPATCH_LEVEL
2875 LARGE_INTEGER DueTime
;
2879 DueTime
.QuadPart
= (-1) * 10 * MicrosecondsToSleep
;
2881 KeInitializeTimer(&Timer
);
2882 KeSetTimer(&Timer
, DueTime
, 0);
2883 KeWaitForSingleObject(&Timer
, Executive
, KernelMode
, FALSE
, 0);
2891 NdisMSynchronizeWithInterrupt(
2892 IN PNDIS_MINIPORT_INTERRUPT Interrupt
,
2893 IN PVOID SynchronizeFunction
,
2894 IN PVOID SynchronizeContext
)
2896 return(KeSynchronizeExecution(Interrupt
->InterruptObject
,
2897 (PKSYNCHRONIZE_ROUTINE
)SynchronizeFunction
,
2898 SynchronizeContext
));
2907 IN NDIS_HANDLE LogHandle
,
2909 IN UINT LogBufferSize
)
2911 PUCHAR Buffer
= LogBuffer
;
2915 for (i
= 0; i
< LogBufferSize
; i
+= 16)
2917 DbgPrint("%08x |", i
);
2918 for (j
= 0; j
< 16; j
++)
2921 if (idx
< LogBufferSize
)
2922 DbgPrint(" %02x", Buffer
[idx
]);
2927 for (j
= 0; j
< 16; j
++)
2930 if (idx
== LogBufferSize
)
2932 if (Buffer
[idx
] >= ' ') /* FIXME: not portable! replace by if (isprint(Buffer[idx])) ? */
2933 DbgPrint("%c", Buffer
[idx
]);
2940 return NDIS_STATUS_FAILURE
;
2948 NdisTerminateWrapper(
2949 IN NDIS_HANDLE NdisWrapperHandle
,
2950 IN PVOID SystemSpecific
)
2952 * FUNCTION: Releases resources allocated by a call to NdisInitializeWrapper
2954 * NdisWrapperHandle = Handle returned by NdisInitializeWrapper (NDIS_M_DRIVER_BLOCK)
2955 * SystemSpecific = Always NULL
2958 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2960 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2962 ExFreePool(Miniport
->RegistryPath
->Buffer
);
2963 ExFreePool(Miniport
->RegistryPath
);
2964 ExInterlockedRemoveEntryList(&Miniport
->ListEntry
, &MiniportListLock
);
2965 ExFreePool(Miniport
);
2974 NdisMQueryAdapterInstanceName(
2975 OUT PNDIS_STRING AdapterInstanceName
,
2976 IN NDIS_HANDLE MiniportAdapterHandle
)
2984 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
2985 UNICODE_STRING AdapterName
;
2987 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2989 AdapterName
.Length
= 0;
2990 AdapterName
.MaximumLength
= Adapter
->NdisMiniportBlock
.MiniportName
.MaximumLength
;
2991 AdapterName
.Buffer
= ExAllocatePool(PagedPool
, AdapterName
.MaximumLength
);
2992 if (!AdapterName
.Buffer
) {
2993 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
2994 return NDIS_STATUS_RESOURCES
;
2997 RtlCopyUnicodeString(&AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
);
2999 *AdapterInstanceName
= AdapterName
;
3001 return NDIS_STATUS_SUCCESS
;
3009 NdisDeregisterAdapterShutdownHandler(
3010 IN NDIS_HANDLE NdisAdapterHandle
)
3018 NdisMDeregisterAdapterShutdownHandler(NdisAdapterHandle
);
3027 NdisRegisterAdapterShutdownHandler(
3028 IN NDIS_HANDLE NdisAdapterHandle
,
3029 IN PVOID ShutdownContext
,
3030 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
3038 NdisMRegisterAdapterShutdownHandler(NdisAdapterHandle
,
3048 NdisMGetDeviceProperty(
3049 IN NDIS_HANDLE MiniportAdapterHandle
,
3050 IN OUT PDEVICE_OBJECT
*PhysicalDeviceObject OPTIONAL
,
3051 IN OUT PDEVICE_OBJECT
*FunctionalDeviceObject OPTIONAL
,
3052 IN OUT PDEVICE_OBJECT
*NextDeviceObject OPTIONAL
,
3053 IN OUT PCM_RESOURCE_LIST
*AllocatedResources OPTIONAL
,
3054 IN OUT PCM_RESOURCE_LIST
*AllocatedResourcesTranslated OPTIONAL
)
3062 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
3064 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
3066 if (PhysicalDeviceObject
!= NULL
)
3067 *PhysicalDeviceObject
= Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
;
3069 if (FunctionalDeviceObject
!= NULL
)
3070 *FunctionalDeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
3072 if (NextDeviceObject
!= NULL
)
3073 *NextDeviceObject
= Adapter
->NdisMiniportBlock
.NextDeviceObject
;
3075 if (AllocatedResources
!= NULL
)
3076 *AllocatedResources
= Adapter
->NdisMiniportBlock
.AllocatedResources
;
3078 if (AllocatedResourcesTranslated
!= NULL
)
3079 *AllocatedResourcesTranslated
= Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
;
3087 NdisMRegisterUnloadHandler(
3088 IN NDIS_HANDLE NdisWrapperHandle
,
3089 IN PDRIVER_UNLOAD UnloadHandler
)
3097 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
3099 NDIS_DbgPrint(MAX_TRACE
, ("Miniport registered unload handler\n"));
3101 DriverBlock
->DriverObject
->DriverUnload
= UnloadHandler
;
3109 NdisMRegisterDevice(
3110 IN NDIS_HANDLE NdisWrapperHandle
,
3111 IN PNDIS_STRING DeviceName
,
3112 IN PNDIS_STRING SymbolicName
,
3113 IN PDRIVER_DISPATCH MajorFunctions
[],
3114 OUT PDEVICE_OBJECT
*pDeviceObject
,
3115 OUT NDIS_HANDLE
*NdisDeviceHandle
)
3123 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
3124 PNDIS_M_DEVICE_BLOCK DeviceBlock
;
3125 PDEVICE_OBJECT DeviceObject
;
3129 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
3131 Status
= IoCreateDevice(DriverBlock
->DriverObject
,
3132 sizeof(NDIS_M_DEVICE_BLOCK
),
3134 FILE_DEVICE_NETWORK
,
3139 if (!NT_SUCCESS(Status
))
3141 NDIS_DbgPrint(MIN_TRACE
, ("IoCreateDevice failed (%x)\n", Status
));
3145 Status
= IoCreateSymbolicLink(SymbolicName
, DeviceName
);
3147 if (!NT_SUCCESS(Status
))
3149 NDIS_DbgPrint(MIN_TRACE
, ("IoCreateSymbolicLink failed (%x)\n", Status
));
3150 IoDeleteDevice(DeviceObject
);
3154 DeviceBlock
= DeviceObject
->DeviceExtension
;
3158 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
3159 IoDeleteDevice(DeviceObject
);
3160 IoDeleteSymbolicLink(SymbolicName
);
3161 return NDIS_STATUS_RESOURCES
;
3164 for (i
= 0; i
<= IRP_MJ_MAXIMUM_FUNCTION
; i
++)
3165 DeviceBlock
->MajorFunction
[i
] = MajorFunctions
[i
];
3167 DeviceBlock
->DeviceObject
= DeviceObject
;
3168 DeviceBlock
->SymbolicName
= SymbolicName
;
3170 *pDeviceObject
= DeviceObject
;
3171 *NdisDeviceHandle
= DeviceBlock
;
3173 return NDIS_STATUS_SUCCESS
;
3181 NdisMDeregisterDevice(
3182 IN NDIS_HANDLE NdisDeviceHandle
)
3190 PNDIS_M_DEVICE_BLOCK DeviceBlock
= NdisDeviceHandle
;
3192 IoDeleteDevice(DeviceBlock
->DeviceObject
);
3194 IoDeleteSymbolicLink(DeviceBlock
->SymbolicName
);
3196 return NDIS_STATUS_SUCCESS
;
3204 NdisQueryAdapterInstanceName(
3205 OUT PNDIS_STRING AdapterInstanceName
,
3206 IN NDIS_HANDLE NdisBindingHandle
)
3214 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3215 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3217 return NdisMQueryAdapterInstanceName(AdapterInstanceName
,
3226 NdisCompletePnPEvent(
3227 IN NDIS_STATUS Status
,
3228 IN NDIS_HANDLE NdisBindingHandle
,
3229 IN PNET_PNP_EVENT NetPnPEvent
)
3237 PIRP Irp
= (PIRP
)NetPnPEvent
->NdisReserved
[0];
3238 PLIST_ENTRY CurrentEntry
= (PLIST_ENTRY
)NetPnPEvent
->NdisReserved
[1];
3239 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3240 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3241 NDIS_STATUS NdisStatus
;
3243 if (Status
!= NDIS_STATUS_SUCCESS
)
3245 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3246 ExFreePool(NetPnPEvent
);
3247 Irp
->IoStatus
.Status
= Status
;
3248 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3252 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
3254 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
3256 NdisStatus
= (*AdapterBinding
->ProtocolBinding
->Chars
.PnPEventHandler
)(
3257 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
3260 if (NdisStatus
== NDIS_STATUS_PENDING
)
3262 NetPnPEvent
->NdisReserved
[1] = (ULONG_PTR
)CurrentEntry
->Flink
;
3265 else if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
3267 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3268 ExFreePool(NetPnPEvent
);
3269 Irp
->IoStatus
.Status
= NdisStatus
;
3270 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3274 CurrentEntry
= CurrentEntry
->Flink
;
3277 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3278 ExFreePool(NetPnPEvent
);
3280 Irp
->IoStatus
.Status
= NDIS_STATUS_SUCCESS
;
3281 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3289 NdisCancelSendPackets(
3290 IN NDIS_HANDLE NdisBindingHandle
,
3293 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3294 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3296 NDIS_DbgPrint(MAX_TRACE
, ("Called for ID %x.\n", CancelId
));
3298 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CancelSendPacketsHandler
)
3300 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CancelSendPacketsHandler
)(
3301 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
3312 NdisIMGetBindingContext(
3313 IN NDIS_HANDLE NdisBindingHandle
)
3321 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3322 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3324 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3326 return Adapter
->NdisMiniportBlock
.DeviceContext
;
3335 NdisIMGetDeviceContext(
3336 IN NDIS_HANDLE MiniportAdapterHandle
)
3344 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
3346 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3348 return Adapter
->NdisMiniportBlock
.DeviceContext
;