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
20 * Define to 1 to get a debugger breakpoint at the end of NdisInitializeWrapper
21 * for each new miniport starting up
23 #define BREAK_ON_MINIPORT_INIT 0
26 * This has to be big enough to hold the results of querying the Route value
27 * from the Linkage key. Please re-code me to determine this dynamically.
29 #define ROUTE_DATA_SIZE 256
31 /* Number of media we know */
32 #define MEDIA_ARRAY_SIZE 15
34 static NDIS_MEDIUM MediaArray
[MEDIA_ARRAY_SIZE
] =
43 NdisMediumArcnet878_2
,
45 NdisMediumWirelessWan
,
53 /* global list and lock of Miniports NDIS has registered */
54 LIST_ENTRY MiniportListHead
;
55 KSPIN_LOCK MiniportListLock
;
57 /* global list and lock of adapters NDIS has registered */
58 LIST_ENTRY AdapterListHead
;
59 KSPIN_LOCK AdapterListLock
;
68 if ((DebugTraceLevel
& DEBUG_PACKET
) > 0) {
69 Length
= CopyPacketToBuffer(
75 DbgPrint("*** PACKET START ***");
77 for (i
= 0; i
< Length
; i
++) {
79 DbgPrint("\n%04X ", i
);
80 DbgPrint("%02X ", Buffer
[i
]);
83 DbgPrint("*** PACKET STOP ***\n");
91 UINT HeaderBufferSize
,
92 PVOID LookaheadBuffer
,
93 UINT LookaheadBufferSize
)
96 if ((DebugTraceLevel
& DEBUG_PACKET
) > 0) {
100 DbgPrint("*** RECEIVE PACKET START ***\n");
103 for (i
= 0; i
< HeaderBufferSize
; i
++) {
105 DbgPrint("\n%04X ", i
);
106 DbgPrint("%02X ", *p
++);
109 DbgPrint("\nFRAME:");
112 Length
= (LookaheadBufferSize
< 64)? LookaheadBufferSize
: 64;
113 for (i
= 0; i
< Length
; i
++) {
115 DbgPrint("\n%04X ", i
);
116 DbgPrint("%02X ", *p
++);
119 DbgPrint("\n*** RECEIVE PACKET STOP ***\n");
124 PNDIS_MINIPORT_WORK_ITEM
125 MiniGetFirstWorkItem(
126 PLOGICAL_ADAPTER Adapter
,
127 NDIS_WORK_ITEM_TYPE Type
)
129 PNDIS_MINIPORT_WORK_ITEM CurrentEntry
= Adapter
->WorkQueueHead
;
133 if (CurrentEntry
->WorkItemType
== Type
)
136 CurrentEntry
= (PNDIS_MINIPORT_WORK_ITEM
)CurrentEntry
->Link
.Next
;
144 PLOGICAL_ADAPTER Adapter
,
145 NDIS_WORK_ITEM_TYPE Type
)
147 BOOLEAN Busy
= FALSE
;
150 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
152 if (Type
== NdisWorkItemRequest
&&
153 (Adapter
->NdisMiniportBlock
.PendingRequest
|| MiniGetFirstWorkItem(Adapter
, NdisWorkItemRequest
)))
157 else if (Type
== NdisWorkItemSend
&&
158 (Adapter
->NdisMiniportBlock
.FirstPendingPacket
|| MiniGetFirstWorkItem(Adapter
, NdisWorkItemSend
)))
162 else if (Type
== NdisWorkItemResetRequested
&&
163 (Adapter
->NdisMiniportBlock
.ResetStatus
== NDIS_STATUS_PENDING
|| MiniGetFirstWorkItem(Adapter
, NdisWorkItemResetRequested
)))
168 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"));
253 MiniIndicateReceivePacket(
254 IN NDIS_HANDLE MiniportAdapterHandle
,
255 IN PPNDIS_PACKET PacketArray
,
256 IN UINT NumberOfPackets
)
258 * FUNCTION: receives miniport packet array indications
260 * MiniportAdapterHandle: Miniport handle for the adapter
261 * PacketArray: pointer to a list of packet pointers to indicate
262 * NumberOfPackets: number of packets to indicate
266 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
267 PLIST_ENTRY CurrentEntry
;
268 PADAPTER_BINDING AdapterBinding
;
272 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
274 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
276 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
278 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
280 for (i
= 0; i
< NumberOfPackets
; i
++)
282 if (AdapterBinding
->ProtocolBinding
->Chars
.ReceivePacketHandler
&&
283 NDIS_GET_PACKET_STATUS(PacketArray
[i
]) != NDIS_STATUS_RESOURCES
)
285 (*AdapterBinding
->ProtocolBinding
->Chars
.ReceivePacketHandler
)(
286 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
291 UINT FirstBufferLength
, TotalBufferLength
, LookAheadSize
, HeaderSize
;
292 PNDIS_BUFFER NdisBuffer
;
293 PVOID NdisBufferVA
, LookAheadBuffer
;
294 NDIS_STATUS NdisStatus
;
297 NdisGetFirstBufferFromPacket(PacketArray
[i
],
303 HeaderSize
= NDIS_GET_PACKET_HEADER_SIZE(PacketArray
[i
]);
305 if (Adapter
->NdisMiniportBlock
.CurrentLookahead
< (TotalBufferLength
- HeaderSize
))
307 LookAheadSize
= Adapter
->NdisMiniportBlock
.CurrentLookahead
;
311 LookAheadSize
= TotalBufferLength
- HeaderSize
;
315 LookAheadBuffer
= ExAllocatePool(NonPagedPool
, LookAheadSize
);
316 if (!LookAheadBuffer
)
318 NDIS_DbgPrint(MIN_TRACE
, ("Failed to allocate lookahead buffer!\n"));
319 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
323 CopyBufferChainToBuffer(LookAheadBuffer
,
328 NdisStatus
= (*AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
)(
329 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
330 AdapterBinding
->NdisOpenBlock
.MacHandle
,
335 TotalBufferLength
- HeaderSize
);
337 NDIS_SET_PACKET_STATUS(PacketArray
[i
], NdisStatus
);
339 ExFreePool(LookAheadBuffer
);
343 CurrentEntry
= CurrentEntry
->Flink
;
346 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
352 IN NDIS_HANDLE MiniportAdapterHandle
,
353 IN NDIS_STATUS Status
,
354 IN BOOLEAN AddressingReset
)
356 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
357 PLIST_ENTRY CurrentEntry
;
358 PADAPTER_BINDING AdapterBinding
;
362 MiniDoAddressingReset(Adapter
);
364 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
365 NdisMIndicateStatusComplete(Adapter
);
367 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
369 if (Adapter
->NdisMiniportBlock
.ResetStatus
!= NDIS_STATUS_PENDING
)
371 KeBugCheckEx(BUGCODE_ID_DRIVER
,
372 (ULONG_PTR
)MiniportAdapterHandle
,
374 (ULONG_PTR
)AddressingReset
,
378 Adapter
->NdisMiniportBlock
.ResetStatus
= Status
;
380 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
382 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
384 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
386 (*AdapterBinding
->ProtocolBinding
->Chars
.ResetCompleteHandler
)(
387 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
390 CurrentEntry
= CurrentEntry
->Flink
;
393 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
398 IN NDIS_HANDLE MiniportAdapterHandle
,
399 IN NDIS_STATUS Status
)
401 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
402 PNDIS_REQUEST Request
;
403 PNDIS_REQUEST_MAC_BLOCK MacBlock
;
406 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
408 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
410 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
411 Request
= Adapter
->NdisMiniportBlock
.PendingRequest
;
412 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
414 MacBlock
= (PNDIS_REQUEST_MAC_BLOCK
)Request
->MacReserved
;
416 if( MacBlock
->Binding
->RequestCompleteHandler
) {
417 (*MacBlock
->Binding
->RequestCompleteHandler
)(
418 MacBlock
->Binding
->ProtocolBindingContext
,
423 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
424 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
425 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
427 KeLowerIrql(OldIrql
);
432 IN NDIS_HANDLE MiniportAdapterHandle
,
433 IN PNDIS_PACKET Packet
,
434 IN NDIS_STATUS Status
)
436 * FUNCTION: Forwards a message to the initiating protocol saying
437 * that a packet was handled
439 * NdisAdapterHandle = Handle input to MiniportInitialize
440 * Packet = Pointer to NDIS packet that was sent
441 * Status = Status of send operation
444 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
445 PADAPTER_BINDING AdapterBinding
;
447 PSCATTER_GATHER_LIST SGList
;
449 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
451 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
453 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
455 if (Adapter
->NdisMiniportBlock
.ScatterGatherListSize
!= 0)
457 NDIS_DbgPrint(MAX_TRACE
, ("Freeing Scatter/Gather list\n"));
459 SGList
= NDIS_PER_PACKET_INFO_FROM_PACKET(Packet
,
460 ScatterGatherListPacketInfo
);
462 Adapter
->NdisMiniportBlock
.SystemAdapterObject
->
463 DmaOperations
->PutScatterGatherList(
464 Adapter
->NdisMiniportBlock
.SystemAdapterObject
,
468 NDIS_PER_PACKET_INFO_FROM_PACKET(Packet
,
469 ScatterGatherListPacketInfo
) = NULL
;
472 (*AdapterBinding
->ProtocolBinding
->Chars
.SendCompleteHandler
)(
473 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
477 KeLowerIrql(OldIrql
);
482 MiniSendResourcesAvailable(
483 IN NDIS_HANDLE MiniportAdapterHandle
)
492 MiniTransferDataComplete(
493 IN NDIS_HANDLE MiniportAdapterHandle
,
494 IN PNDIS_PACKET Packet
,
495 IN NDIS_STATUS Status
,
496 IN UINT BytesTransferred
)
498 PADAPTER_BINDING AdapterBinding
;
501 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
503 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
505 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
506 (*AdapterBinding
->ProtocolBinding
->Chars
.TransferDataCompleteHandler
)(
507 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
511 KeLowerIrql(OldIrql
);
516 MiniAdapterHasAddress(
517 PLOGICAL_ADAPTER Adapter
,
520 * FUNCTION: Determines whether a packet has the same destination address as an adapter
522 * Adapter = Pointer to logical adapter object
523 * Packet = Pointer to NDIS packet
525 * TRUE if the destination address is that of the adapter, FALSE if not
531 PNDIS_BUFFER NdisBuffer
;
534 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
539 NDIS_DbgPrint(MIN_TRACE
, ("Adapter object was null\n"));
545 NDIS_DbgPrint(MIN_TRACE
, ("Packet was null\n"));
550 NdisQueryPacket(Packet
, NULL
, NULL
, &NdisBuffer
, NULL
);
554 NDIS_DbgPrint(MIN_TRACE
, ("Packet contains no buffers.\n"));
558 NdisQueryBuffer(NdisBuffer
, (PVOID
)&Start2
, &BufferLength
);
560 /* FIXME: Should handle fragmented packets */
562 switch (Adapter
->NdisMiniportBlock
.MediaType
)
564 case NdisMedium802_3
:
565 Length
= ETH_LENGTH_OF_ADDRESS
;
566 /* Destination address is the first field */
570 NDIS_DbgPrint(MIN_TRACE
, ("Adapter has unsupported media type (0x%X).\n", Adapter
->NdisMiniportBlock
.MediaType
));
574 if (BufferLength
< Length
)
576 NDIS_DbgPrint(MIN_TRACE
, ("Buffer is too small.\n"));
580 Start1
= (PUCHAR
)&Adapter
->Address
;
581 NDIS_DbgPrint(MAX_TRACE
, ("packet address: %x:%x:%x:%x:%x:%x adapter address: %x:%x:%x:%x:%x:%x\n",
582 *((char *)Start1
), *(((char *)Start1
)+1), *(((char *)Start1
)+2), *(((char *)Start1
)+3), *(((char *)Start1
)+4), *(((char *)Start1
)+5),
583 *((char *)Start2
), *(((char *)Start2
)+1), *(((char *)Start2
)+2), *(((char *)Start2
)+3), *(((char *)Start2
)+4), *(((char *)Start2
)+5))
586 return (RtlCompareMemory((PVOID
)Start1
, (PVOID
)Start2
, Length
) == Length
);
592 PNDIS_STRING AdapterName
)
594 * FUNCTION: Finds an adapter object by name
596 * AdapterName = Pointer to name of adapter
598 * Pointer to logical adapter object, or NULL if none was found.
599 * If found, the adapter is referenced for the caller. The caller
600 * is responsible for dereferencing after use
604 PLIST_ENTRY CurrentEntry
;
605 PLOGICAL_ADAPTER Adapter
= 0;
609 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
611 if(IsListEmpty(&AdapterListHead
))
613 NDIS_DbgPrint(MIN_TRACE
, ("No registered miniports for protocol to bind to\n"));
617 KeAcquireSpinLock(&AdapterListLock
, &OldIrql
);
619 CurrentEntry
= AdapterListHead
.Flink
;
621 while (CurrentEntry
!= &AdapterListHead
)
623 Adapter
= CONTAINING_RECORD(CurrentEntry
, LOGICAL_ADAPTER
, ListEntry
);
627 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Examining adapter 0x%lx\n", Adapter
));
628 NDIS_DbgPrint(DEBUG_MINIPORT
, ("AdapterName = %wZ\n", AdapterName
));
629 NDIS_DbgPrint(DEBUG_MINIPORT
, ("DeviceName = %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
631 if (RtlCompareUnicodeString(AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
, TRUE
) == 0)
637 CurrentEntry
= CurrentEntry
->Flink
;
640 KeReleaseSpinLock(&AdapterListLock
, OldIrql
);
644 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Leaving. Adapter found at 0x%x\n", Adapter
));
648 NDIS_DbgPrint(MIN_TRACE
, ("Leaving (adapter not found for %wZ).\n", AdapterName
));
656 PLOGICAL_ADAPTER Adapter
,
662 NDIS_STATUS NdisStatus
;
663 PNDIS_REQUEST NdisRequest
;
665 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
667 NdisRequest
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_REQUEST
));
669 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
670 return NDIS_STATUS_RESOURCES
;
673 RtlZeroMemory(NdisRequest
, sizeof(NDIS_REQUEST
));
675 NdisRequest
->RequestType
= NdisRequestSetInformation
;
676 NdisRequest
->DATA
.SET_INFORMATION
.Oid
= Oid
;
677 NdisRequest
->DATA
.SET_INFORMATION
.InformationBuffer
= Buffer
;
678 NdisRequest
->DATA
.SET_INFORMATION
.InformationBufferLength
= Size
;
680 NdisStatus
= MiniDoRequest(Adapter
, NdisRequest
);
682 /* FIXME: Wait in pending case! */
684 ASSERT(NdisStatus
!= NDIS_STATUS_PENDING
);
686 *BytesRead
= NdisRequest
->DATA
.SET_INFORMATION
.BytesRead
;
688 ExFreePool(NdisRequest
);
694 MiniQueryInformation(
695 PLOGICAL_ADAPTER Adapter
,
701 * FUNCTION: Queries a logical adapter for properties
703 * Adapter = Pointer to the logical adapter object to query
704 * Oid = Specifies the Object ID to query for
705 * Size = Size of the passed buffer
706 * Buffer = Buffer for the output
707 * BytesWritten = Address of buffer to place number of bytes written
709 * Status of operation
712 NDIS_STATUS NdisStatus
;
713 PNDIS_REQUEST NdisRequest
;
715 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
717 NdisRequest
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_REQUEST
));
719 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
720 return NDIS_STATUS_RESOURCES
;
723 RtlZeroMemory(NdisRequest
, sizeof(NDIS_REQUEST
));
725 NdisRequest
->RequestType
= NdisRequestQueryInformation
;
726 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
= Oid
;
727 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
= Buffer
;
728 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
= Size
;
730 NdisStatus
= MiniDoRequest(Adapter
, NdisRequest
);
732 /* FIXME: Wait in pending case! */
734 ASSERT(NdisStatus
!= NDIS_STATUS_PENDING
);
736 *BytesWritten
= NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
;
738 ExFreePool(NdisRequest
);
744 MiniCheckForHang( PLOGICAL_ADAPTER Adapter
)
746 * FUNCTION: Checks to see if the miniport is hung
748 * Adapter = Pointer to the logical adapter object
750 * TRUE if the miniport is hung
751 * FALSE if the miniport is not hung
757 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
758 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)
759 Ret
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)(
760 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
);
761 KeLowerIrql(OldIrql
);
767 MiniDoAddressingReset(PLOGICAL_ADAPTER Adapter
)
771 MiniSetInformation(Adapter
,
772 OID_GEN_CURRENT_LOOKAHEAD
,
774 &Adapter
->NdisMiniportBlock
.CurrentLookahead
,
777 /* FIXME: Set more stuff */
782 PLOGICAL_ADAPTER Adapter
)
784 * FUNCTION: Resets the miniport
786 * Adapter = Pointer to the logical adapter object
788 * Status of the operation
793 BOOLEAN AddressingReset
= TRUE
;
795 if (MiniIsBusy(Adapter
, NdisWorkItemResetRequested
)) {
796 MiniQueueWorkItem(Adapter
, NdisWorkItemResetRequested
, NULL
, FALSE
);
797 return NDIS_STATUS_PENDING
;
800 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
801 NdisMIndicateStatusComplete(Adapter
);
803 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
804 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
805 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
808 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
809 Adapter
->NdisMiniportBlock
.ResetStatus
= Status
;
810 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
812 KeLowerIrql(OldIrql
);
814 if (Status
!= NDIS_STATUS_PENDING
) {
816 MiniDoAddressingReset(Adapter
);
818 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
819 NdisMIndicateStatusComplete(Adapter
);
828 PVOID DeferredContext
,
829 PVOID SystemArgument1
,
830 PVOID SystemArgument2
)
832 PLOGICAL_ADAPTER Adapter
= DeferredContext
;
834 if (MiniCheckForHang(Adapter
)) {
835 NDIS_DbgPrint(MIN_TRACE
, ("Miniport detected adapter hang\n"));
844 PLOGICAL_ADAPTER Adapter
,
845 NDIS_WORK_ITEM_TYPE WorkItemType
,
846 PVOID WorkItemContext
,
849 * FUNCTION: Queues a work item for execution at a later time
851 * Adapter = Pointer to the logical adapter object to queue work item on
852 * WorkItemType = Type of work item to queue
853 * WorkItemContext = Pointer to context information for work item
855 * Status of operation
858 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
859 PIO_WORKITEM IoWorkItem
;
862 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
866 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
869 if (WorkItemType
== NdisWorkItemSend
)
871 NDIS_DbgPrint(MIN_TRACE
, ("Requeuing failed packet (%x).\n", WorkItemContext
));
872 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= WorkItemContext
;
876 //This should never happen
882 MiniportWorkItem
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_MINIPORT_WORK_ITEM
));
883 if (!MiniportWorkItem
)
885 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
886 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
890 MiniportWorkItem
->WorkItemType
= WorkItemType
;
891 MiniportWorkItem
->WorkItemContext
= WorkItemContext
;
893 /* safe due to adapter lock held */
894 MiniportWorkItem
->Link
.Next
= NULL
;
895 if (!Adapter
->WorkQueueHead
)
897 Adapter
->WorkQueueHead
= MiniportWorkItem
;
898 Adapter
->WorkQueueTail
= MiniportWorkItem
;
902 Adapter
->WorkQueueTail
->Link
.Next
= (PSINGLE_LIST_ENTRY
)MiniportWorkItem
;
903 Adapter
->WorkQueueTail
= MiniportWorkItem
;
907 IoWorkItem
= IoAllocateWorkItem(Adapter
->NdisMiniportBlock
.DeviceObject
);
909 IoQueueWorkItem(IoWorkItem
, MiniportWorker
, DelayedWorkQueue
, IoWorkItem
);
911 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
918 PLOGICAL_ADAPTER Adapter
,
919 NDIS_WORK_ITEM_TYPE
*WorkItemType
,
920 PVOID
*WorkItemContext
)
922 * FUNCTION: Dequeues a work item from the work queue of a logical adapter
924 * Adapter = Pointer to the logical adapter object to dequeue work item from
925 * AdapterBinding = Address of buffer for adapter binding for this request
926 * WorkItemType = Address of buffer for work item type
927 * WorkItemContext = Address of buffer for pointer to context information
929 * Adapter lock must be held when called
931 * Status of operation
934 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
937 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
939 MiniportWorkItem
= Adapter
->WorkQueueHead
;
941 if ((Packet
= Adapter
->NdisMiniportBlock
.FirstPendingPacket
))
943 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= NULL
;
945 *WorkItemType
= NdisWorkItemSend
;
946 *WorkItemContext
= Packet
;
948 return NDIS_STATUS_SUCCESS
;
950 else if (MiniportWorkItem
)
952 /* safe due to adapter lock held */
953 Adapter
->WorkQueueHead
= (PNDIS_MINIPORT_WORK_ITEM
)MiniportWorkItem
->Link
.Next
;
955 if (MiniportWorkItem
== Adapter
->WorkQueueTail
)
956 Adapter
->WorkQueueTail
= NULL
;
958 *WorkItemType
= MiniportWorkItem
->WorkItemType
;
959 *WorkItemContext
= MiniportWorkItem
->WorkItemContext
;
961 ExFreePool(MiniportWorkItem
);
963 return NDIS_STATUS_SUCCESS
;
967 NDIS_DbgPrint(MIN_TRACE
, ("No work item to dequeue\n"));
969 return NDIS_STATUS_FAILURE
;
976 PLOGICAL_ADAPTER Adapter
,
977 PNDIS_REQUEST NdisRequest
)
979 * FUNCTION: Sends a request to a miniport
981 * AdapterBinding = Pointer to binding used in the request
982 * NdisRequest = Pointer to NDIS request structure describing request
984 * Status of operation
989 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
991 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
993 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
994 Adapter
->NdisMiniportBlock
.PendingRequest
= NdisRequest
;
995 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
997 if (!Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CoRequestHandler
)
999 switch (NdisRequest
->RequestType
)
1001 case NdisRequestQueryInformation
:
1002 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.QueryInformationHandler
)(
1003 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1004 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
,
1005 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
,
1006 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
,
1007 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
,
1008 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesNeeded
);
1011 case NdisRequestSetInformation
:
1012 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SetInformationHandler
)(
1013 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1014 NdisRequest
->DATA
.SET_INFORMATION
.Oid
,
1015 NdisRequest
->DATA
.SET_INFORMATION
.InformationBuffer
,
1016 NdisRequest
->DATA
.SET_INFORMATION
.InformationBufferLength
,
1017 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesRead
,
1018 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesNeeded
);
1022 NDIS_DbgPrint(MIN_TRACE
, ("Bad request type\n"));
1023 Status
= NDIS_STATUS_FAILURE
;
1028 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CoRequestHandler
)(
1029 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1034 if (Status
!= NDIS_STATUS_PENDING
) {
1035 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1036 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
1037 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1040 KeLowerIrql(OldIrql
);
1048 #undef NdisMSetInformationComplete
1051 NdisMSetInformationComplete(
1052 IN NDIS_HANDLE MiniportAdapterHandle
,
1053 IN NDIS_STATUS Status
)
1055 PLOGICAL_ADAPTER Adapter
=
1056 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
1059 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1060 if (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)
1061 (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)(MiniportAdapterHandle
, Status
);
1062 KeLowerIrql(OldIrql
);
1069 #undef NdisMQueryInformationComplete
1072 NdisMQueryInformationComplete(
1073 IN NDIS_HANDLE MiniportAdapterHandle
,
1074 IN NDIS_STATUS Status
)
1076 PLOGICAL_ADAPTER Adapter
=
1077 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
1080 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1081 if( Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)
1082 (Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)(MiniportAdapterHandle
, Status
);
1083 KeLowerIrql(OldIrql
);
1088 MiniportWorker(IN PDEVICE_OBJECT DeviceObject
, IN PVOID Context
)
1090 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
1091 KIRQL OldIrql
, RaiseOldIrql
;
1092 NDIS_STATUS NdisStatus
;
1093 PVOID WorkItemContext
;
1094 NDIS_WORK_ITEM_TYPE WorkItemType
;
1095 BOOLEAN AddressingReset
;
1097 IoFreeWorkItem((PIO_WORKITEM
)Context
);
1099 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1103 (Adapter
, &WorkItemType
, &WorkItemContext
);
1105 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1107 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1109 switch (WorkItemType
)
1111 case NdisWorkItemSend
:
1113 * called by ProSend when protocols want to send packets to the miniport
1116 if(Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)
1118 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1120 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1121 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1122 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1123 NdisStatus
= NDIS_STATUS_PENDING
;
1127 /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */
1128 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1130 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1131 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1132 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1134 KeLowerIrql(RaiseOldIrql
);
1136 NdisStatus
= NDIS_GET_PACKET_STATUS((PNDIS_PACKET
)WorkItemContext
);
1137 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1138 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1145 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1147 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1148 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1149 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1150 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1151 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1155 /* Send is called at DISPATCH_LEVEL for all serialized miniports */
1156 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1157 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1158 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1159 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1160 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1161 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1162 KeLowerIrql(RaiseOldIrql
);
1163 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1164 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1170 if( NdisStatus
!= NDIS_STATUS_PENDING
) {
1172 ( Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1176 case NdisWorkItemSendLoopback
:
1178 * called by ProSend when protocols want to send loopback packets
1180 /* XXX atm ProIndicatePacket sends a packet up via the loopback adapter only */
1181 NdisStatus
= ProIndicatePacket(Adapter
, (PNDIS_PACKET
)WorkItemContext
);
1183 if( NdisStatus
!= NDIS_STATUS_PENDING
)
1184 MiniSendComplete((NDIS_HANDLE
)Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1187 case NdisWorkItemReturnPackets
:
1190 case NdisWorkItemResetRequested
:
1191 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
1192 NdisMIndicateStatusComplete(Adapter
);
1194 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1195 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
1196 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1199 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1200 Adapter
->NdisMiniportBlock
.ResetStatus
= NdisStatus
;
1201 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1203 KeLowerIrql(OldIrql
);
1205 if (NdisStatus
!= NDIS_STATUS_PENDING
)
1206 MiniResetComplete(Adapter
, NdisStatus
, AddressingReset
);
1209 case NdisWorkItemResetInProgress
:
1212 case NdisWorkItemMiniportCallback
:
1215 case NdisWorkItemRequest
:
1216 NdisStatus
= MiniDoRequest(Adapter
, (PNDIS_REQUEST
)WorkItemContext
);
1218 if (NdisStatus
== NDIS_STATUS_PENDING
)
1221 switch (((PNDIS_REQUEST
)WorkItemContext
)->RequestType
)
1223 case NdisRequestQueryInformation
:
1224 NdisMQueryInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1227 case NdisRequestSetInformation
:
1228 NdisMSetInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1232 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS request type.\n"));
1238 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS work item type (%d).\n", WorkItemType
));
1249 IN NDIS_HANDLE MiniportHandle
,
1250 IN NDIS_STATUS GeneralStatus
,
1251 IN PVOID StatusBuffer
,
1252 IN UINT StatusBufferSize
)
1254 PLOGICAL_ADAPTER Adapter
= MiniportHandle
;
1255 PLIST_ENTRY CurrentEntry
;
1256 PADAPTER_BINDING AdapterBinding
;
1259 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1261 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1263 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1265 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1267 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusHandler
)(
1268 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
1273 CurrentEntry
= CurrentEntry
->Flink
;
1276 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1283 IN NDIS_HANDLE MiniportAdapterHandle
)
1285 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1286 PLIST_ENTRY CurrentEntry
;
1287 PADAPTER_BINDING AdapterBinding
;
1290 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1292 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1294 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1296 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1298 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusCompleteHandler
)(
1299 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
);
1301 CurrentEntry
= CurrentEntry
->Flink
;
1304 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1314 IN NDIS_HANDLE LogHandle
)
1316 PNDIS_LOG Log
= (PNDIS_LOG
)LogHandle
;
1317 PNDIS_MINIPORT_BLOCK Miniport
= Log
->Miniport
;
1320 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1322 KeAcquireSpinLock(&(Miniport
)->Lock
, &OldIrql
);
1323 Miniport
->Log
= NULL
;
1324 KeReleaseSpinLock(&(Miniport
)->Lock
, OldIrql
);
1335 IN NDIS_HANDLE MiniportAdapterHandle
,
1337 OUT PNDIS_HANDLE LogHandle
)
1339 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1343 NDIS_DbgPrint(MAX_TRACE
, ("called: MiniportAdapterHandle 0x%x, Size %ld\n", MiniportAdapterHandle
, Size
));
1345 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1347 if (Adapter
->NdisMiniportBlock
.Log
)
1350 return NDIS_STATUS_FAILURE
;
1353 Log
= ExAllocatePool(NonPagedPool
, Size
+ sizeof(NDIS_LOG
));
1357 return NDIS_STATUS_RESOURCES
;
1360 Adapter
->NdisMiniportBlock
.Log
= Log
;
1362 KeInitializeSpinLock(&Log
->LogLock
);
1364 Log
->Miniport
= &Adapter
->NdisMiniportBlock
;
1365 Log
->TotalSize
= Size
;
1366 Log
->CurrentSize
= 0;
1373 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1375 return NDIS_STATUS_SUCCESS
;
1383 NdisMDeregisterAdapterShutdownHandler(
1384 IN NDIS_HANDLE MiniportHandle
)
1386 * FUNCTION: de-registers a shutdown handler
1387 * ARGUMENTS: MiniportHandle: Handle passed into MiniportInitialize
1390 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1392 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1394 if(Adapter
->BugcheckContext
->ShutdownHandler
) {
1395 KeDeregisterBugCheckCallback(Adapter
->BugcheckContext
->CallbackRecord
);
1396 IoUnregisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1406 IN NDIS_HANDLE LogHandle
)
1408 PNDIS_LOG Log
= (PNDIS_LOG
) LogHandle
;
1411 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1414 KeAcquireSpinLock(&Log
->LogLock
, &OldIrql
);
1416 /* Set buffers size */
1417 Log
->CurrentSize
= 0;
1422 KeReleaseSpinLock(&Log
->LogLock
, OldIrql
);
1428 #undef NdisMIndicateStatus
1431 NdisMIndicateStatus(
1432 IN NDIS_HANDLE MiniportAdapterHandle
,
1433 IN NDIS_STATUS GeneralStatus
,
1434 IN PVOID StatusBuffer
,
1435 IN UINT StatusBufferSize
)
1437 MiniStatus(MiniportAdapterHandle
, GeneralStatus
, StatusBuffer
, StatusBufferSize
);
1443 #undef NdisMIndicateStatusComplete
1446 NdisMIndicateStatusComplete(
1447 IN NDIS_HANDLE MiniportAdapterHandle
)
1449 MiniStatusComplete(MiniportAdapterHandle
);
1458 NdisInitializeWrapper(
1459 OUT PNDIS_HANDLE NdisWrapperHandle
,
1460 IN PVOID SystemSpecific1
,
1461 IN PVOID SystemSpecific2
,
1462 IN PVOID SystemSpecific3
)
1464 * FUNCTION: Notifies the NDIS library that a new miniport is initializing
1466 * NdisWrapperHandle = Address of buffer to place NDIS wrapper handle
1467 * SystemSpecific1 = Pointer to the driver's driver object
1468 * SystemSpecific2 = Pointer to the driver's registry path
1469 * SystemSpecific3 = Always NULL
1471 * - SystemSpecific2 goes invalid so we copy it
1474 PNDIS_M_DRIVER_BLOCK Miniport
;
1475 PUNICODE_STRING RegistryPath
;
1476 WCHAR
*RegistryBuffer
;
1478 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1480 ASSERT(NdisWrapperHandle
);
1482 *NdisWrapperHandle
= NULL
;
1484 #if BREAK_ON_MINIPORT_INIT
1488 Miniport
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DRIVER_BLOCK
));
1492 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1496 RtlZeroMemory(Miniport
, sizeof(NDIS_M_DRIVER_BLOCK
));
1498 KeInitializeSpinLock(&Miniport
->Lock
);
1500 Miniport
->DriverObject
= (PDRIVER_OBJECT
)SystemSpecific1
;
1502 /* set the miniport's driver registry path */
1503 RegistryPath
= ExAllocatePool(PagedPool
, sizeof(UNICODE_STRING
));
1506 ExFreePool(Miniport
);
1507 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1511 RegistryPath
->Length
= ((PUNICODE_STRING
)SystemSpecific2
)->Length
;
1512 RegistryPath
->MaximumLength
= RegistryPath
->Length
+ sizeof(WCHAR
); /* room for 0-term */
1514 RegistryBuffer
= ExAllocatePool(PagedPool
, RegistryPath
->MaximumLength
);
1517 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1518 ExFreePool(Miniport
);
1519 ExFreePool(RegistryPath
);
1523 RtlCopyMemory(RegistryBuffer
, ((PUNICODE_STRING
)SystemSpecific2
)->Buffer
, RegistryPath
->Length
);
1524 RegistryBuffer
[RegistryPath
->Length
/sizeof(WCHAR
)] = 0;
1526 RegistryPath
->Buffer
= RegistryBuffer
;
1527 Miniport
->RegistryPath
= RegistryPath
;
1529 InitializeListHead(&Miniport
->DeviceList
);
1531 /* Put miniport in global miniport list */
1532 ExInterlockedInsertTailList(&MiniportListHead
, &Miniport
->ListEntry
, &MiniportListLock
);
1534 *NdisWrapperHandle
= Miniport
;
1538 VOID NTAPI
NdisIBugcheckCallback(
1542 * FUNCTION: Internal callback for handling bugchecks - calls adapter's shutdown handler
1544 * Buffer: Pointer to a bugcheck callback context
1548 PMINIPORT_BUGCHECK_CONTEXT Context
= (PMINIPORT_BUGCHECK_CONTEXT
)Buffer
;
1549 ADAPTER_SHUTDOWN_HANDLER sh
= (ADAPTER_SHUTDOWN_HANDLER
)Context
->ShutdownHandler
;
1551 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1554 sh(Context
->DriverContext
);
1563 NdisMRegisterAdapterShutdownHandler(
1564 IN NDIS_HANDLE MiniportHandle
,
1565 IN PVOID ShutdownContext
,
1566 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
1568 * FUNCTION: Register a shutdown handler for an adapter
1570 * MiniportHandle: Handle originally passed into MiniportInitialize
1571 * ShutdownContext: Pre-initialized bugcheck context
1572 * ShutdownHandler: Function to call to handle the bugcheck
1574 * - I'm not sure about ShutdownContext
1577 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1578 PMINIPORT_BUGCHECK_CONTEXT BugcheckContext
;
1580 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1582 BugcheckContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_BUGCHECK_CONTEXT
));
1583 if(!BugcheckContext
)
1585 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1589 BugcheckContext
->ShutdownHandler
= ShutdownHandler
;
1590 BugcheckContext
->DriverContext
= ShutdownContext
;
1592 BugcheckContext
->CallbackRecord
= ExAllocatePool(NonPagedPool
, sizeof(KBUGCHECK_CALLBACK_RECORD
));
1593 if (!BugcheckContext
->CallbackRecord
) {
1594 ExFreePool(BugcheckContext
);
1598 Adapter
->BugcheckContext
= BugcheckContext
;
1600 KeInitializeCallbackRecord(BugcheckContext
->CallbackRecord
);
1602 KeRegisterBugCheckCallback(BugcheckContext
->CallbackRecord
, NdisIBugcheckCallback
,
1603 BugcheckContext
, sizeof(*BugcheckContext
), (PUCHAR
)"Ndis Miniport");
1605 IoRegisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1611 PLOGICAL_ADAPTER Adapter
,
1612 NDIS_OID AddressOID
)
1614 * FUNCTION: Queries miniport for information
1616 * Adapter = Pointer to logical adapter
1617 * AddressOID = OID to use to query for current address
1619 * Status of operation
1623 NDIS_STATUS NdisStatus
;
1625 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1627 /* Get MAC options for adapter */
1628 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAC_OPTIONS
, sizeof(UINT
),
1629 &Adapter
->NdisMiniportBlock
.MacOptions
,
1632 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1634 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAC_OPTIONS failed. NdisStatus (0x%X).\n", NdisStatus
));
1638 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MacOptions (0x%X).\n", Adapter
->NdisMiniportBlock
.MacOptions
));
1640 /* Get current hardware address of adapter */
1641 NdisStatus
= MiniQueryInformation(Adapter
, AddressOID
, Adapter
->AddressLength
,
1642 &Adapter
->Address
, &BytesWritten
);
1644 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1646 NDIS_DbgPrint(MIN_TRACE
, ("Address OID (0x%X) failed. NdisStatus (0x%X).\n", AddressOID
, NdisStatus
));
1654 PUCHAR A
= (PUCHAR
)&Adapter
->Address
.Type
.Medium802_3
;
1656 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]));
1660 /* Get maximum lookahead buffer size of adapter */
1661 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_LOOKAHEAD
, sizeof(ULONG
),
1662 &Adapter
->NdisMiniportBlock
.MaximumLookahead
, &BytesWritten
);
1664 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1666 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1670 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MaxLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.MaximumLookahead
));
1672 /* Get current lookahead buffer size of adapter */
1673 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_CURRENT_LOOKAHEAD
, sizeof(ULONG
),
1674 &Adapter
->NdisMiniportBlock
.CurrentLookahead
, &BytesWritten
);
1676 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1678 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_CURRENT_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1682 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_SEND_PACKETS
, sizeof(ULONG
),
1683 &Adapter
->NdisMiniportBlock
.MaxSendPackets
, &BytesWritten
);
1685 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1687 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_SEND_PACKETS failed. NdisStatus (0x%X).\n", NdisStatus
));
1689 /* Set it to 1 if it fails because some drivers don't support this (?)*/
1690 Adapter
->NdisMiniportBlock
.MaxSendPackets
= 1;
1693 NDIS_DbgPrint(DEBUG_MINIPORT
, ("CurLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.CurrentLookahead
));
1695 return STATUS_SUCCESS
;
1701 NdisIForwardIrpAndWaitCompletionRoutine(
1706 PKEVENT Event
= Context
;
1708 if (Irp
->PendingReturned
)
1709 KeSetEvent(Event
, IO_NO_INCREMENT
, FALSE
);
1711 return STATUS_MORE_PROCESSING_REQUIRED
;
1717 NdisIForwardIrpAndWait(PLOGICAL_ADAPTER Adapter
, PIRP Irp
)
1722 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1723 IoCopyCurrentIrpStackLocationToNext(Irp
);
1724 IoSetCompletionRoutine(Irp
, NdisIForwardIrpAndWaitCompletionRoutine
, &Event
,
1726 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
1727 if (Status
== STATUS_PENDING
)
1729 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1730 Status
= Irp
->IoStatus
.Status
;
1738 IN PDEVICE_OBJECT DeviceObject
,
1741 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1742 Irp
->IoStatus
.Information
= 0;
1744 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1746 return STATUS_SUCCESS
;
1752 NdisIPnPStartDevice(
1753 IN PDEVICE_OBJECT DeviceObject
,
1756 * FUNCTION: Handle the PnP start device event
1758 * DeviceObejct = Functional Device Object
1759 * Irp = IRP_MN_START_DEVICE I/O request packet
1761 * Status of operation
1764 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
1765 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1766 NDIS_WRAPPER_CONTEXT WrapperContext
;
1767 NDIS_STATUS NdisStatus
;
1768 NDIS_STATUS OpenErrorStatus
;
1770 UINT SelectedMediumIndex
= 0;
1771 NDIS_OID AddressOID
;
1772 BOOLEAN Success
= FALSE
;
1773 ULONG ResourceCount
;
1774 ULONG ResourceListSize
;
1775 UNICODE_STRING ParamName
;
1776 PNDIS_CONFIGURATION_PARAMETER ConfigParam
;
1777 NDIS_HANDLE ConfigHandle
;
1779 LARGE_INTEGER Timeout
;
1780 UINT MaxMulticastAddresses
;
1782 PLIST_ENTRY CurrentEntry
;
1783 PPROTOCOL_BINDING ProtocolBinding
;
1786 * Prepare wrapper context used by HW and configuration routines.
1789 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Start Device %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
1791 NDIS_DbgPrint(MAX_TRACE
, ("Inserting adapter 0x%x into adapter list\n", Adapter
));
1793 /* Put adapter in global adapter list */
1794 ExInterlockedInsertTailList(&AdapterListHead
, &Adapter
->ListEntry
, &AdapterListLock
);
1796 Status
= IoOpenDeviceRegistryKey(
1797 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
, PLUGPLAY_REGKEY_DRIVER
,
1798 KEY_ALL_ACCESS
, &WrapperContext
.RegistryHandle
);
1799 if (!NT_SUCCESS(Status
))
1801 NDIS_DbgPrint(MIN_TRACE
,("failed to open adapter-specific reg key\n"));
1802 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1806 NDIS_DbgPrint(MAX_TRACE
, ("opened device reg key\n"));
1808 WrapperContext
.DeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
1811 * Store the adapter resources used by HW routines such as
1812 * NdisMQueryAdapterResources.
1815 if (Stack
->Parameters
.StartDevice
.AllocatedResources
!= NULL
)
1817 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResources
->List
[0].
1818 PartialResourceList
.Count
;
1820 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1821 PartialDescriptors
[ResourceCount
]);
1823 Adapter
->NdisMiniportBlock
.AllocatedResources
=
1824 ExAllocatePool(PagedPool
, ResourceListSize
);
1825 if (Adapter
->NdisMiniportBlock
.AllocatedResources
== NULL
)
1827 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1828 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1829 return STATUS_INSUFFICIENT_RESOURCES
;
1832 Adapter
->NdisMiniportBlock
.Resources
=
1833 ExAllocatePool(PagedPool
, ResourceListSize
);
1834 if (!Adapter
->NdisMiniportBlock
.Resources
)
1836 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1837 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
1838 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
1839 return STATUS_INSUFFICIENT_RESOURCES
;
1842 RtlCopyMemory(Adapter
->NdisMiniportBlock
.Resources
,
1843 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1846 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResources
,
1847 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1851 if (Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
!= NULL
)
1853 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
->List
[0].
1854 PartialResourceList
.Count
;
1856 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1857 PartialDescriptors
[ResourceCount
]);
1859 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
=
1860 ExAllocatePool(PagedPool
, ResourceListSize
);
1861 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
== NULL
)
1863 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1864 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1865 return STATUS_INSUFFICIENT_RESOURCES
;
1868 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
,
1869 Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
,
1874 * Store the Bus Type, Bus Number and Slot information. It's used by
1875 * the hardware routines then.
1878 NdisOpenConfiguration(&NdisStatus
, &ConfigHandle
, (NDIS_HANDLE
)&WrapperContext
);
1879 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1881 NDIS_DbgPrint(MIN_TRACE
, ("Failed to open configuration key\n"));
1882 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1886 Size
= sizeof(ULONG
);
1887 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1888 DevicePropertyLegacyBusType
, Size
,
1889 &Adapter
->NdisMiniportBlock
.BusType
, &Size
);
1890 if (!NT_SUCCESS(Status
) || (INTERFACE_TYPE
)Adapter
->NdisMiniportBlock
.BusType
== InterfaceTypeUndefined
)
1892 NdisInitUnicodeString(&ParamName
, L
"BusType");
1893 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1894 &ParamName
, NdisParameterInteger
);
1895 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1896 Adapter
->NdisMiniportBlock
.BusType
= ConfigParam
->ParameterData
.IntegerData
;
1898 Adapter
->NdisMiniportBlock
.BusType
= Isa
;
1901 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1902 DevicePropertyBusNumber
, Size
,
1903 &Adapter
->NdisMiniportBlock
.BusNumber
, &Size
);
1904 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.BusNumber
== 0xFFFFFFF0)
1906 NdisInitUnicodeString(&ParamName
, L
"BusNumber");
1907 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1908 &ParamName
, NdisParameterInteger
);
1909 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1910 Adapter
->NdisMiniportBlock
.BusNumber
= ConfigParam
->ParameterData
.IntegerData
;
1912 Adapter
->NdisMiniportBlock
.BusNumber
= 0;
1914 WrapperContext
.BusNumber
= Adapter
->NdisMiniportBlock
.BusNumber
;
1916 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1917 DevicePropertyAddress
, Size
,
1918 &Adapter
->NdisMiniportBlock
.SlotNumber
, &Size
);
1919 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.SlotNumber
== (NDIS_INTERFACE_TYPE
)-1)
1921 NdisInitUnicodeString(&ParamName
, L
"SlotNumber");
1922 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1923 &ParamName
, NdisParameterInteger
);
1924 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1925 Adapter
->NdisMiniportBlock
.SlotNumber
= ConfigParam
->ParameterData
.IntegerData
;
1927 Adapter
->NdisMiniportBlock
.SlotNumber
= 0;
1931 /* Convert slotnumber to PCI_SLOT_NUMBER */
1932 ULONG PciSlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
1933 PCI_SLOT_NUMBER SlotNumber
;
1935 SlotNumber
.u
.AsULONG
= 0;
1936 SlotNumber
.u
.bits
.DeviceNumber
= (PciSlotNumber
>> 16) & 0xFFFF;
1937 SlotNumber
.u
.bits
.FunctionNumber
= PciSlotNumber
& 0xFFFF;
1939 Adapter
->NdisMiniportBlock
.SlotNumber
= SlotNumber
.u
.AsULONG
;
1941 WrapperContext
.SlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
1943 NdisCloseConfiguration(ConfigHandle
);
1945 /* Set handlers (some NDIS macros require these) */
1946 Adapter
->NdisMiniportBlock
.EthRxCompleteHandler
= EthFilterDprIndicateReceiveComplete
;
1947 Adapter
->NdisMiniportBlock
.EthRxIndicateHandler
= EthFilterDprIndicateReceive
;
1948 Adapter
->NdisMiniportBlock
.SendCompleteHandler
= MiniSendComplete
;
1949 Adapter
->NdisMiniportBlock
.SendResourcesHandler
= MiniSendResourcesAvailable
;
1950 Adapter
->NdisMiniportBlock
.ResetCompleteHandler
= MiniResetComplete
;
1951 Adapter
->NdisMiniportBlock
.TDCompleteHandler
= MiniTransferDataComplete
;
1952 Adapter
->NdisMiniportBlock
.PacketIndicateHandler
= MiniIndicateReceivePacket
;
1953 Adapter
->NdisMiniportBlock
.StatusHandler
= MiniStatus
;
1954 Adapter
->NdisMiniportBlock
.StatusCompleteHandler
= MiniStatusComplete
;
1955 Adapter
->NdisMiniportBlock
.SendPacketsHandler
= ProSendPackets
;
1956 Adapter
->NdisMiniportBlock
.QueryCompleteHandler
= MiniRequestComplete
;
1957 Adapter
->NdisMiniportBlock
.SetCompleteHandler
= MiniRequestComplete
;
1960 * Call MiniportInitialize.
1963 NDIS_DbgPrint(MID_TRACE
, ("calling MiniportInitialize\n"));
1964 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.InitializeHandler
)(
1965 &OpenErrorStatus
, &SelectedMediumIndex
, &MediaArray
[0],
1966 MEDIA_ARRAY_SIZE
, Adapter
, (NDIS_HANDLE
)&WrapperContext
);
1968 ZwClose(WrapperContext
.RegistryHandle
);
1970 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1972 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() failed for an adapter.\n"));
1973 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1974 if (Adapter
->NdisMiniportBlock
.Interrupt
)
1976 KeBugCheckEx(BUGCODE_ID_DRIVER
,
1978 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.Interrupt
,
1979 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.TimerQueue
,
1982 if (Adapter
->NdisMiniportBlock
.TimerQueue
)
1984 KeBugCheckEx(BUGCODE_ID_DRIVER
,
1986 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.Interrupt
,
1987 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.TimerQueue
,
1993 if (SelectedMediumIndex
>= MEDIA_ARRAY_SIZE
)
1995 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() selected a bad index\n"));
1996 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1997 return NDIS_STATUS_UNSUPPORTED_MEDIA
;
2000 Adapter
->NdisMiniportBlock
.MediaType
= MediaArray
[SelectedMediumIndex
];
2002 switch (Adapter
->NdisMiniportBlock
.MediaType
)
2004 case NdisMedium802_3
:
2005 Adapter
->MediumHeaderSize
= 14; /* XXX figure out what to do about LLC */
2006 AddressOID
= OID_802_3_CURRENT_ADDRESS
;
2007 Adapter
->AddressLength
= ETH_LENGTH_OF_ADDRESS
;
2008 NdisStatus
= DoQueries(Adapter
, AddressOID
);
2009 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
2011 NdisStatus
= MiniQueryInformation(Adapter
, OID_802_3_MAXIMUM_LIST_SIZE
, sizeof(UINT
),
2012 &MaxMulticastAddresses
, &BytesWritten
);
2014 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2016 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
2017 NDIS_DbgPrint(MIN_TRACE
, ("MiniQueryInformation failed (%x)\n", NdisStatus
));
2021 Success
= EthCreateFilter(MaxMulticastAddresses
,
2022 Adapter
->Address
.Type
.Medium802_3
,
2023 &Adapter
->NdisMiniportBlock
.EthDB
);
2025 ((PETHI_FILTER
)Adapter
->NdisMiniportBlock
.EthDB
)->Miniport
= (PNDIS_MINIPORT_BLOCK
)Adapter
;
2027 NdisStatus
= NDIS_STATUS_RESOURCES
;
2032 /* FIXME: Support other types of media */
2033 NDIS_DbgPrint(MIN_TRACE
, ("error: unsupported media\n"));
2035 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
2036 return STATUS_UNSUCCESSFUL
;
2039 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2041 NDIS_DbgPrint(MIN_TRACE
, ("couldn't create filter (%x)\n", NdisStatus
));
2045 /* Check for a hang every two seconds if it wasn't set in MiniportInitialize */
2046 if (Adapter
->NdisMiniportBlock
.CheckForHangSeconds
== 0)
2047 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= 2;
2049 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
2050 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStarted
;
2052 IoSetDeviceInterfaceState(&Adapter
->NdisMiniportBlock
.SymbolicLinkName
, TRUE
);
2054 Timeout
.QuadPart
= Int32x32To64(Adapter
->NdisMiniportBlock
.CheckForHangSeconds
, -1000000);
2055 KeSetTimerEx(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
, Timeout
,
2056 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
* 1000,
2057 &Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
);
2059 /* Put adapter in adapter list for this miniport */
2060 ExInterlockedInsertTailList(&Adapter
->NdisMiniportBlock
.DriverHandle
->DeviceList
, &Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
2062 /* Refresh bindings for all protocols */
2063 CurrentEntry
= ProtocolListHead
.Flink
;
2064 while (CurrentEntry
!= &ProtocolListHead
)
2066 ProtocolBinding
= CONTAINING_RECORD(CurrentEntry
, PROTOCOL_BINDING
, ListEntry
);
2068 ndisBindMiniportsToProtocol(&NdisStatus
, ProtocolBinding
);
2070 CurrentEntry
= CurrentEntry
->Flink
;
2073 return STATUS_SUCCESS
;
2080 IN PDEVICE_OBJECT DeviceObject
,
2083 * FUNCTION: Handle the PnP stop device event
2085 * DeviceObejct = Functional Device Object
2086 * Irp = IRP_MN_STOP_DEVICE I/O request packet
2088 * Status of operation
2091 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2093 /* Remove adapter from adapter list for this miniport */
2094 ExInterlockedRemoveEntryList(&Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
2096 /* Remove adapter from global adapter list */
2097 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
2099 KeCancelTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
2101 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.HaltHandler
)(Adapter
);
2103 IoSetDeviceInterfaceState(&Adapter
->NdisMiniportBlock
.SymbolicLinkName
, FALSE
);
2105 if (Adapter
->NdisMiniportBlock
.AllocatedResources
)
2107 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
2108 Adapter
->NdisMiniportBlock
.AllocatedResources
= NULL
;
2110 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
)
2112 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
);
2113 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
= NULL
;
2116 if (Adapter
->NdisMiniportBlock
.Resources
)
2118 ExFreePool(Adapter
->NdisMiniportBlock
.Resources
);
2119 Adapter
->NdisMiniportBlock
.Resources
= NULL
;
2122 if (Adapter
->NdisMiniportBlock
.EthDB
)
2124 EthDeleteFilter(Adapter
->NdisMiniportBlock
.EthDB
);
2125 Adapter
->NdisMiniportBlock
.EthDB
= NULL
;
2128 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
2129 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStopped
;
2131 return STATUS_SUCCESS
;
2137 IN PDEVICE_OBJECT DeviceObject
,
2140 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
2141 PMINIPORT_BUGCHECK_CONTEXT Context
= Adapter
->BugcheckContext
;
2142 ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
= Context
->ShutdownHandler
;
2144 ASSERT(ShutdownHandler
);
2146 ShutdownHandler(Context
->DriverContext
);
2148 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2149 Irp
->IoStatus
.Information
= 0;
2151 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2153 return STATUS_SUCCESS
;
2158 NdisIDeviceIoControl(
2159 IN PDEVICE_OBJECT DeviceObject
,
2162 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2163 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2164 NDIS_STATUS Status
= STATUS_NOT_SUPPORTED
;
2167 Irp
->IoStatus
.Information
= 0;
2171 switch (Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
2173 case IOCTL_NDIS_QUERY_GLOBAL_STATS
:
2174 Status
= MiniQueryInformation(Adapter
,
2175 *(PNDIS_OID
)Irp
->AssociatedIrp
.SystemBuffer
,
2176 Stack
->Parameters
.DeviceIoControl
.OutputBufferLength
,
2177 MmGetSystemAddressForMdl(Irp
->MdlAddress
),
2179 Irp
->IoStatus
.Information
= Written
;
2187 if (Status
!= NDIS_STATUS_PENDING
)
2189 Irp
->IoStatus
.Status
= Status
;
2190 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2193 IoMarkIrpPending(Irp
);
2202 IN PDEVICE_OBJECT DeviceObject
,
2205 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2206 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2209 switch (Stack
->MinorFunction
)
2211 case IRP_MN_START_DEVICE
:
2212 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2213 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2215 Status
= NdisIPnPStartDevice(DeviceObject
, Irp
);
2218 NDIS_DbgPrint(MIN_TRACE
, ("Lower driver failed device start\n"));
2219 Irp
->IoStatus
.Status
= Status
;
2220 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2223 case IRP_MN_STOP_DEVICE
:
2224 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2225 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2227 Status
= NdisIPnPStopDevice(DeviceObject
, Irp
);
2230 NDIS_DbgPrint(MIN_TRACE
, ("Lower driver failed device stop\n"));
2231 Irp
->IoStatus
.Status
= Status
;
2232 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2235 case IRP_MN_QUERY_REMOVE_DEVICE
:
2236 case IRP_MN_QUERY_STOP_DEVICE
:
2237 Status
= NdisIPnPQueryStopDevice(DeviceObject
, Irp
);
2238 Irp
->IoStatus
.Status
= Status
;
2239 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2242 case IRP_MN_CANCEL_REMOVE_DEVICE
:
2243 case IRP_MN_CANCEL_STOP_DEVICE
:
2244 Status
= NdisIPnPCancelStopDevice(DeviceObject
, Irp
);
2245 Irp
->IoStatus
.Status
= Status
;
2246 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2249 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
2250 Status
= NDIS_STATUS_SUCCESS
;
2251 Irp
->IoStatus
.Status
= Status
;
2252 Irp
->IoStatus
.Information
|= Adapter
->NdisMiniportBlock
.PnPFlags
;
2253 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2257 IoSkipCurrentIrpStackLocation(Irp
);
2258 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
2269 IN PDRIVER_OBJECT DriverObject
,
2270 IN PDEVICE_OBJECT PhysicalDeviceObject
)
2272 * FUNCTION: Create a device for an adapter found using PnP
2274 * DriverObject = Pointer to the miniport driver object
2275 * PhysicalDeviceObject = Pointer to the PDO for our adapter
2278 static const WCHAR ClassKeyName
[] = {'C','l','a','s','s','\\'};
2279 static const WCHAR LinkageKeyName
[] = {'\\','L','i','n','k','a','g','e',0};
2280 PNDIS_M_DRIVER_BLOCK Miniport
;
2281 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2282 WCHAR
*LinkageKeyBuffer
;
2283 ULONG DriverKeyLength
;
2284 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
2285 UNICODE_STRING ExportName
;
2286 PDEVICE_OBJECT DeviceObject
;
2287 PLOGICAL_ADAPTER Adapter
;
2291 * Gain the access to the miniport data structure first.
2294 MiniportPtr
= IoGetDriverObjectExtension(DriverObject
, (PVOID
)'NMID');
2295 if (MiniportPtr
== NULL
)
2297 NDIS_DbgPrint(MIN_TRACE
, ("Can't get driver object extension.\n"));
2298 return NDIS_STATUS_FAILURE
;
2300 Miniport
= *MiniportPtr
;
2303 * Get name of the Linkage registry key for our adapter. It's located under
2304 * the driver key for our driver and so we have basicly two ways to do it.
2305 * Either we can use IoOpenDriverRegistryKey or compose it using information
2306 * gathered by IoGetDeviceProperty. I choosed the second because
2307 * IoOpenDriverRegistryKey wasn't implemented at the time of writing.
2310 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2311 0, NULL
, &DriverKeyLength
);
2312 if (Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
&& Status
!= STATUS_SUCCESS
)
2314 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport driver key length.\n"));
2318 LinkageKeyBuffer
= ExAllocatePool(PagedPool
, DriverKeyLength
+
2319 sizeof(ClassKeyName
) + sizeof(LinkageKeyName
));
2320 if (LinkageKeyBuffer
== NULL
)
2322 NDIS_DbgPrint(MIN_TRACE
, ("Can't allocate memory for driver key name.\n"));
2323 return STATUS_INSUFFICIENT_RESOURCES
;
2326 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2327 DriverKeyLength
, LinkageKeyBuffer
+
2328 (sizeof(ClassKeyName
) / sizeof(WCHAR
)),
2330 if (!NT_SUCCESS(Status
))
2332 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport driver key.\n"));
2333 ExFreePool(LinkageKeyBuffer
);
2337 /* Compose the linkage key name. */
2338 RtlCopyMemory(LinkageKeyBuffer
, ClassKeyName
, sizeof(ClassKeyName
));
2339 RtlCopyMemory(LinkageKeyBuffer
+ ((sizeof(ClassKeyName
) + DriverKeyLength
) /
2340 sizeof(WCHAR
)) - 1, LinkageKeyName
, sizeof(LinkageKeyName
));
2342 NDIS_DbgPrint(DEBUG_MINIPORT
, ("LinkageKey: %S.\n", LinkageKeyBuffer
));
2345 * Now open the linkage key and read the "Export" and "RootDevice" values
2346 * which contains device name and root service respectively.
2349 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
2350 RtlInitUnicodeString(&ExportName
, NULL
);
2351 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
| RTL_QUERY_REGISTRY_DIRECT
;
2352 QueryTable
[0].Name
= L
"Export";
2353 QueryTable
[0].EntryContext
= &ExportName
;
2355 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
, LinkageKeyBuffer
,
2356 QueryTable
, NULL
, NULL
);
2357 ExFreePool(LinkageKeyBuffer
);
2358 if (!NT_SUCCESS(Status
))
2360 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport device name. (%x)\n", Status
));
2365 * Create the device object.
2368 NDIS_DbgPrint(MAX_TRACE
, ("creating device %wZ\n", &ExportName
));
2370 Status
= IoCreateDevice(Miniport
->DriverObject
, sizeof(LOGICAL_ADAPTER
),
2371 &ExportName
, FILE_DEVICE_PHYSICAL_NETCARD
,
2372 0, FALSE
, &DeviceObject
);
2373 if (!NT_SUCCESS(Status
))
2375 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device object.\n"));
2376 RtlFreeUnicodeString(&ExportName
);
2381 * Initialize the adapter structure.
2384 Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2385 KeInitializeSpinLock(&Adapter
->NdisMiniportBlock
.Lock
);
2386 InitializeListHead(&Adapter
->ProtocolListHead
);
2388 Status
= IoRegisterDeviceInterface(PhysicalDeviceObject
,
2389 &GUID_DEVINTERFACE_NET
,
2391 &Adapter
->NdisMiniportBlock
.SymbolicLinkName
);
2393 if (!NT_SUCCESS(Status
))
2395 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device interface.\n"));
2396 IoDeleteDevice(DeviceObject
);
2397 RtlFreeUnicodeString(&ExportName
);
2401 Adapter
->NdisMiniportBlock
.DriverHandle
= Miniport
;
2402 Adapter
->NdisMiniportBlock
.MiniportName
= ExportName
;
2403 Adapter
->NdisMiniportBlock
.DeviceObject
= DeviceObject
;
2404 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
= PhysicalDeviceObject
;
2405 Adapter
->NdisMiniportBlock
.NextDeviceObject
=
2406 IoAttachDeviceToDeviceStack(Adapter
->NdisMiniportBlock
.DeviceObject
,
2407 PhysicalDeviceObject
);
2409 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= 0;
2410 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceAdded
;
2412 KeInitializeTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
2413 KeInitializeDpc(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
, MiniportHangDpc
, Adapter
);
2415 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
2417 return STATUS_SUCCESS
;
2426 NdisMRegisterMiniport(
2427 IN NDIS_HANDLE NdisWrapperHandle
,
2428 IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics
,
2429 IN UINT CharacteristicsLength
)
2431 * FUNCTION: Registers a miniport's MiniportXxx entry points with the NDIS library
2433 * NdisWrapperHandle = Pointer to handle returned by NdisMInitializeWrapper
2434 * MiniportCharacteristics = Pointer to a buffer with miniport characteristics
2435 * CharacteristicsLength = Number of bytes in characteristics buffer
2437 * Status of operation
2441 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2442 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2445 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2447 switch (MiniportCharacteristics
->MajorNdisVersion
)
2450 MinSize
= sizeof(NDIS30_MINIPORT_CHARACTERISTICS
);
2454 MinSize
= sizeof(NDIS40_MINIPORT_CHARACTERISTICS
);
2458 switch (MiniportCharacteristics
->MinorNdisVersion
)
2461 MinSize
= sizeof(NDIS50_MINIPORT_CHARACTERISTICS
);
2465 MinSize
= sizeof(NDIS51_MINIPORT_CHARACTERISTICS
);
2469 NDIS_DbgPrint(MIN_TRACE
, ("Bad 5.x minor characteristics version.\n"));
2470 return NDIS_STATUS_BAD_VERSION
;
2475 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics version.\n"));
2476 return NDIS_STATUS_BAD_VERSION
;
2479 NDIS_DbgPrint(MIN_TRACE
, ("Initializing an NDIS %u.%u miniport\n",
2480 MiniportCharacteristics
->MajorNdisVersion
,
2481 MiniportCharacteristics
->MinorNdisVersion
));
2483 if (CharacteristicsLength
< MinSize
)
2485 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics length.\n"));
2486 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2489 /* Check if mandatory MiniportXxx functions are specified */
2490 if ((!MiniportCharacteristics
->HaltHandler
) ||
2491 (!MiniportCharacteristics
->InitializeHandler
)||
2492 (!MiniportCharacteristics
->ResetHandler
))
2494 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics.\n"));
2495 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2498 if (MiniportCharacteristics
->MajorNdisVersion
< 0x05)
2500 if ((!MiniportCharacteristics
->QueryInformationHandler
) ||
2501 (!MiniportCharacteristics
->SetInformationHandler
))
2503 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (Set/Query)\n"));
2504 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2509 if (((!MiniportCharacteristics
->QueryInformationHandler
) ||
2510 (!MiniportCharacteristics
->SetInformationHandler
)) &&
2511 (!MiniportCharacteristics
->CoRequestHandler
))
2513 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (Set/Query)\n"));
2514 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2518 if (MiniportCharacteristics
->MajorNdisVersion
== 0x03)
2520 if (!MiniportCharacteristics
->SendHandler
)
2522 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 3.0)\n"));
2523 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2526 else if (MiniportCharacteristics
->MajorNdisVersion
== 0x04)
2529 if ((!MiniportCharacteristics
->SendHandler
) &&
2530 (!MiniportCharacteristics
->SendPacketsHandler
))
2532 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 4.0)\n"));
2533 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2536 else if (MiniportCharacteristics
->MajorNdisVersion
== 0x05)
2538 /* TODO: Add more checks here */
2540 if ((!MiniportCharacteristics
->SendHandler
) &&
2541 (!MiniportCharacteristics
->SendPacketsHandler
) &&
2542 (!MiniportCharacteristics
->CoSendPacketsHandler
))
2544 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 5.0)\n"));
2545 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2549 RtlCopyMemory(&Miniport
->MiniportCharacteristics
, MiniportCharacteristics
, MinSize
);
2552 * NOTE: This is VERY unoptimal! Should we store the NDIS_M_DRIVER_BLOCK
2553 * structure in the driver extension or what?
2556 Status
= IoAllocateDriverObjectExtension(Miniport
->DriverObject
, (PVOID
)'NMID',
2557 sizeof(PNDIS_M_DRIVER_BLOCK
), (PVOID
*)&MiniportPtr
);
2558 if (!NT_SUCCESS(Status
))
2560 NDIS_DbgPrint(MIN_TRACE
, ("Can't allocate driver object extension.\n"));
2561 return NDIS_STATUS_RESOURCES
;
2564 *MiniportPtr
= Miniport
;
2566 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = NdisICreateClose
;
2567 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = NdisICreateClose
;
2568 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_PNP
] = NdisIDispatchPnp
;
2569 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] = NdisIShutdown
;
2570 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = NdisIDeviceIoControl
;
2571 Miniport
->DriverObject
->DriverExtension
->AddDevice
= NdisIAddDevice
;
2573 return NDIS_STATUS_SUCCESS
;
2580 #undef NdisMResetComplete
2584 IN NDIS_HANDLE MiniportAdapterHandle
,
2585 IN NDIS_STATUS Status
,
2586 IN BOOLEAN AddressingReset
)
2588 MiniResetComplete(MiniportAdapterHandle
, Status
, AddressingReset
);
2595 #undef NdisMSendComplete
2599 IN NDIS_HANDLE MiniportAdapterHandle
,
2600 IN PNDIS_PACKET Packet
,
2601 IN NDIS_STATUS Status
)
2603 * FUNCTION: Forwards a message to the initiating protocol saying
2604 * that a packet was handled
2606 * NdisAdapterHandle = Handle input to MiniportInitialize
2607 * Packet = Pointer to NDIS packet that was sent
2608 * Status = Status of send operation
2611 MiniSendComplete(MiniportAdapterHandle
, Packet
, Status
);
2618 #undef NdisMSendResourcesAvailable
2621 NdisMSendResourcesAvailable(
2622 IN NDIS_HANDLE MiniportAdapterHandle
)
2624 MiniSendResourcesAvailable(MiniportAdapterHandle
);
2631 #undef NdisMTransferDataComplete
2634 NdisMTransferDataComplete(
2635 IN NDIS_HANDLE MiniportAdapterHandle
,
2636 IN PNDIS_PACKET Packet
,
2637 IN NDIS_STATUS Status
,
2638 IN UINT BytesTransferred
)
2640 MiniTransferDataComplete(MiniportAdapterHandle
, Packet
, Status
, BytesTransferred
);
2647 #undef NdisMSetAttributes
2651 IN NDIS_HANDLE MiniportAdapterHandle
,
2652 IN NDIS_HANDLE MiniportAdapterContext
,
2653 IN BOOLEAN BusMaster
,
2654 IN NDIS_INTERFACE_TYPE AdapterType
)
2656 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2658 * MiniportAdapterHandle = Handle input to MiniportInitialize
2659 * MiniportAdapterContext = Pointer to context information
2660 * BusMaster = Specifies TRUE if the caller's NIC is a busmaster DMA device
2661 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2664 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2665 NdisMSetAttributesEx(MiniportAdapterHandle
, MiniportAdapterContext
, 0,
2666 BusMaster
? NDIS_ATTRIBUTE_BUS_MASTER
: 0,
2676 NdisMSetAttributesEx(
2677 IN NDIS_HANDLE MiniportAdapterHandle
,
2678 IN NDIS_HANDLE MiniportAdapterContext
,
2679 IN UINT CheckForHangTimeInSeconds OPTIONAL
,
2680 IN ULONG AttributeFlags
,
2681 IN NDIS_INTERFACE_TYPE AdapterType
)
2683 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2685 * MiniportAdapterHandle = Handle input to MiniportInitialize
2686 * MiniportAdapterContext = Pointer to context information
2687 * CheckForHangTimeInSeconds = Specifies interval in seconds at which
2688 * MiniportCheckForHang should be called
2689 * AttributeFlags = Bitmask that indicates specific attributes
2690 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2693 PLOGICAL_ADAPTER Adapter
= GET_LOGICAL_ADAPTER(MiniportAdapterHandle
);
2695 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2697 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
= MiniportAdapterContext
;
2698 Adapter
->NdisMiniportBlock
.Flags
= AttributeFlags
;
2699 Adapter
->NdisMiniportBlock
.AdapterType
= AdapterType
;
2700 if (CheckForHangTimeInSeconds
> 0)
2701 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= CheckForHangTimeInSeconds
;
2702 if (AttributeFlags
& NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER
)
2703 NDIS_DbgPrint(MAX_TRACE
, ("Intermediate drivers not supported yet.\n"));
2706 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.AdapterShutdownHandler
)
2708 NDIS_DbgPrint(MAX_TRACE
, ("Miniport set AdapterShutdownHandler in MiniportCharacteristics\n"));
2709 NdisMRegisterAdapterShutdownHandler(Adapter
,
2710 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
2711 Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.AdapterShutdownHandler
);
2722 IN ULONG MicrosecondsToSleep
)
2724 * FUNCTION: delay the thread's execution for MicrosecondsToSleep
2726 * MicrosecondsToSleep: duh...
2728 * - Because this is a blocking call, current IRQL must be < DISPATCH_LEVEL
2732 LARGE_INTEGER DueTime
;
2736 DueTime
.QuadPart
= (-1) * 10 * MicrosecondsToSleep
;
2738 KeInitializeTimer(&Timer
);
2739 KeSetTimer(&Timer
, DueTime
, 0);
2740 KeWaitForSingleObject(&Timer
, Executive
, KernelMode
, FALSE
, 0);
2749 NdisMSynchronizeWithInterrupt(
2750 IN PNDIS_MINIPORT_INTERRUPT Interrupt
,
2751 IN PVOID SynchronizeFunction
,
2752 IN PVOID SynchronizeContext
)
2754 return(KeSynchronizeExecution(Interrupt
->InterruptObject
,
2755 (PKSYNCHRONIZE_ROUTINE
)SynchronizeFunction
,
2756 SynchronizeContext
));
2766 IN NDIS_HANDLE LogHandle
,
2768 IN UINT LogBufferSize
)
2770 PUCHAR Buffer
= LogBuffer
;
2774 for (i
= 0; i
< LogBufferSize
; i
+= 16)
2776 DbgPrint("%08x |", i
);
2777 for (j
= 0; j
< 16; j
++)
2780 if (idx
< LogBufferSize
)
2781 DbgPrint(" %02x", Buffer
[idx
]);
2786 for (j
= 0; j
< 16; j
++)
2789 if (idx
== LogBufferSize
)
2791 if (Buffer
[idx
] >= ' ') /* FIXME: not portable! replace by if (isprint(Buffer[idx])) ? */
2792 DbgPrint("%c", Buffer
[idx
]);
2799 return NDIS_STATUS_FAILURE
;
2808 NdisTerminateWrapper(
2809 IN NDIS_HANDLE NdisWrapperHandle
,
2810 IN PVOID SystemSpecific
)
2812 * FUNCTION: Releases resources allocated by a call to NdisInitializeWrapper
2814 * NdisWrapperHandle = Handle returned by NdisInitializeWrapper (NDIS_M_DRIVER_BLOCK)
2815 * SystemSpecific = Always NULL
2818 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2820 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2822 ExFreePool(Miniport
->RegistryPath
->Buffer
);
2823 ExFreePool(Miniport
->RegistryPath
);
2824 ExInterlockedRemoveEntryList(&Miniport
->ListEntry
, &MiniportListLock
);
2825 ExFreePool(Miniport
);
2834 NdisMQueryAdapterInstanceName(
2835 OUT PNDIS_STRING AdapterInstanceName
,
2836 IN NDIS_HANDLE MiniportAdapterHandle
)
2844 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
2845 UNICODE_STRING AdapterName
;
2847 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2849 AdapterName
.Length
= 0;
2850 AdapterName
.MaximumLength
= Adapter
->NdisMiniportBlock
.MiniportName
.MaximumLength
;
2851 AdapterName
.Buffer
= ExAllocatePool(PagedPool
, AdapterName
.MaximumLength
);
2852 if (!AdapterName
.Buffer
) {
2853 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
2854 return NDIS_STATUS_RESOURCES
;
2857 RtlCopyUnicodeString(&AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
);
2859 *AdapterInstanceName
= AdapterName
;
2861 return NDIS_STATUS_SUCCESS
;
2869 NdisDeregisterAdapterShutdownHandler(
2870 IN NDIS_HANDLE NdisAdapterHandle
)
2878 NdisMDeregisterAdapterShutdownHandler(NdisAdapterHandle
);
2887 NdisRegisterAdapterShutdownHandler(
2888 IN NDIS_HANDLE NdisAdapterHandle
,
2889 IN PVOID ShutdownContext
,
2890 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
2898 NdisMRegisterAdapterShutdownHandler(NdisAdapterHandle
,
2908 NdisMGetDeviceProperty(
2909 IN NDIS_HANDLE MiniportAdapterHandle
,
2910 IN OUT PDEVICE_OBJECT
*PhysicalDeviceObject OPTIONAL
,
2911 IN OUT PDEVICE_OBJECT
*FunctionalDeviceObject OPTIONAL
,
2912 IN OUT PDEVICE_OBJECT
*NextDeviceObject OPTIONAL
,
2913 IN OUT PCM_RESOURCE_LIST
*AllocatedResources OPTIONAL
,
2914 IN OUT PCM_RESOURCE_LIST
*AllocatedResourcesTranslated OPTIONAL
)
2922 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
2924 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
2926 if (PhysicalDeviceObject
!= NULL
)
2927 *PhysicalDeviceObject
= Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
;
2929 if (FunctionalDeviceObject
!= NULL
)
2930 *FunctionalDeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
2932 if (NextDeviceObject
!= NULL
)
2933 *NextDeviceObject
= Adapter
->NdisMiniportBlock
.NextDeviceObject
;
2935 if (AllocatedResources
!= NULL
)
2936 *AllocatedResources
= Adapter
->NdisMiniportBlock
.AllocatedResources
;
2938 if (AllocatedResourcesTranslated
!= NULL
)
2939 *AllocatedResourcesTranslated
= Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
;
2947 NdisMRegisterUnloadHandler(
2948 IN NDIS_HANDLE NdisWrapperHandle
,
2949 IN PDRIVER_UNLOAD UnloadHandler
)
2957 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
2959 NDIS_DbgPrint(MAX_TRACE
, ("Miniport registered unload handler\n"));
2961 DriverBlock
->DriverObject
->DriverUnload
= UnloadHandler
;
2969 NdisMRegisterDevice(
2970 IN NDIS_HANDLE NdisWrapperHandle
,
2971 IN PNDIS_STRING DeviceName
,
2972 IN PNDIS_STRING SymbolicName
,
2973 IN PDRIVER_DISPATCH MajorFunctions
[],
2974 OUT PDEVICE_OBJECT
*pDeviceObject
,
2975 OUT NDIS_HANDLE
*NdisDeviceHandle
)
2983 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
2984 PNDIS_M_DEVICE_BLOCK DeviceBlock
;
2985 PDEVICE_OBJECT DeviceObject
;
2989 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
2991 Status
= IoCreateDevice(DriverBlock
->DriverObject
,
2992 0, /* This space is reserved for us. Should we use it? */
2994 FILE_DEVICE_NETWORK
,
2999 if (!NT_SUCCESS(Status
))
3001 NDIS_DbgPrint(MIN_TRACE
, ("IoCreateDevice failed (%x)\n", Status
));
3005 Status
= IoCreateSymbolicLink(SymbolicName
, DeviceName
);
3007 if (!NT_SUCCESS(Status
))
3009 NDIS_DbgPrint(MIN_TRACE
, ("IoCreateSymbolicLink failed (%x)\n", Status
));
3010 IoDeleteDevice(DeviceObject
);
3014 DeviceBlock
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DEVICE_BLOCK
));
3018 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
3019 IoDeleteDevice(DeviceObject
);
3020 IoDeleteSymbolicLink(SymbolicName
);
3021 return NDIS_STATUS_RESOURCES
;
3024 for (i
= 0; i
<= IRP_MJ_MAXIMUM_FUNCTION
; i
++)
3025 DriverBlock
->DriverObject
->MajorFunction
[i
] = MajorFunctions
[i
];
3027 DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_PNP
] = NdisIDispatchPnp
;
3029 if (!DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_CREATE
])
3030 DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = NdisICreateClose
;
3032 if (!DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_CLOSE
])
3033 DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = NdisICreateClose
;
3035 DeviceBlock
->DeviceObject
= DeviceObject
;
3036 DeviceBlock
->SymbolicName
= SymbolicName
;
3038 *pDeviceObject
= DeviceObject
;
3039 *NdisDeviceHandle
= DeviceBlock
;
3041 return NDIS_STATUS_SUCCESS
;
3049 NdisMDeregisterDevice(
3050 IN NDIS_HANDLE NdisDeviceHandle
)
3058 PNDIS_M_DEVICE_BLOCK DeviceBlock
= NdisDeviceHandle
;
3060 IoDeleteDevice(DeviceBlock
->DeviceObject
);
3062 IoDeleteSymbolicLink(DeviceBlock
->SymbolicName
);
3064 ExFreePool(DeviceBlock
);
3066 return NDIS_STATUS_SUCCESS
;
3074 NdisQueryAdapterInstanceName(
3075 OUT PNDIS_STRING AdapterInstanceName
,
3076 IN NDIS_HANDLE NdisBindingHandle
)
3084 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3085 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3087 return NdisMQueryAdapterInstanceName(AdapterInstanceName
,
3096 NdisCompletePnPEvent(
3097 IN NDIS_STATUS Status
,
3098 IN NDIS_HANDLE NdisBindingHandle
,
3099 IN PNET_PNP_EVENT NetPnPEvent
)
3107 PIRP Irp
= (PIRP
)NetPnPEvent
->NdisReserved
[0];
3108 PLIST_ENTRY CurrentEntry
= (PLIST_ENTRY
)NetPnPEvent
->NdisReserved
[1];
3109 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3110 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3111 NDIS_STATUS NdisStatus
;
3113 if (Status
!= NDIS_STATUS_SUCCESS
)
3115 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3116 ExFreePool(NetPnPEvent
);
3117 Irp
->IoStatus
.Status
= Status
;
3118 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3122 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
3124 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
3126 NdisStatus
= (*AdapterBinding
->ProtocolBinding
->Chars
.PnPEventHandler
)(
3127 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
3130 if (NdisStatus
== NDIS_STATUS_PENDING
)
3132 NetPnPEvent
->NdisReserved
[1] = (ULONG_PTR
)CurrentEntry
->Flink
;
3135 else if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
3137 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3138 ExFreePool(NetPnPEvent
);
3139 Irp
->IoStatus
.Status
= NdisStatus
;
3140 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3144 CurrentEntry
= CurrentEntry
->Flink
;
3147 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3148 ExFreePool(NetPnPEvent
);
3150 Irp
->IoStatus
.Status
= NDIS_STATUS_SUCCESS
;
3151 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3159 NdisCancelSendPackets(
3160 IN NDIS_HANDLE NdisBindingHandle
,
3163 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3164 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3166 NDIS_DbgPrint(MAX_TRACE
, ("Called for ID %x.\n", CancelId
));
3168 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CancelSendPacketsHandler
)
3170 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CancelSendPacketsHandler
)(
3171 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
3182 NdisIMGetBindingContext(
3183 IN NDIS_HANDLE NdisBindingHandle
)
3191 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3192 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3194 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3196 return Adapter
->NdisMiniportBlock
.DeviceContext
;
3205 NdisIMGetDeviceContext(
3206 IN NDIS_HANDLE MiniportAdapterHandle
)
3214 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
3216 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3218 return Adapter
->NdisMiniportBlock
.DeviceContext
;