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
17 * Define to 1 to get a debugger breakpoint at the end of NdisInitializeWrapper
18 * for each new miniport starting up
20 #define BREAK_ON_MINIPORT_INIT 0
23 * This has to be big enough to hold the results of querying the Route value
24 * from the Linkage key. Please re-code me to determine this dynamically.
26 #define ROUTE_DATA_SIZE 256
28 /* Number of media we know */
29 #define MEDIA_ARRAY_SIZE 15
31 static NDIS_MEDIUM MediaArray
[MEDIA_ARRAY_SIZE
] =
40 NdisMediumArcnet878_2
,
42 NdisMediumWirelessWan
,
50 /* global list and lock of Miniports NDIS has registered */
51 LIST_ENTRY MiniportListHead
;
52 KSPIN_LOCK MiniportListLock
;
54 /* global list and lock of adapters NDIS has registered */
55 LIST_ENTRY AdapterListHead
;
56 KSPIN_LOCK AdapterListLock
;
65 if ((DebugTraceLevel
& DEBUG_PACKET
) > 0) {
66 Length
= CopyPacketToBuffer(
72 DbgPrint("*** PACKET START ***");
74 for (i
= 0; i
< Length
; i
++) {
76 DbgPrint("\n%04X ", i
);
77 DbgPrint("%02X ", Buffer
[i
]);
80 DbgPrint("*** PACKET STOP ***\n");
88 UINT HeaderBufferSize
,
89 PVOID LookaheadBuffer
,
90 UINT LookaheadBufferSize
)
93 if ((DebugTraceLevel
& DEBUG_PACKET
) > 0) {
97 DbgPrint("*** RECEIVE PACKET START ***\n");
100 for (i
= 0; i
< HeaderBufferSize
; i
++) {
102 DbgPrint("\n%04X ", i
);
103 DbgPrint("%02X ", *p
++);
106 DbgPrint("\nFRAME:");
109 Length
= (LookaheadBufferSize
< 64)? LookaheadBufferSize
: 64;
110 for (i
= 0; i
< Length
; i
++) {
112 DbgPrint("\n%04X ", i
);
113 DbgPrint("%02X ", *p
++);
116 DbgPrint("\n*** RECEIVE PACKET STOP ***\n");
121 PNDIS_MINIPORT_WORK_ITEM
122 MiniGetFirstWorkItem(
123 PLOGICAL_ADAPTER Adapter
,
124 NDIS_WORK_ITEM_TYPE Type
)
126 PNDIS_MINIPORT_WORK_ITEM CurrentEntry
= Adapter
->WorkQueueHead
;
130 if (CurrentEntry
->WorkItemType
== Type
)
133 CurrentEntry
= (PNDIS_MINIPORT_WORK_ITEM
)CurrentEntry
->Link
.Next
;
141 PLOGICAL_ADAPTER Adapter
,
142 NDIS_WORK_ITEM_TYPE Type
)
144 BOOLEAN Busy
= FALSE
;
147 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
149 if (Type
== NdisWorkItemRequest
&&
150 (Adapter
->NdisMiniportBlock
.PendingRequest
|| MiniGetFirstWorkItem(Adapter
, NdisWorkItemRequest
)))
154 else if (Type
== NdisWorkItemSend
&&
155 (Adapter
->NdisMiniportBlock
.FirstPendingPacket
|| MiniGetFirstWorkItem(Adapter
, NdisWorkItemSend
)))
159 else if (Type
== NdisWorkItemResetRequested
&&
160 (Adapter
->NdisMiniportBlock
.ResetStatus
== NDIS_STATUS_PENDING
|| MiniGetFirstWorkItem(Adapter
, NdisWorkItemResetRequested
)))
165 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
173 PLOGICAL_ADAPTER Adapter
,
174 NDIS_HANDLE MacReceiveContext
,
176 UINT HeaderBufferSize
,
177 PVOID LookaheadBuffer
,
178 UINT LookaheadBufferSize
,
181 * FUNCTION: Indicate received data to bound protocols
183 * Adapter = Pointer to logical adapter
184 * MacReceiveContext = MAC receive context handle
185 * HeaderBuffer = Pointer to header buffer
186 * HeaderBufferSize = Size of header buffer
187 * LookaheadBuffer = Pointer to lookahead buffer
188 * LookaheadBufferSize = Size of lookahead buffer
189 * PacketSize = Total size of received packet
193 PLIST_ENTRY CurrentEntry
;
194 PADAPTER_BINDING AdapterBinding
;
196 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called. Adapter (0x%X) HeaderBuffer (0x%X) "
197 "HeaderBufferSize (0x%X) LookaheadBuffer (0x%X) LookaheadBufferSize (0x%X).\n",
198 Adapter
, HeaderBuffer
, HeaderBufferSize
, LookaheadBuffer
, LookaheadBufferSize
));
200 MiniDisplayPacket2(HeaderBuffer
, HeaderBufferSize
, LookaheadBuffer
, LookaheadBufferSize
);
202 NDIS_DbgPrint(MAX_TRACE
, ("acquiring miniport block lock\n"));
203 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
205 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
206 NDIS_DbgPrint(DEBUG_MINIPORT
, ("CurrentEntry = %x\n", CurrentEntry
));
208 if (CurrentEntry
== &Adapter
->ProtocolListHead
)
210 NDIS_DbgPrint(MIN_TRACE
, ("WARNING: No upper protocol layer.\n"));
213 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
215 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
216 NDIS_DbgPrint(DEBUG_MINIPORT
, ("AdapterBinding = %x\n", AdapterBinding
));
220 ("XXX (%x) %x %x %x %x %x %x %x XXX\n",
221 *AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
,
222 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
230 /* call the receive handler */
231 (*AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
)(
232 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
240 CurrentEntry
= CurrentEntry
->Flink
;
243 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
245 NDIS_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
250 MiniIndicateReceivePacket(
251 IN NDIS_HANDLE MiniportAdapterHandle
,
252 IN PPNDIS_PACKET PacketArray
,
253 IN UINT NumberOfPackets
)
255 * FUNCTION: receives miniport packet array indications
257 * MiniportAdapterHandle: Miniport handle for the adapter
258 * PacketArray: pointer to a list of packet pointers to indicate
259 * NumberOfPackets: number of packets to indicate
263 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
264 PLIST_ENTRY CurrentEntry
;
265 PADAPTER_BINDING AdapterBinding
;
269 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
271 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
273 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
275 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
277 for (i
= 0; i
< NumberOfPackets
; i
++)
279 if (AdapterBinding
->ProtocolBinding
->Chars
.ReceivePacketHandler
&&
280 NDIS_GET_PACKET_STATUS(PacketArray
[i
]) != NDIS_STATUS_RESOURCES
)
282 (*AdapterBinding
->ProtocolBinding
->Chars
.ReceivePacketHandler
)(
283 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
288 UINT FirstBufferLength
, TotalBufferLength
, LookAheadSize
, HeaderSize
;
289 PNDIS_BUFFER NdisBuffer
;
290 PVOID NdisBufferVA
, LookAheadBuffer
;
291 NDIS_STATUS NdisStatus
;
294 NdisGetFirstBufferFromPacket(PacketArray
[i
],
300 HeaderSize
= NDIS_GET_PACKET_HEADER_SIZE(PacketArray
[i
]);
302 if (Adapter
->NdisMiniportBlock
.CurrentLookahead
< (TotalBufferLength
- HeaderSize
))
304 LookAheadSize
= Adapter
->NdisMiniportBlock
.CurrentLookahead
;
308 LookAheadSize
= TotalBufferLength
- HeaderSize
;
312 LookAheadBuffer
= ExAllocatePool(NonPagedPool
, LookAheadSize
);
313 if (!LookAheadBuffer
)
315 NDIS_DbgPrint(MIN_TRACE
, ("Failed to allocate lookahead buffer!\n"));
316 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
320 CopyBufferChainToBuffer(LookAheadBuffer
,
325 NdisStatus
= (*AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
)(
326 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
327 AdapterBinding
->NdisOpenBlock
.MacHandle
,
332 TotalBufferLength
- HeaderSize
);
334 NDIS_SET_PACKET_STATUS(PacketArray
[i
], NdisStatus
);
336 ExFreePool(LookAheadBuffer
);
340 CurrentEntry
= CurrentEntry
->Flink
;
343 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
349 IN NDIS_HANDLE MiniportAdapterHandle
,
350 IN NDIS_STATUS Status
,
351 IN BOOLEAN AddressingReset
)
353 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
354 PLIST_ENTRY CurrentEntry
;
355 PADAPTER_BINDING AdapterBinding
;
359 MiniDoAddressingReset(Adapter
);
361 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
362 NdisMIndicateStatusComplete(Adapter
);
364 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
366 if (Adapter
->NdisMiniportBlock
.ResetStatus
!= NDIS_STATUS_PENDING
)
368 KeBugCheckEx(BUGCODE_ID_DRIVER
,
369 (ULONG_PTR
)MiniportAdapterHandle
,
371 (ULONG_PTR
)AddressingReset
,
375 Adapter
->NdisMiniportBlock
.ResetStatus
= Status
;
377 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
379 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
381 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
383 (*AdapterBinding
->ProtocolBinding
->Chars
.ResetCompleteHandler
)(
384 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
387 CurrentEntry
= CurrentEntry
->Flink
;
390 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
395 IN NDIS_HANDLE MiniportAdapterHandle
,
396 IN NDIS_STATUS Status
)
398 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
399 PNDIS_REQUEST Request
;
400 PNDIS_REQUEST_MAC_BLOCK MacBlock
;
403 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
405 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
407 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
408 Request
= Adapter
->NdisMiniportBlock
.PendingRequest
;
409 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
411 MacBlock
= (PNDIS_REQUEST_MAC_BLOCK
)Request
->MacReserved
;
413 if( MacBlock
->Binding
->RequestCompleteHandler
) {
414 (*MacBlock
->Binding
->RequestCompleteHandler
)(
415 MacBlock
->Binding
->ProtocolBindingContext
,
420 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
421 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
422 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
424 KeLowerIrql(OldIrql
);
429 IN NDIS_HANDLE MiniportAdapterHandle
,
430 IN PNDIS_PACKET Packet
,
431 IN NDIS_STATUS Status
)
433 * FUNCTION: Forwards a message to the initiating protocol saying
434 * that a packet was handled
436 * NdisAdapterHandle = Handle input to MiniportInitialize
437 * Packet = Pointer to NDIS packet that was sent
438 * Status = Status of send operation
441 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
442 PADAPTER_BINDING AdapterBinding
;
444 PSCATTER_GATHER_LIST SGList
;
446 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
448 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
450 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
452 if (Adapter
->NdisMiniportBlock
.ScatterGatherListSize
!= 0)
454 NDIS_DbgPrint(MAX_TRACE
, ("Freeing Scatter/Gather list\n"));
456 SGList
= NDIS_PER_PACKET_INFO_FROM_PACKET(Packet
,
457 ScatterGatherListPacketInfo
);
459 Adapter
->NdisMiniportBlock
.SystemAdapterObject
->
460 DmaOperations
->PutScatterGatherList(
461 Adapter
->NdisMiniportBlock
.SystemAdapterObject
,
465 NDIS_PER_PACKET_INFO_FROM_PACKET(Packet
,
466 ScatterGatherListPacketInfo
) = NULL
;
469 (*AdapterBinding
->ProtocolBinding
->Chars
.SendCompleteHandler
)(
470 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
474 KeLowerIrql(OldIrql
);
479 MiniSendResourcesAvailable(
480 IN NDIS_HANDLE MiniportAdapterHandle
)
489 MiniTransferDataComplete(
490 IN NDIS_HANDLE MiniportAdapterHandle
,
491 IN PNDIS_PACKET Packet
,
492 IN NDIS_STATUS Status
,
493 IN UINT BytesTransferred
)
495 PADAPTER_BINDING AdapterBinding
;
498 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
500 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
502 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
503 (*AdapterBinding
->ProtocolBinding
->Chars
.TransferDataCompleteHandler
)(
504 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
508 KeLowerIrql(OldIrql
);
513 MiniAdapterHasAddress(
514 PLOGICAL_ADAPTER Adapter
,
517 * FUNCTION: Determines whether a packet has the same destination address as an adapter
519 * Adapter = Pointer to logical adapter object
520 * Packet = Pointer to NDIS packet
522 * TRUE if the destination address is that of the adapter, FALSE if not
528 PNDIS_BUFFER NdisBuffer
;
531 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
536 NDIS_DbgPrint(MIN_TRACE
, ("Adapter object was null\n"));
542 NDIS_DbgPrint(MIN_TRACE
, ("Packet was null\n"));
547 NdisQueryPacket(Packet
, NULL
, NULL
, &NdisBuffer
, NULL
);
551 NDIS_DbgPrint(MIN_TRACE
, ("Packet contains no buffers.\n"));
555 NdisQueryBuffer(NdisBuffer
, (PVOID
)&Start2
, &BufferLength
);
557 /* FIXME: Should handle fragmented packets */
559 switch (Adapter
->NdisMiniportBlock
.MediaType
)
561 case NdisMedium802_3
:
562 Length
= ETH_LENGTH_OF_ADDRESS
;
563 /* Destination address is the first field */
567 NDIS_DbgPrint(MIN_TRACE
, ("Adapter has unsupported media type (0x%X).\n", Adapter
->NdisMiniportBlock
.MediaType
));
571 if (BufferLength
< Length
)
573 NDIS_DbgPrint(MIN_TRACE
, ("Buffer is too small.\n"));
577 Start1
= (PUCHAR
)&Adapter
->Address
;
578 NDIS_DbgPrint(MAX_TRACE
, ("packet address: %x:%x:%x:%x:%x:%x adapter address: %x:%x:%x:%x:%x:%x\n",
579 *((char *)Start1
), *(((char *)Start1
)+1), *(((char *)Start1
)+2), *(((char *)Start1
)+3), *(((char *)Start1
)+4), *(((char *)Start1
)+5),
580 *((char *)Start2
), *(((char *)Start2
)+1), *(((char *)Start2
)+2), *(((char *)Start2
)+3), *(((char *)Start2
)+4), *(((char *)Start2
)+5))
583 return (RtlCompareMemory((PVOID
)Start1
, (PVOID
)Start2
, Length
) == Length
);
589 PNDIS_STRING AdapterName
)
591 * FUNCTION: Finds an adapter object by name
593 * AdapterName = Pointer to name of adapter
595 * Pointer to logical adapter object, or NULL if none was found.
596 * If found, the adapter is referenced for the caller. The caller
597 * is responsible for dereferencing after use
601 PLIST_ENTRY CurrentEntry
;
602 PLOGICAL_ADAPTER Adapter
= 0;
606 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
608 if(IsListEmpty(&AdapterListHead
))
610 NDIS_DbgPrint(MIN_TRACE
, ("No registered miniports for protocol to bind to\n"));
614 KeAcquireSpinLock(&AdapterListLock
, &OldIrql
);
616 CurrentEntry
= AdapterListHead
.Flink
;
618 while (CurrentEntry
!= &AdapterListHead
)
620 Adapter
= CONTAINING_RECORD(CurrentEntry
, LOGICAL_ADAPTER
, ListEntry
);
624 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Examining adapter 0x%lx\n", Adapter
));
625 NDIS_DbgPrint(DEBUG_MINIPORT
, ("AdapterName = %wZ\n", AdapterName
));
626 NDIS_DbgPrint(DEBUG_MINIPORT
, ("DeviceName = %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
628 if (RtlCompareUnicodeString(AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
, TRUE
) == 0)
634 CurrentEntry
= CurrentEntry
->Flink
;
637 KeReleaseSpinLock(&AdapterListLock
, OldIrql
);
641 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Leaving. Adapter found at 0x%x\n", Adapter
));
645 NDIS_DbgPrint(MIN_TRACE
, ("Leaving (adapter not found for %wZ).\n", AdapterName
));
653 PLOGICAL_ADAPTER Adapter
,
659 NDIS_STATUS NdisStatus
;
660 PNDIS_REQUEST NdisRequest
;
662 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
664 NdisRequest
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_REQUEST
));
666 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
667 return NDIS_STATUS_RESOURCES
;
670 RtlZeroMemory(NdisRequest
, sizeof(NDIS_REQUEST
));
672 NdisRequest
->RequestType
= NdisRequestSetInformation
;
673 NdisRequest
->DATA
.SET_INFORMATION
.Oid
= Oid
;
674 NdisRequest
->DATA
.SET_INFORMATION
.InformationBuffer
= Buffer
;
675 NdisRequest
->DATA
.SET_INFORMATION
.InformationBufferLength
= Size
;
677 NdisStatus
= MiniDoRequest(Adapter
, NdisRequest
);
679 /* FIXME: Wait in pending case! */
681 ASSERT(NdisStatus
!= NDIS_STATUS_PENDING
);
683 *BytesRead
= NdisRequest
->DATA
.SET_INFORMATION
.BytesRead
;
685 ExFreePool(NdisRequest
);
691 MiniQueryInformation(
692 PLOGICAL_ADAPTER Adapter
,
698 * FUNCTION: Queries a logical adapter for properties
700 * Adapter = Pointer to the logical adapter object to query
701 * Oid = Specifies the Object ID to query for
702 * Size = Size of the passed buffer
703 * Buffer = Buffer for the output
704 * BytesWritten = Address of buffer to place number of bytes written
706 * Status of operation
709 NDIS_STATUS NdisStatus
;
710 PNDIS_REQUEST NdisRequest
;
712 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
714 NdisRequest
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_REQUEST
));
716 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
717 return NDIS_STATUS_RESOURCES
;
720 RtlZeroMemory(NdisRequest
, sizeof(NDIS_REQUEST
));
722 NdisRequest
->RequestType
= NdisRequestQueryInformation
;
723 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
= Oid
;
724 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
= Buffer
;
725 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
= Size
;
727 NdisStatus
= MiniDoRequest(Adapter
, NdisRequest
);
729 /* FIXME: Wait in pending case! */
731 ASSERT(NdisStatus
!= NDIS_STATUS_PENDING
);
733 *BytesWritten
= NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
;
735 ExFreePool(NdisRequest
);
741 MiniCheckForHang( PLOGICAL_ADAPTER Adapter
)
743 * FUNCTION: Checks to see if the miniport is hung
745 * Adapter = Pointer to the logical adapter object
747 * TRUE if the miniport is hung
748 * FALSE if the miniport is not hung
754 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
755 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)
756 Ret
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)(
757 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
);
758 KeLowerIrql(OldIrql
);
764 MiniDoAddressingReset(PLOGICAL_ADAPTER Adapter
)
768 MiniSetInformation(Adapter
,
769 OID_GEN_CURRENT_LOOKAHEAD
,
771 &Adapter
->NdisMiniportBlock
.CurrentLookahead
,
774 /* FIXME: Set more stuff */
779 PLOGICAL_ADAPTER Adapter
)
781 * FUNCTION: Resets the miniport
783 * Adapter = Pointer to the logical adapter object
785 * Status of the operation
790 BOOLEAN AddressingReset
= TRUE
;
792 if (MiniIsBusy(Adapter
, NdisWorkItemResetRequested
)) {
793 MiniQueueWorkItem(Adapter
, NdisWorkItemResetRequested
, NULL
, FALSE
);
794 return NDIS_STATUS_PENDING
;
797 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
798 NdisMIndicateStatusComplete(Adapter
);
800 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
801 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
802 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
805 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
806 Adapter
->NdisMiniportBlock
.ResetStatus
= Status
;
807 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
809 KeLowerIrql(OldIrql
);
811 if (Status
!= NDIS_STATUS_PENDING
) {
813 MiniDoAddressingReset(Adapter
);
815 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
816 NdisMIndicateStatusComplete(Adapter
);
825 PVOID DeferredContext
,
826 PVOID SystemArgument1
,
827 PVOID SystemArgument2
)
829 PLOGICAL_ADAPTER Adapter
= DeferredContext
;
831 if (MiniCheckForHang(Adapter
)) {
832 NDIS_DbgPrint(MIN_TRACE
, ("Miniport detected adapter hang\n"));
841 PLOGICAL_ADAPTER Adapter
,
842 NDIS_WORK_ITEM_TYPE WorkItemType
,
843 PVOID WorkItemContext
,
846 * FUNCTION: Queues a work item for execution at a later time
848 * Adapter = Pointer to the logical adapter object to queue work item on
849 * WorkItemType = Type of work item to queue
850 * WorkItemContext = Pointer to context information for work item
852 * Status of operation
855 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
856 PIO_WORKITEM IoWorkItem
;
859 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
863 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
866 if (WorkItemType
== NdisWorkItemSend
)
868 NDIS_DbgPrint(MIN_TRACE
, ("Requeuing failed packet (%x).\n", WorkItemContext
));
869 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= WorkItemContext
;
873 //This should never happen
879 MiniportWorkItem
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_MINIPORT_WORK_ITEM
));
880 if (!MiniportWorkItem
)
882 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
883 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
887 MiniportWorkItem
->WorkItemType
= WorkItemType
;
888 MiniportWorkItem
->WorkItemContext
= WorkItemContext
;
890 /* safe due to adapter lock held */
891 MiniportWorkItem
->Link
.Next
= NULL
;
892 if (!Adapter
->WorkQueueHead
)
894 Adapter
->WorkQueueHead
= MiniportWorkItem
;
895 Adapter
->WorkQueueTail
= MiniportWorkItem
;
899 Adapter
->WorkQueueTail
->Link
.Next
= (PSINGLE_LIST_ENTRY
)MiniportWorkItem
;
900 Adapter
->WorkQueueTail
= MiniportWorkItem
;
904 IoWorkItem
= IoAllocateWorkItem(Adapter
->NdisMiniportBlock
.DeviceObject
);
906 IoQueueWorkItem(IoWorkItem
, MiniportWorker
, DelayedWorkQueue
, IoWorkItem
);
908 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
915 PLOGICAL_ADAPTER Adapter
,
916 NDIS_WORK_ITEM_TYPE
*WorkItemType
,
917 PVOID
*WorkItemContext
)
919 * FUNCTION: Dequeues a work item from the work queue of a logical adapter
921 * Adapter = Pointer to the logical adapter object to dequeue work item from
922 * AdapterBinding = Address of buffer for adapter binding for this request
923 * WorkItemType = Address of buffer for work item type
924 * WorkItemContext = Address of buffer for pointer to context information
926 * Adapter lock must be held when called
928 * Status of operation
931 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
934 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
936 MiniportWorkItem
= Adapter
->WorkQueueHead
;
938 if ((Packet
= Adapter
->NdisMiniportBlock
.FirstPendingPacket
))
940 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= NULL
;
942 *WorkItemType
= NdisWorkItemSend
;
943 *WorkItemContext
= Packet
;
945 return NDIS_STATUS_SUCCESS
;
947 else if (MiniportWorkItem
)
949 /* safe due to adapter lock held */
950 Adapter
->WorkQueueHead
= (PNDIS_MINIPORT_WORK_ITEM
)MiniportWorkItem
->Link
.Next
;
952 if (MiniportWorkItem
== Adapter
->WorkQueueTail
)
953 Adapter
->WorkQueueTail
= NULL
;
955 *WorkItemType
= MiniportWorkItem
->WorkItemType
;
956 *WorkItemContext
= MiniportWorkItem
->WorkItemContext
;
958 ExFreePool(MiniportWorkItem
);
960 return NDIS_STATUS_SUCCESS
;
964 NDIS_DbgPrint(MIN_TRACE
, ("No work item to dequeue\n"));
966 return NDIS_STATUS_FAILURE
;
973 PLOGICAL_ADAPTER Adapter
,
974 PNDIS_REQUEST NdisRequest
)
976 * FUNCTION: Sends a request to a miniport
978 * AdapterBinding = Pointer to binding used in the request
979 * NdisRequest = Pointer to NDIS request structure describing request
981 * Status of operation
986 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
988 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
990 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
991 Adapter
->NdisMiniportBlock
.PendingRequest
= NdisRequest
;
992 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
994 if (!Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CoRequestHandler
)
996 switch (NdisRequest
->RequestType
)
998 case NdisRequestQueryInformation
:
999 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.QueryInformationHandler
)(
1000 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1001 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
,
1002 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
,
1003 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
,
1004 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
,
1005 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesNeeded
);
1008 case NdisRequestSetInformation
:
1009 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SetInformationHandler
)(
1010 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1011 NdisRequest
->DATA
.SET_INFORMATION
.Oid
,
1012 NdisRequest
->DATA
.SET_INFORMATION
.InformationBuffer
,
1013 NdisRequest
->DATA
.SET_INFORMATION
.InformationBufferLength
,
1014 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesRead
,
1015 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesNeeded
);
1019 NDIS_DbgPrint(MIN_TRACE
, ("Bad request type\n"));
1020 Status
= NDIS_STATUS_FAILURE
;
1025 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CoRequestHandler
)(
1026 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1031 if (Status
!= NDIS_STATUS_PENDING
) {
1032 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1033 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
1034 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1037 KeLowerIrql(OldIrql
);
1045 #undef NdisMSetInformationComplete
1048 NdisMSetInformationComplete(
1049 IN NDIS_HANDLE MiniportAdapterHandle
,
1050 IN NDIS_STATUS Status
)
1052 PLOGICAL_ADAPTER Adapter
=
1053 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
1056 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1057 if (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)
1058 (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)(MiniportAdapterHandle
, Status
);
1059 KeLowerIrql(OldIrql
);
1066 #undef NdisMQueryInformationComplete
1069 NdisMQueryInformationComplete(
1070 IN NDIS_HANDLE MiniportAdapterHandle
,
1071 IN NDIS_STATUS Status
)
1073 PLOGICAL_ADAPTER Adapter
=
1074 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
1077 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1078 if( Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)
1079 (Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)(MiniportAdapterHandle
, Status
);
1080 KeLowerIrql(OldIrql
);
1085 MiniportWorker(IN PDEVICE_OBJECT DeviceObject
, IN PVOID Context
)
1087 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
1088 KIRQL OldIrql
, RaiseOldIrql
;
1089 NDIS_STATUS NdisStatus
;
1090 PVOID WorkItemContext
;
1091 NDIS_WORK_ITEM_TYPE WorkItemType
;
1092 BOOLEAN AddressingReset
;
1094 IoFreeWorkItem((PIO_WORKITEM
)Context
);
1096 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1100 (Adapter
, &WorkItemType
, &WorkItemContext
);
1102 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1104 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1106 switch (WorkItemType
)
1108 case NdisWorkItemSend
:
1110 * called by ProSend when protocols want to send packets to the miniport
1113 if(Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)
1115 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1117 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1118 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1119 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1120 NdisStatus
= NDIS_STATUS_PENDING
;
1124 /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */
1125 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1127 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1128 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1129 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1131 KeLowerIrql(RaiseOldIrql
);
1133 NdisStatus
= NDIS_GET_PACKET_STATUS((PNDIS_PACKET
)WorkItemContext
);
1134 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1135 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1142 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1144 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1145 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1146 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1147 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1148 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1152 /* Send is called at DISPATCH_LEVEL for all serialized miniports */
1153 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1154 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1155 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1156 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1157 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1158 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1159 KeLowerIrql(RaiseOldIrql
);
1160 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1161 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1167 if( NdisStatus
!= NDIS_STATUS_PENDING
) {
1169 ( Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1173 case NdisWorkItemSendLoopback
:
1175 * called by ProSend when protocols want to send loopback packets
1177 /* XXX atm ProIndicatePacket sends a packet up via the loopback adapter only */
1178 NdisStatus
= ProIndicatePacket(Adapter
, (PNDIS_PACKET
)WorkItemContext
);
1180 if( NdisStatus
!= NDIS_STATUS_PENDING
)
1181 MiniSendComplete((NDIS_HANDLE
)Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1184 case NdisWorkItemReturnPackets
:
1187 case NdisWorkItemResetRequested
:
1188 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
1189 NdisMIndicateStatusComplete(Adapter
);
1191 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1192 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
1193 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1196 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1197 Adapter
->NdisMiniportBlock
.ResetStatus
= NdisStatus
;
1198 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1200 KeLowerIrql(OldIrql
);
1202 if (NdisStatus
!= NDIS_STATUS_PENDING
)
1203 MiniResetComplete(Adapter
, NdisStatus
, AddressingReset
);
1206 case NdisWorkItemResetInProgress
:
1209 case NdisWorkItemMiniportCallback
:
1212 case NdisWorkItemRequest
:
1213 NdisStatus
= MiniDoRequest(Adapter
, (PNDIS_REQUEST
)WorkItemContext
);
1215 if (NdisStatus
== NDIS_STATUS_PENDING
)
1218 switch (((PNDIS_REQUEST
)WorkItemContext
)->RequestType
)
1220 case NdisRequestQueryInformation
:
1221 NdisMQueryInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1224 case NdisRequestSetInformation
:
1225 NdisMSetInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1229 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS request type.\n"));
1235 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS work item type (%d).\n", WorkItemType
));
1246 IN NDIS_HANDLE MiniportHandle
,
1247 IN NDIS_STATUS GeneralStatus
,
1248 IN PVOID StatusBuffer
,
1249 IN UINT StatusBufferSize
)
1251 PLOGICAL_ADAPTER Adapter
= MiniportHandle
;
1252 PLIST_ENTRY CurrentEntry
;
1253 PADAPTER_BINDING AdapterBinding
;
1256 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1258 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1260 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1262 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1264 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusHandler
)(
1265 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
1270 CurrentEntry
= CurrentEntry
->Flink
;
1273 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1280 IN NDIS_HANDLE MiniportAdapterHandle
)
1282 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1283 PLIST_ENTRY CurrentEntry
;
1284 PADAPTER_BINDING AdapterBinding
;
1287 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1289 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1291 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1293 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1295 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusCompleteHandler
)(
1296 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
);
1298 CurrentEntry
= CurrentEntry
->Flink
;
1301 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1311 IN NDIS_HANDLE LogHandle
)
1313 PNDIS_LOG Log
= (PNDIS_LOG
)LogHandle
;
1314 PNDIS_MINIPORT_BLOCK Miniport
= Log
->Miniport
;
1317 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1319 KeAcquireSpinLock(&(Miniport
)->Lock
, &OldIrql
);
1320 Miniport
->Log
= NULL
;
1321 KeReleaseSpinLock(&(Miniport
)->Lock
, OldIrql
);
1332 IN NDIS_HANDLE MiniportAdapterHandle
,
1334 OUT PNDIS_HANDLE LogHandle
)
1336 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1340 NDIS_DbgPrint(MAX_TRACE
, ("called: MiniportAdapterHandle 0x%x, Size %ld\n", MiniportAdapterHandle
, Size
));
1342 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1344 if (Adapter
->NdisMiniportBlock
.Log
)
1347 return NDIS_STATUS_FAILURE
;
1350 Log
= ExAllocatePool(NonPagedPool
, Size
+ sizeof(NDIS_LOG
));
1354 return NDIS_STATUS_RESOURCES
;
1357 Adapter
->NdisMiniportBlock
.Log
= Log
;
1359 KeInitializeSpinLock(&Log
->LogLock
);
1361 Log
->Miniport
= &Adapter
->NdisMiniportBlock
;
1362 Log
->TotalSize
= Size
;
1363 Log
->CurrentSize
= 0;
1370 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1372 return NDIS_STATUS_SUCCESS
;
1380 NdisMDeregisterAdapterShutdownHandler(
1381 IN NDIS_HANDLE MiniportHandle
)
1383 * FUNCTION: de-registers a shutdown handler
1384 * ARGUMENTS: MiniportHandle: Handle passed into MiniportInitialize
1387 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1389 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1391 if(Adapter
->BugcheckContext
->ShutdownHandler
) {
1392 KeDeregisterBugCheckCallback(Adapter
->BugcheckContext
->CallbackRecord
);
1393 IoUnregisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1403 IN NDIS_HANDLE LogHandle
)
1405 PNDIS_LOG Log
= (PNDIS_LOG
) LogHandle
;
1408 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1411 KeAcquireSpinLock(&Log
->LogLock
, &OldIrql
);
1413 /* Set buffers size */
1414 Log
->CurrentSize
= 0;
1419 KeReleaseSpinLock(&Log
->LogLock
, OldIrql
);
1425 #undef NdisMIndicateStatus
1428 NdisMIndicateStatus(
1429 IN NDIS_HANDLE MiniportAdapterHandle
,
1430 IN NDIS_STATUS GeneralStatus
,
1431 IN PVOID StatusBuffer
,
1432 IN UINT StatusBufferSize
)
1434 MiniStatus(MiniportAdapterHandle
, GeneralStatus
, StatusBuffer
, StatusBufferSize
);
1440 #undef NdisMIndicateStatusComplete
1443 NdisMIndicateStatusComplete(
1444 IN NDIS_HANDLE MiniportAdapterHandle
)
1446 MiniStatusComplete(MiniportAdapterHandle
);
1455 NdisInitializeWrapper(
1456 OUT PNDIS_HANDLE NdisWrapperHandle
,
1457 IN PVOID SystemSpecific1
,
1458 IN PVOID SystemSpecific2
,
1459 IN PVOID SystemSpecific3
)
1461 * FUNCTION: Notifies the NDIS library that a new miniport is initializing
1463 * NdisWrapperHandle = Address of buffer to place NDIS wrapper handle
1464 * SystemSpecific1 = Pointer to the driver's driver object
1465 * SystemSpecific2 = Pointer to the driver's registry path
1466 * SystemSpecific3 = Always NULL
1468 * - SystemSpecific2 goes invalid so we copy it
1471 PNDIS_M_DRIVER_BLOCK Miniport
;
1472 PUNICODE_STRING RegistryPath
;
1473 WCHAR
*RegistryBuffer
;
1475 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1477 ASSERT(NdisWrapperHandle
);
1479 *NdisWrapperHandle
= NULL
;
1481 #if BREAK_ON_MINIPORT_INIT
1485 Miniport
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DRIVER_BLOCK
));
1489 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1493 RtlZeroMemory(Miniport
, sizeof(NDIS_M_DRIVER_BLOCK
));
1495 KeInitializeSpinLock(&Miniport
->Lock
);
1497 Miniport
->DriverObject
= (PDRIVER_OBJECT
)SystemSpecific1
;
1499 /* set the miniport's driver registry path */
1500 RegistryPath
= ExAllocatePool(PagedPool
, sizeof(UNICODE_STRING
));
1503 ExFreePool(Miniport
);
1504 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1508 RegistryPath
->Length
= ((PUNICODE_STRING
)SystemSpecific2
)->Length
;
1509 RegistryPath
->MaximumLength
= RegistryPath
->Length
+ sizeof(WCHAR
); /* room for 0-term */
1511 RegistryBuffer
= ExAllocatePool(PagedPool
, RegistryPath
->MaximumLength
);
1514 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1515 ExFreePool(Miniport
);
1516 ExFreePool(RegistryPath
);
1520 RtlCopyMemory(RegistryBuffer
, ((PUNICODE_STRING
)SystemSpecific2
)->Buffer
, RegistryPath
->Length
);
1521 RegistryBuffer
[RegistryPath
->Length
/sizeof(WCHAR
)] = 0;
1523 RegistryPath
->Buffer
= RegistryBuffer
;
1524 Miniport
->RegistryPath
= RegistryPath
;
1526 InitializeListHead(&Miniport
->DeviceList
);
1528 /* Put miniport in global miniport list */
1529 ExInterlockedInsertTailList(&MiniportListHead
, &Miniport
->ListEntry
, &MiniportListLock
);
1531 *NdisWrapperHandle
= Miniport
;
1535 VOID NTAPI
NdisIBugcheckCallback(
1539 * FUNCTION: Internal callback for handling bugchecks - calls adapter's shutdown handler
1541 * Buffer: Pointer to a bugcheck callback context
1545 PMINIPORT_BUGCHECK_CONTEXT Context
= (PMINIPORT_BUGCHECK_CONTEXT
)Buffer
;
1546 ADAPTER_SHUTDOWN_HANDLER sh
= (ADAPTER_SHUTDOWN_HANDLER
)Context
->ShutdownHandler
;
1548 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1551 sh(Context
->DriverContext
);
1560 NdisMRegisterAdapterShutdownHandler(
1561 IN NDIS_HANDLE MiniportHandle
,
1562 IN PVOID ShutdownContext
,
1563 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
1565 * FUNCTION: Register a shutdown handler for an adapter
1567 * MiniportHandle: Handle originally passed into MiniportInitialize
1568 * ShutdownContext: Pre-initialized bugcheck context
1569 * ShutdownHandler: Function to call to handle the bugcheck
1571 * - I'm not sure about ShutdownContext
1574 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1575 PMINIPORT_BUGCHECK_CONTEXT BugcheckContext
;
1577 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1579 BugcheckContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_BUGCHECK_CONTEXT
));
1580 if(!BugcheckContext
)
1582 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1586 BugcheckContext
->ShutdownHandler
= ShutdownHandler
;
1587 BugcheckContext
->DriverContext
= ShutdownContext
;
1589 BugcheckContext
->CallbackRecord
= ExAllocatePool(NonPagedPool
, sizeof(KBUGCHECK_CALLBACK_RECORD
));
1590 if (!BugcheckContext
->CallbackRecord
) {
1591 ExFreePool(BugcheckContext
);
1595 Adapter
->BugcheckContext
= BugcheckContext
;
1597 KeInitializeCallbackRecord(BugcheckContext
->CallbackRecord
);
1599 KeRegisterBugCheckCallback(BugcheckContext
->CallbackRecord
, NdisIBugcheckCallback
,
1600 BugcheckContext
, sizeof(*BugcheckContext
), (PUCHAR
)"Ndis Miniport");
1602 IoRegisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1608 PLOGICAL_ADAPTER Adapter
,
1609 NDIS_OID AddressOID
)
1611 * FUNCTION: Queries miniport for information
1613 * Adapter = Pointer to logical adapter
1614 * AddressOID = OID to use to query for current address
1616 * Status of operation
1620 NDIS_STATUS NdisStatus
;
1622 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1624 /* Get MAC options for adapter */
1625 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAC_OPTIONS
, sizeof(UINT
),
1626 &Adapter
->NdisMiniportBlock
.MacOptions
,
1629 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1631 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAC_OPTIONS failed. NdisStatus (0x%X).\n", NdisStatus
));
1635 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MacOptions (0x%X).\n", Adapter
->NdisMiniportBlock
.MacOptions
));
1637 /* Get current hardware address of adapter */
1638 NdisStatus
= MiniQueryInformation(Adapter
, AddressOID
, Adapter
->AddressLength
,
1639 &Adapter
->Address
, &BytesWritten
);
1641 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1643 NDIS_DbgPrint(MIN_TRACE
, ("Address OID (0x%X) failed. NdisStatus (0x%X).\n", AddressOID
, NdisStatus
));
1651 PUCHAR A
= (PUCHAR
)&Adapter
->Address
.Type
.Medium802_3
;
1653 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]));
1657 /* Get maximum lookahead buffer size of adapter */
1658 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_LOOKAHEAD
, sizeof(ULONG
),
1659 &Adapter
->NdisMiniportBlock
.MaximumLookahead
, &BytesWritten
);
1661 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1663 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1667 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MaxLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.MaximumLookahead
));
1669 /* Get current lookahead buffer size of adapter */
1670 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_CURRENT_LOOKAHEAD
, sizeof(ULONG
),
1671 &Adapter
->NdisMiniportBlock
.CurrentLookahead
, &BytesWritten
);
1673 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1675 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_CURRENT_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1679 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_SEND_PACKETS
, sizeof(ULONG
),
1680 &Adapter
->NdisMiniportBlock
.MaxSendPackets
, &BytesWritten
);
1682 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1684 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_SEND_PACKETS failed. NdisStatus (0x%X).\n", NdisStatus
));
1686 /* Set it to 1 if it fails because some drivers don't support this (?)*/
1687 Adapter
->NdisMiniportBlock
.MaxSendPackets
= 1;
1690 NDIS_DbgPrint(DEBUG_MINIPORT
, ("CurLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.CurrentLookahead
));
1692 return STATUS_SUCCESS
;
1698 NdisIForwardIrpAndWaitCompletionRoutine(
1703 PKEVENT Event
= Context
;
1705 if (Irp
->PendingReturned
)
1706 KeSetEvent(Event
, IO_NO_INCREMENT
, FALSE
);
1708 return STATUS_MORE_PROCESSING_REQUIRED
;
1714 NdisIForwardIrpAndWait(PLOGICAL_ADAPTER Adapter
, PIRP Irp
)
1719 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1720 IoCopyCurrentIrpStackLocationToNext(Irp
);
1721 IoSetCompletionRoutine(Irp
, NdisIForwardIrpAndWaitCompletionRoutine
, &Event
,
1723 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
1724 if (Status
== STATUS_PENDING
)
1726 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1727 Status
= Irp
->IoStatus
.Status
;
1735 IN PDEVICE_OBJECT DeviceObject
,
1738 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1739 Irp
->IoStatus
.Information
= 0;
1741 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1743 return STATUS_SUCCESS
;
1749 NdisIPnPStartDevice(
1750 IN PDEVICE_OBJECT DeviceObject
,
1753 * FUNCTION: Handle the PnP start device event
1755 * DeviceObejct = Functional Device Object
1756 * Irp = IRP_MN_START_DEVICE I/O request packet
1758 * Status of operation
1761 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
1762 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1763 NDIS_WRAPPER_CONTEXT WrapperContext
;
1764 NDIS_STATUS NdisStatus
;
1765 NDIS_STATUS OpenErrorStatus
;
1767 UINT SelectedMediumIndex
= 0;
1768 NDIS_OID AddressOID
;
1769 BOOLEAN Success
= FALSE
;
1770 ULONG ResourceCount
;
1771 ULONG ResourceListSize
;
1772 UNICODE_STRING ParamName
;
1773 PNDIS_CONFIGURATION_PARAMETER ConfigParam
;
1774 NDIS_HANDLE ConfigHandle
;
1776 LARGE_INTEGER Timeout
;
1777 UINT MaxMulticastAddresses
;
1779 PLIST_ENTRY CurrentEntry
;
1780 PPROTOCOL_BINDING ProtocolBinding
;
1783 * Prepare wrapper context used by HW and configuration routines.
1786 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Start Device %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
1788 NDIS_DbgPrint(MAX_TRACE
, ("Inserting adapter 0x%x into adapter list\n", Adapter
));
1790 /* Put adapter in global adapter list */
1791 ExInterlockedInsertTailList(&AdapterListHead
, &Adapter
->ListEntry
, &AdapterListLock
);
1793 Status
= IoOpenDeviceRegistryKey(
1794 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
, PLUGPLAY_REGKEY_DRIVER
,
1795 KEY_ALL_ACCESS
, &WrapperContext
.RegistryHandle
);
1796 if (!NT_SUCCESS(Status
))
1798 NDIS_DbgPrint(MIN_TRACE
,("failed to open adapter-specific reg key\n"));
1799 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1803 NDIS_DbgPrint(MAX_TRACE
, ("opened device reg key\n"));
1805 WrapperContext
.DeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
1808 * Store the adapter resources used by HW routines such as
1809 * NdisMQueryAdapterResources.
1812 if (Stack
->Parameters
.StartDevice
.AllocatedResources
!= NULL
)
1814 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResources
->List
[0].
1815 PartialResourceList
.Count
;
1817 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1818 PartialDescriptors
[ResourceCount
]);
1820 Adapter
->NdisMiniportBlock
.AllocatedResources
=
1821 ExAllocatePool(PagedPool
, ResourceListSize
);
1822 if (Adapter
->NdisMiniportBlock
.AllocatedResources
== NULL
)
1824 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1825 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1826 return STATUS_INSUFFICIENT_RESOURCES
;
1829 Adapter
->NdisMiniportBlock
.Resources
=
1830 ExAllocatePool(PagedPool
, ResourceListSize
);
1831 if (!Adapter
->NdisMiniportBlock
.Resources
)
1833 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1834 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
1835 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
1836 return STATUS_INSUFFICIENT_RESOURCES
;
1839 RtlCopyMemory(Adapter
->NdisMiniportBlock
.Resources
,
1840 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1843 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResources
,
1844 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1848 if (Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
!= NULL
)
1850 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
->List
[0].
1851 PartialResourceList
.Count
;
1853 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1854 PartialDescriptors
[ResourceCount
]);
1856 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
=
1857 ExAllocatePool(PagedPool
, ResourceListSize
);
1858 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
== NULL
)
1860 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1861 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1862 return STATUS_INSUFFICIENT_RESOURCES
;
1865 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
,
1866 Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
,
1871 * Store the Bus Type, Bus Number and Slot information. It's used by
1872 * the hardware routines then.
1875 NdisOpenConfiguration(&NdisStatus
, &ConfigHandle
, (NDIS_HANDLE
)&WrapperContext
);
1876 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1878 NDIS_DbgPrint(MIN_TRACE
, ("Failed to open configuration key\n"));
1879 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1883 Size
= sizeof(ULONG
);
1884 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1885 DevicePropertyLegacyBusType
, Size
,
1886 &Adapter
->NdisMiniportBlock
.BusType
, &Size
);
1887 if (!NT_SUCCESS(Status
) || (INTERFACE_TYPE
)Adapter
->NdisMiniportBlock
.BusType
== InterfaceTypeUndefined
)
1889 NdisInitUnicodeString(&ParamName
, L
"BusType");
1890 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1891 &ParamName
, NdisParameterInteger
);
1892 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1893 Adapter
->NdisMiniportBlock
.BusType
= ConfigParam
->ParameterData
.IntegerData
;
1895 Adapter
->NdisMiniportBlock
.BusType
= Isa
;
1898 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1899 DevicePropertyBusNumber
, Size
,
1900 &Adapter
->NdisMiniportBlock
.BusNumber
, &Size
);
1901 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.BusNumber
== 0xFFFFFFF0)
1903 NdisInitUnicodeString(&ParamName
, L
"BusNumber");
1904 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1905 &ParamName
, NdisParameterInteger
);
1906 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1907 Adapter
->NdisMiniportBlock
.BusNumber
= ConfigParam
->ParameterData
.IntegerData
;
1909 Adapter
->NdisMiniportBlock
.BusNumber
= 0;
1911 WrapperContext
.BusNumber
= Adapter
->NdisMiniportBlock
.BusNumber
;
1913 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1914 DevicePropertyAddress
, Size
,
1915 &Adapter
->NdisMiniportBlock
.SlotNumber
, &Size
);
1916 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.SlotNumber
== (NDIS_INTERFACE_TYPE
)-1)
1918 NdisInitUnicodeString(&ParamName
, L
"SlotNumber");
1919 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1920 &ParamName
, NdisParameterInteger
);
1921 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1922 Adapter
->NdisMiniportBlock
.SlotNumber
= ConfigParam
->ParameterData
.IntegerData
;
1924 Adapter
->NdisMiniportBlock
.SlotNumber
= 0;
1928 /* Convert slotnumber to PCI_SLOT_NUMBER */
1929 ULONG PciSlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
1930 PCI_SLOT_NUMBER SlotNumber
;
1932 SlotNumber
.u
.AsULONG
= 0;
1933 SlotNumber
.u
.bits
.DeviceNumber
= (PciSlotNumber
>> 16) & 0xFFFF;
1934 SlotNumber
.u
.bits
.FunctionNumber
= PciSlotNumber
& 0xFFFF;
1936 Adapter
->NdisMiniportBlock
.SlotNumber
= SlotNumber
.u
.AsULONG
;
1938 WrapperContext
.SlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
1940 NdisCloseConfiguration(ConfigHandle
);
1942 /* Set handlers (some NDIS macros require these) */
1943 Adapter
->NdisMiniportBlock
.EthRxCompleteHandler
= EthFilterDprIndicateReceiveComplete
;
1944 Adapter
->NdisMiniportBlock
.EthRxIndicateHandler
= EthFilterDprIndicateReceive
;
1945 Adapter
->NdisMiniportBlock
.SendCompleteHandler
= MiniSendComplete
;
1946 Adapter
->NdisMiniportBlock
.SendResourcesHandler
= MiniSendResourcesAvailable
;
1947 Adapter
->NdisMiniportBlock
.ResetCompleteHandler
= MiniResetComplete
;
1948 Adapter
->NdisMiniportBlock
.TDCompleteHandler
= MiniTransferDataComplete
;
1949 Adapter
->NdisMiniportBlock
.PacketIndicateHandler
= MiniIndicateReceivePacket
;
1950 Adapter
->NdisMiniportBlock
.StatusHandler
= MiniStatus
;
1951 Adapter
->NdisMiniportBlock
.StatusCompleteHandler
= MiniStatusComplete
;
1952 Adapter
->NdisMiniportBlock
.SendPacketsHandler
= ProSendPackets
;
1953 Adapter
->NdisMiniportBlock
.QueryCompleteHandler
= MiniRequestComplete
;
1954 Adapter
->NdisMiniportBlock
.SetCompleteHandler
= MiniRequestComplete
;
1957 * Call MiniportInitialize.
1960 NDIS_DbgPrint(MID_TRACE
, ("calling MiniportInitialize\n"));
1961 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.InitializeHandler
)(
1962 &OpenErrorStatus
, &SelectedMediumIndex
, &MediaArray
[0],
1963 MEDIA_ARRAY_SIZE
, Adapter
, (NDIS_HANDLE
)&WrapperContext
);
1965 ZwClose(WrapperContext
.RegistryHandle
);
1967 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1969 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() failed for an adapter.\n"));
1970 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1971 if (Adapter
->NdisMiniportBlock
.Interrupt
)
1973 KeBugCheckEx(BUGCODE_ID_DRIVER
,
1975 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.Interrupt
,
1976 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.TimerQueue
,
1979 if (Adapter
->NdisMiniportBlock
.TimerQueue
)
1981 KeBugCheckEx(BUGCODE_ID_DRIVER
,
1983 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.Interrupt
,
1984 (ULONG_PTR
)Adapter
->NdisMiniportBlock
.TimerQueue
,
1990 if (SelectedMediumIndex
>= MEDIA_ARRAY_SIZE
)
1992 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() selected a bad index\n"));
1993 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1994 return NDIS_STATUS_UNSUPPORTED_MEDIA
;
1997 Adapter
->NdisMiniportBlock
.MediaType
= MediaArray
[SelectedMediumIndex
];
1999 switch (Adapter
->NdisMiniportBlock
.MediaType
)
2001 case NdisMedium802_3
:
2002 Adapter
->MediumHeaderSize
= 14; /* XXX figure out what to do about LLC */
2003 AddressOID
= OID_802_3_CURRENT_ADDRESS
;
2004 Adapter
->AddressLength
= ETH_LENGTH_OF_ADDRESS
;
2005 NdisStatus
= DoQueries(Adapter
, AddressOID
);
2006 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
2008 NdisStatus
= MiniQueryInformation(Adapter
, OID_802_3_MAXIMUM_LIST_SIZE
, sizeof(UINT
),
2009 &MaxMulticastAddresses
, &BytesWritten
);
2011 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2013 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
2014 NDIS_DbgPrint(MIN_TRACE
, ("MiniQueryInformation failed (%x)\n", NdisStatus
));
2018 Success
= EthCreateFilter(MaxMulticastAddresses
,
2019 Adapter
->Address
.Type
.Medium802_3
,
2020 &Adapter
->NdisMiniportBlock
.EthDB
);
2022 ((PETHI_FILTER
)Adapter
->NdisMiniportBlock
.EthDB
)->Miniport
= (PNDIS_MINIPORT_BLOCK
)Adapter
;
2024 NdisStatus
= NDIS_STATUS_RESOURCES
;
2029 /* FIXME: Support other types of media */
2030 NDIS_DbgPrint(MIN_TRACE
, ("error: unsupported media\n"));
2032 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
2033 return STATUS_UNSUCCESSFUL
;
2036 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2038 NDIS_DbgPrint(MIN_TRACE
, ("couldn't create filter (%x)\n", NdisStatus
));
2042 /* Check for a hang every two seconds if it wasn't set in MiniportInitialize */
2043 if (Adapter
->NdisMiniportBlock
.CheckForHangSeconds
== 0)
2044 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= 2;
2046 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
2047 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStarted
;
2049 IoSetDeviceInterfaceState(&Adapter
->NdisMiniportBlock
.SymbolicLinkName
, TRUE
);
2051 Timeout
.QuadPart
= Int32x32To64(Adapter
->NdisMiniportBlock
.CheckForHangSeconds
, -1000000);
2052 KeSetTimerEx(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
, Timeout
,
2053 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
* 1000,
2054 &Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
);
2056 /* Put adapter in adapter list for this miniport */
2057 ExInterlockedInsertTailList(&Adapter
->NdisMiniportBlock
.DriverHandle
->DeviceList
, &Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
2059 /* Refresh bindings for all protocols */
2060 CurrentEntry
= ProtocolListHead
.Flink
;
2061 while (CurrentEntry
!= &ProtocolListHead
)
2063 ProtocolBinding
= CONTAINING_RECORD(CurrentEntry
, PROTOCOL_BINDING
, ListEntry
);
2065 ndisBindMiniportsToProtocol(&NdisStatus
, ProtocolBinding
);
2067 CurrentEntry
= CurrentEntry
->Flink
;
2070 return STATUS_SUCCESS
;
2077 IN PDEVICE_OBJECT DeviceObject
,
2080 * FUNCTION: Handle the PnP stop device event
2082 * DeviceObejct = Functional Device Object
2083 * Irp = IRP_MN_STOP_DEVICE I/O request packet
2085 * Status of operation
2088 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2090 /* Remove adapter from adapter list for this miniport */
2091 ExInterlockedRemoveEntryList(&Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
2093 /* Remove adapter from global adapter list */
2094 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
2096 KeCancelTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
2098 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.HaltHandler
)(Adapter
);
2100 IoSetDeviceInterfaceState(&Adapter
->NdisMiniportBlock
.SymbolicLinkName
, FALSE
);
2102 if (Adapter
->NdisMiniportBlock
.AllocatedResources
)
2104 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
2105 Adapter
->NdisMiniportBlock
.AllocatedResources
= NULL
;
2107 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
)
2109 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
);
2110 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
= NULL
;
2113 if (Adapter
->NdisMiniportBlock
.Resources
)
2115 ExFreePool(Adapter
->NdisMiniportBlock
.Resources
);
2116 Adapter
->NdisMiniportBlock
.Resources
= NULL
;
2119 if (Adapter
->NdisMiniportBlock
.EthDB
)
2121 EthDeleteFilter(Adapter
->NdisMiniportBlock
.EthDB
);
2122 Adapter
->NdisMiniportBlock
.EthDB
= NULL
;
2125 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
2126 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStopped
;
2128 return STATUS_SUCCESS
;
2134 IN PDEVICE_OBJECT DeviceObject
,
2137 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
2138 PMINIPORT_BUGCHECK_CONTEXT Context
= Adapter
->BugcheckContext
;
2139 ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
= Context
->ShutdownHandler
;
2141 ASSERT(ShutdownHandler
);
2143 ShutdownHandler(Context
->DriverContext
);
2145 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2146 Irp
->IoStatus
.Information
= 0;
2148 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2150 return STATUS_SUCCESS
;
2155 NdisIDeviceIoControl(
2156 IN PDEVICE_OBJECT DeviceObject
,
2159 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2160 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2161 NDIS_STATUS Status
= STATUS_NOT_SUPPORTED
;
2164 Irp
->IoStatus
.Information
= 0;
2168 switch (Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
2170 case IOCTL_NDIS_QUERY_GLOBAL_STATS
:
2171 Status
= MiniQueryInformation(Adapter
,
2172 *(PNDIS_OID
)Irp
->AssociatedIrp
.SystemBuffer
,
2173 Stack
->Parameters
.DeviceIoControl
.OutputBufferLength
,
2174 MmGetSystemAddressForMdl(Irp
->MdlAddress
),
2176 Irp
->IoStatus
.Information
= Written
;
2184 if (Status
!= NDIS_STATUS_PENDING
)
2186 Irp
->IoStatus
.Status
= Status
;
2187 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2190 IoMarkIrpPending(Irp
);
2199 IN PDEVICE_OBJECT DeviceObject
,
2202 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2203 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2206 switch (Stack
->MinorFunction
)
2208 case IRP_MN_START_DEVICE
:
2209 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2210 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2212 Status
= NdisIPnPStartDevice(DeviceObject
, Irp
);
2215 NDIS_DbgPrint(MIN_TRACE
, ("Lower driver failed device start\n"));
2216 Irp
->IoStatus
.Status
= Status
;
2217 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2220 case IRP_MN_STOP_DEVICE
:
2221 Status
= NdisIPnPStopDevice(DeviceObject
, Irp
);
2222 if (!NT_SUCCESS(Status
))
2223 NDIS_DbgPrint(MIN_TRACE
, ("WARNING: Ignoring halt device failure! Passing the IRP down anyway\n"));
2224 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2227 case IRP_MN_QUERY_REMOVE_DEVICE
:
2228 case IRP_MN_QUERY_STOP_DEVICE
:
2229 Status
= NdisIPnPQueryStopDevice(DeviceObject
, Irp
);
2230 Irp
->IoStatus
.Status
= Status
;
2231 if (Status
!= STATUS_SUCCESS
)
2233 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2234 NDIS_DbgPrint(MIN_TRACE
, ("Failing miniport halt request\n"));
2239 case IRP_MN_CANCEL_REMOVE_DEVICE
:
2240 case IRP_MN_CANCEL_STOP_DEVICE
:
2241 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2242 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2244 Status
= NdisIPnPCancelStopDevice(DeviceObject
, Irp
);
2248 NDIS_DbgPrint(MIN_TRACE
, ("Lower driver failed cancel stop/remove request\n"));
2250 Irp
->IoStatus
.Status
= Status
;
2251 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2254 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
2255 Status
= NDIS_STATUS_SUCCESS
;
2256 Irp
->IoStatus
.Status
= Status
;
2257 Irp
->IoStatus
.Information
|= Adapter
->NdisMiniportBlock
.PnPFlags
;
2264 IoSkipCurrentIrpStackLocation(Irp
);
2265 return IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
2272 IN PDRIVER_OBJECT DriverObject
,
2273 IN PDEVICE_OBJECT PhysicalDeviceObject
)
2275 * FUNCTION: Create a device for an adapter found using PnP
2277 * DriverObject = Pointer to the miniport driver object
2278 * PhysicalDeviceObject = Pointer to the PDO for our adapter
2281 static const WCHAR ClassKeyName
[] = {'C','l','a','s','s','\\'};
2282 static const WCHAR LinkageKeyName
[] = {'\\','L','i','n','k','a','g','e',0};
2283 PNDIS_M_DRIVER_BLOCK Miniport
;
2284 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2285 WCHAR
*LinkageKeyBuffer
;
2286 ULONG DriverKeyLength
;
2287 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
2288 UNICODE_STRING ExportName
;
2289 PDEVICE_OBJECT DeviceObject
;
2290 PLOGICAL_ADAPTER Adapter
;
2294 * Gain the access to the miniport data structure first.
2297 MiniportPtr
= IoGetDriverObjectExtension(DriverObject
, (PVOID
)'NMID');
2298 if (MiniportPtr
== NULL
)
2300 NDIS_DbgPrint(MIN_TRACE
, ("Can't get driver object extension.\n"));
2301 return NDIS_STATUS_FAILURE
;
2303 Miniport
= *MiniportPtr
;
2306 * Get name of the Linkage registry key for our adapter. It's located under
2307 * the driver key for our driver and so we have basicly two ways to do it.
2308 * Either we can use IoOpenDriverRegistryKey or compose it using information
2309 * gathered by IoGetDeviceProperty. I choosed the second because
2310 * IoOpenDriverRegistryKey wasn't implemented at the time of writing.
2313 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2314 0, NULL
, &DriverKeyLength
);
2315 if (Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
&& Status
!= STATUS_SUCCESS
)
2317 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport driver key length.\n"));
2321 LinkageKeyBuffer
= ExAllocatePool(PagedPool
, DriverKeyLength
+
2322 sizeof(ClassKeyName
) + sizeof(LinkageKeyName
));
2323 if (LinkageKeyBuffer
== NULL
)
2325 NDIS_DbgPrint(MIN_TRACE
, ("Can't allocate memory for driver key name.\n"));
2326 return STATUS_INSUFFICIENT_RESOURCES
;
2329 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2330 DriverKeyLength
, LinkageKeyBuffer
+
2331 (sizeof(ClassKeyName
) / sizeof(WCHAR
)),
2333 if (!NT_SUCCESS(Status
))
2335 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport driver key.\n"));
2336 ExFreePool(LinkageKeyBuffer
);
2340 /* Compose the linkage key name. */
2341 RtlCopyMemory(LinkageKeyBuffer
, ClassKeyName
, sizeof(ClassKeyName
));
2342 RtlCopyMemory(LinkageKeyBuffer
+ ((sizeof(ClassKeyName
) + DriverKeyLength
) /
2343 sizeof(WCHAR
)) - 1, LinkageKeyName
, sizeof(LinkageKeyName
));
2345 NDIS_DbgPrint(DEBUG_MINIPORT
, ("LinkageKey: %S.\n", LinkageKeyBuffer
));
2348 * Now open the linkage key and read the "Export" and "RootDevice" values
2349 * which contains device name and root service respectively.
2352 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
2353 RtlInitUnicodeString(&ExportName
, NULL
);
2354 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
| RTL_QUERY_REGISTRY_DIRECT
;
2355 QueryTable
[0].Name
= L
"Export";
2356 QueryTable
[0].EntryContext
= &ExportName
;
2358 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
, LinkageKeyBuffer
,
2359 QueryTable
, NULL
, NULL
);
2360 ExFreePool(LinkageKeyBuffer
);
2361 if (!NT_SUCCESS(Status
))
2363 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport device name. (%x)\n", Status
));
2368 * Create the device object.
2371 NDIS_DbgPrint(MAX_TRACE
, ("creating device %wZ\n", &ExportName
));
2373 Status
= IoCreateDevice(Miniport
->DriverObject
, sizeof(LOGICAL_ADAPTER
),
2374 &ExportName
, FILE_DEVICE_PHYSICAL_NETCARD
,
2375 0, FALSE
, &DeviceObject
);
2376 if (!NT_SUCCESS(Status
))
2378 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device object.\n"));
2379 RtlFreeUnicodeString(&ExportName
);
2384 * Initialize the adapter structure.
2387 Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2388 KeInitializeSpinLock(&Adapter
->NdisMiniportBlock
.Lock
);
2389 InitializeListHead(&Adapter
->ProtocolListHead
);
2391 Status
= IoRegisterDeviceInterface(PhysicalDeviceObject
,
2392 &GUID_DEVINTERFACE_NET
,
2394 &Adapter
->NdisMiniportBlock
.SymbolicLinkName
);
2396 if (!NT_SUCCESS(Status
))
2398 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device interface.\n"));
2399 IoDeleteDevice(DeviceObject
);
2400 RtlFreeUnicodeString(&ExportName
);
2404 Adapter
->NdisMiniportBlock
.DriverHandle
= Miniport
;
2405 Adapter
->NdisMiniportBlock
.MiniportName
= ExportName
;
2406 Adapter
->NdisMiniportBlock
.DeviceObject
= DeviceObject
;
2407 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
= PhysicalDeviceObject
;
2408 Adapter
->NdisMiniportBlock
.NextDeviceObject
=
2409 IoAttachDeviceToDeviceStack(Adapter
->NdisMiniportBlock
.DeviceObject
,
2410 PhysicalDeviceObject
);
2412 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= 0;
2413 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceAdded
;
2415 KeInitializeTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
2416 KeInitializeDpc(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
, MiniportHangDpc
, Adapter
);
2418 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
2420 return STATUS_SUCCESS
;
2429 NdisMRegisterMiniport(
2430 IN NDIS_HANDLE NdisWrapperHandle
,
2431 IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics
,
2432 IN UINT CharacteristicsLength
)
2434 * FUNCTION: Registers a miniport's MiniportXxx entry points with the NDIS library
2436 * NdisWrapperHandle = Pointer to handle returned by NdisMInitializeWrapper
2437 * MiniportCharacteristics = Pointer to a buffer with miniport characteristics
2438 * CharacteristicsLength = Number of bytes in characteristics buffer
2440 * Status of operation
2444 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2445 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2448 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2450 switch (MiniportCharacteristics
->MajorNdisVersion
)
2453 MinSize
= sizeof(NDIS30_MINIPORT_CHARACTERISTICS
);
2457 MinSize
= sizeof(NDIS40_MINIPORT_CHARACTERISTICS
);
2461 switch (MiniportCharacteristics
->MinorNdisVersion
)
2464 MinSize
= sizeof(NDIS50_MINIPORT_CHARACTERISTICS
);
2468 MinSize
= sizeof(NDIS51_MINIPORT_CHARACTERISTICS
);
2472 NDIS_DbgPrint(MIN_TRACE
, ("Bad 5.x minor characteristics version.\n"));
2473 return NDIS_STATUS_BAD_VERSION
;
2478 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics version.\n"));
2479 return NDIS_STATUS_BAD_VERSION
;
2482 NDIS_DbgPrint(MIN_TRACE
, ("Initializing an NDIS %u.%u miniport\n",
2483 MiniportCharacteristics
->MajorNdisVersion
,
2484 MiniportCharacteristics
->MinorNdisVersion
));
2486 if (CharacteristicsLength
< MinSize
)
2488 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics length.\n"));
2489 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2492 /* Check if mandatory MiniportXxx functions are specified */
2493 if ((!MiniportCharacteristics
->HaltHandler
) ||
2494 (!MiniportCharacteristics
->InitializeHandler
)||
2495 (!MiniportCharacteristics
->ResetHandler
))
2497 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics.\n"));
2498 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2501 if (MiniportCharacteristics
->MajorNdisVersion
< 0x05)
2503 if ((!MiniportCharacteristics
->QueryInformationHandler
) ||
2504 (!MiniportCharacteristics
->SetInformationHandler
))
2506 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (Set/Query)\n"));
2507 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2512 if (((!MiniportCharacteristics
->QueryInformationHandler
) ||
2513 (!MiniportCharacteristics
->SetInformationHandler
)) &&
2514 (!MiniportCharacteristics
->CoRequestHandler
))
2516 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (Set/Query)\n"));
2517 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2521 if (MiniportCharacteristics
->MajorNdisVersion
== 0x03)
2523 if (!MiniportCharacteristics
->SendHandler
)
2525 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 3.0)\n"));
2526 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2529 else if (MiniportCharacteristics
->MajorNdisVersion
== 0x04)
2532 if ((!MiniportCharacteristics
->SendHandler
) &&
2533 (!MiniportCharacteristics
->SendPacketsHandler
))
2535 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 4.0)\n"));
2536 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2539 else if (MiniportCharacteristics
->MajorNdisVersion
== 0x05)
2541 /* TODO: Add more checks here */
2543 if ((!MiniportCharacteristics
->SendHandler
) &&
2544 (!MiniportCharacteristics
->SendPacketsHandler
) &&
2545 (!MiniportCharacteristics
->CoSendPacketsHandler
))
2547 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 5.0)\n"));
2548 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2552 RtlCopyMemory(&Miniport
->MiniportCharacteristics
, MiniportCharacteristics
, MinSize
);
2555 * NOTE: This is VERY unoptimal! Should we store the NDIS_M_DRIVER_BLOCK
2556 * structure in the driver extension or what?
2559 Status
= IoAllocateDriverObjectExtension(Miniport
->DriverObject
, (PVOID
)'NMID',
2560 sizeof(PNDIS_M_DRIVER_BLOCK
), (PVOID
*)&MiniportPtr
);
2561 if (!NT_SUCCESS(Status
))
2563 NDIS_DbgPrint(MIN_TRACE
, ("Can't allocate driver object extension.\n"));
2564 return NDIS_STATUS_RESOURCES
;
2567 *MiniportPtr
= Miniport
;
2569 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = NdisICreateClose
;
2570 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = NdisICreateClose
;
2571 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_PNP
] = NdisIDispatchPnp
;
2572 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] = NdisIShutdown
;
2573 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = NdisIDeviceIoControl
;
2574 Miniport
->DriverObject
->DriverExtension
->AddDevice
= NdisIAddDevice
;
2576 return NDIS_STATUS_SUCCESS
;
2583 #undef NdisMResetComplete
2587 IN NDIS_HANDLE MiniportAdapterHandle
,
2588 IN NDIS_STATUS Status
,
2589 IN BOOLEAN AddressingReset
)
2591 MiniResetComplete(MiniportAdapterHandle
, Status
, AddressingReset
);
2598 #undef NdisMSendComplete
2602 IN NDIS_HANDLE MiniportAdapterHandle
,
2603 IN PNDIS_PACKET Packet
,
2604 IN NDIS_STATUS Status
)
2606 * FUNCTION: Forwards a message to the initiating protocol saying
2607 * that a packet was handled
2609 * NdisAdapterHandle = Handle input to MiniportInitialize
2610 * Packet = Pointer to NDIS packet that was sent
2611 * Status = Status of send operation
2614 MiniSendComplete(MiniportAdapterHandle
, Packet
, Status
);
2621 #undef NdisMSendResourcesAvailable
2624 NdisMSendResourcesAvailable(
2625 IN NDIS_HANDLE MiniportAdapterHandle
)
2627 MiniSendResourcesAvailable(MiniportAdapterHandle
);
2634 #undef NdisMTransferDataComplete
2637 NdisMTransferDataComplete(
2638 IN NDIS_HANDLE MiniportAdapterHandle
,
2639 IN PNDIS_PACKET Packet
,
2640 IN NDIS_STATUS Status
,
2641 IN UINT BytesTransferred
)
2643 MiniTransferDataComplete(MiniportAdapterHandle
, Packet
, Status
, BytesTransferred
);
2650 #undef NdisMSetAttributes
2654 IN NDIS_HANDLE MiniportAdapterHandle
,
2655 IN NDIS_HANDLE MiniportAdapterContext
,
2656 IN BOOLEAN BusMaster
,
2657 IN NDIS_INTERFACE_TYPE AdapterType
)
2659 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2661 * MiniportAdapterHandle = Handle input to MiniportInitialize
2662 * MiniportAdapterContext = Pointer to context information
2663 * BusMaster = Specifies TRUE if the caller's NIC is a busmaster DMA device
2664 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2667 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2668 NdisMSetAttributesEx(MiniportAdapterHandle
, MiniportAdapterContext
, 0,
2669 BusMaster
? NDIS_ATTRIBUTE_BUS_MASTER
: 0,
2679 NdisMSetAttributesEx(
2680 IN NDIS_HANDLE MiniportAdapterHandle
,
2681 IN NDIS_HANDLE MiniportAdapterContext
,
2682 IN UINT CheckForHangTimeInSeconds OPTIONAL
,
2683 IN ULONG AttributeFlags
,
2684 IN NDIS_INTERFACE_TYPE AdapterType
)
2686 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2688 * MiniportAdapterHandle = Handle input to MiniportInitialize
2689 * MiniportAdapterContext = Pointer to context information
2690 * CheckForHangTimeInSeconds = Specifies interval in seconds at which
2691 * MiniportCheckForHang should be called
2692 * AttributeFlags = Bitmask that indicates specific attributes
2693 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2696 PLOGICAL_ADAPTER Adapter
= GET_LOGICAL_ADAPTER(MiniportAdapterHandle
);
2698 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2700 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
= MiniportAdapterContext
;
2701 Adapter
->NdisMiniportBlock
.Flags
= AttributeFlags
;
2702 Adapter
->NdisMiniportBlock
.AdapterType
= AdapterType
;
2703 if (CheckForHangTimeInSeconds
> 0)
2704 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= CheckForHangTimeInSeconds
;
2705 if (AttributeFlags
& NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER
)
2706 NDIS_DbgPrint(MAX_TRACE
, ("Intermediate drivers not supported yet.\n"));
2709 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.AdapterShutdownHandler
)
2711 NDIS_DbgPrint(MAX_TRACE
, ("Miniport set AdapterShutdownHandler in MiniportCharacteristics\n"));
2712 NdisMRegisterAdapterShutdownHandler(Adapter
,
2713 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
2714 Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.AdapterShutdownHandler
);
2725 IN ULONG MicrosecondsToSleep
)
2727 * FUNCTION: delay the thread's execution for MicrosecondsToSleep
2729 * MicrosecondsToSleep: duh...
2731 * - Because this is a blocking call, current IRQL must be < DISPATCH_LEVEL
2735 LARGE_INTEGER DueTime
;
2739 DueTime
.QuadPart
= (-1) * 10 * MicrosecondsToSleep
;
2741 KeInitializeTimer(&Timer
);
2742 KeSetTimer(&Timer
, DueTime
, 0);
2743 KeWaitForSingleObject(&Timer
, Executive
, KernelMode
, FALSE
, 0);
2752 NdisMSynchronizeWithInterrupt(
2753 IN PNDIS_MINIPORT_INTERRUPT Interrupt
,
2754 IN PVOID SynchronizeFunction
,
2755 IN PVOID SynchronizeContext
)
2757 return(KeSynchronizeExecution(Interrupt
->InterruptObject
,
2758 (PKSYNCHRONIZE_ROUTINE
)SynchronizeFunction
,
2759 SynchronizeContext
));
2769 IN NDIS_HANDLE LogHandle
,
2771 IN UINT LogBufferSize
)
2773 PUCHAR Buffer
= LogBuffer
;
2777 for (i
= 0; i
< LogBufferSize
; i
+= 16)
2779 DbgPrint("%08x |", i
);
2780 for (j
= 0; j
< 16; j
++)
2783 if (idx
< LogBufferSize
)
2784 DbgPrint(" %02x", Buffer
[idx
]);
2789 for (j
= 0; j
< 16; j
++)
2792 if (idx
== LogBufferSize
)
2794 if (Buffer
[idx
] >= ' ') /* FIXME: not portable! replace by if (isprint(Buffer[idx])) ? */
2795 DbgPrint("%c", Buffer
[idx
]);
2802 return NDIS_STATUS_FAILURE
;
2811 NdisTerminateWrapper(
2812 IN NDIS_HANDLE NdisWrapperHandle
,
2813 IN PVOID SystemSpecific
)
2815 * FUNCTION: Releases resources allocated by a call to NdisInitializeWrapper
2817 * NdisWrapperHandle = Handle returned by NdisInitializeWrapper (NDIS_M_DRIVER_BLOCK)
2818 * SystemSpecific = Always NULL
2821 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2823 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2825 ExFreePool(Miniport
->RegistryPath
->Buffer
);
2826 ExFreePool(Miniport
->RegistryPath
);
2827 ExInterlockedRemoveEntryList(&Miniport
->ListEntry
, &MiniportListLock
);
2828 ExFreePool(Miniport
);
2837 NdisMQueryAdapterInstanceName(
2838 OUT PNDIS_STRING AdapterInstanceName
,
2839 IN NDIS_HANDLE MiniportAdapterHandle
)
2847 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
2848 UNICODE_STRING AdapterName
;
2850 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2852 AdapterName
.Length
= 0;
2853 AdapterName
.MaximumLength
= Adapter
->NdisMiniportBlock
.MiniportName
.MaximumLength
;
2854 AdapterName
.Buffer
= ExAllocatePool(PagedPool
, AdapterName
.MaximumLength
);
2855 if (!AdapterName
.Buffer
) {
2856 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
2857 return NDIS_STATUS_RESOURCES
;
2860 RtlCopyUnicodeString(&AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
);
2862 *AdapterInstanceName
= AdapterName
;
2864 return NDIS_STATUS_SUCCESS
;
2872 NdisDeregisterAdapterShutdownHandler(
2873 IN NDIS_HANDLE NdisAdapterHandle
)
2881 NdisMDeregisterAdapterShutdownHandler(NdisAdapterHandle
);
2890 NdisRegisterAdapterShutdownHandler(
2891 IN NDIS_HANDLE NdisAdapterHandle
,
2892 IN PVOID ShutdownContext
,
2893 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
2901 NdisMRegisterAdapterShutdownHandler(NdisAdapterHandle
,
2911 NdisMGetDeviceProperty(
2912 IN NDIS_HANDLE MiniportAdapterHandle
,
2913 IN OUT PDEVICE_OBJECT
*PhysicalDeviceObject OPTIONAL
,
2914 IN OUT PDEVICE_OBJECT
*FunctionalDeviceObject OPTIONAL
,
2915 IN OUT PDEVICE_OBJECT
*NextDeviceObject OPTIONAL
,
2916 IN OUT PCM_RESOURCE_LIST
*AllocatedResources OPTIONAL
,
2917 IN OUT PCM_RESOURCE_LIST
*AllocatedResourcesTranslated OPTIONAL
)
2925 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
2927 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
2929 if (PhysicalDeviceObject
!= NULL
)
2930 *PhysicalDeviceObject
= Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
;
2932 if (FunctionalDeviceObject
!= NULL
)
2933 *FunctionalDeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
2935 if (NextDeviceObject
!= NULL
)
2936 *NextDeviceObject
= Adapter
->NdisMiniportBlock
.NextDeviceObject
;
2938 if (AllocatedResources
!= NULL
)
2939 *AllocatedResources
= Adapter
->NdisMiniportBlock
.AllocatedResources
;
2941 if (AllocatedResourcesTranslated
!= NULL
)
2942 *AllocatedResourcesTranslated
= Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
;
2950 NdisMRegisterUnloadHandler(
2951 IN NDIS_HANDLE NdisWrapperHandle
,
2952 IN PDRIVER_UNLOAD UnloadHandler
)
2960 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
2962 NDIS_DbgPrint(MAX_TRACE
, ("Miniport registered unload handler\n"));
2964 DriverBlock
->DriverObject
->DriverUnload
= UnloadHandler
;
2972 NdisMRegisterDevice(
2973 IN NDIS_HANDLE NdisWrapperHandle
,
2974 IN PNDIS_STRING DeviceName
,
2975 IN PNDIS_STRING SymbolicName
,
2976 IN PDRIVER_DISPATCH MajorFunctions
[],
2977 OUT PDEVICE_OBJECT
*pDeviceObject
,
2978 OUT NDIS_HANDLE
*NdisDeviceHandle
)
2986 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
2987 PNDIS_M_DEVICE_BLOCK DeviceBlock
;
2988 PDEVICE_OBJECT DeviceObject
;
2992 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
2994 Status
= IoCreateDevice(DriverBlock
->DriverObject
,
2995 0, /* This space is reserved for us. Should we use it? */
2997 FILE_DEVICE_NETWORK
,
3002 if (!NT_SUCCESS(Status
))
3004 NDIS_DbgPrint(MIN_TRACE
, ("IoCreateDevice failed (%x)\n", Status
));
3008 Status
= IoCreateSymbolicLink(SymbolicName
, DeviceName
);
3010 if (!NT_SUCCESS(Status
))
3012 NDIS_DbgPrint(MIN_TRACE
, ("IoCreateSymbolicLink failed (%x)\n", Status
));
3013 IoDeleteDevice(DeviceObject
);
3017 DeviceBlock
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DEVICE_BLOCK
));
3021 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
3022 IoDeleteDevice(DeviceObject
);
3023 IoDeleteSymbolicLink(SymbolicName
);
3024 return NDIS_STATUS_RESOURCES
;
3027 for (i
= 0; i
<= IRP_MJ_MAXIMUM_FUNCTION
; i
++)
3028 DriverBlock
->DriverObject
->MajorFunction
[i
] = MajorFunctions
[i
];
3030 DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_PNP
] = NdisIDispatchPnp
;
3032 if (!DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_CREATE
])
3033 DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = NdisICreateClose
;
3035 if (!DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_CLOSE
])
3036 DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = NdisICreateClose
;
3038 DeviceBlock
->DeviceObject
= DeviceObject
;
3039 DeviceBlock
->SymbolicName
= SymbolicName
;
3041 *pDeviceObject
= DeviceObject
;
3042 *NdisDeviceHandle
= DeviceBlock
;
3044 return NDIS_STATUS_SUCCESS
;
3052 NdisMDeregisterDevice(
3053 IN NDIS_HANDLE NdisDeviceHandle
)
3061 PNDIS_M_DEVICE_BLOCK DeviceBlock
= NdisDeviceHandle
;
3063 IoDeleteDevice(DeviceBlock
->DeviceObject
);
3065 IoDeleteSymbolicLink(DeviceBlock
->SymbolicName
);
3067 ExFreePool(DeviceBlock
);
3069 return NDIS_STATUS_SUCCESS
;
3077 NdisQueryAdapterInstanceName(
3078 OUT PNDIS_STRING AdapterInstanceName
,
3079 IN NDIS_HANDLE NdisBindingHandle
)
3087 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3088 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3090 return NdisMQueryAdapterInstanceName(AdapterInstanceName
,
3099 NdisCompletePnPEvent(
3100 IN NDIS_STATUS Status
,
3101 IN NDIS_HANDLE NdisBindingHandle
,
3102 IN PNET_PNP_EVENT NetPnPEvent
)
3110 PIRP Irp
= (PIRP
)NetPnPEvent
->NdisReserved
[0];
3111 PLIST_ENTRY CurrentEntry
= (PLIST_ENTRY
)NetPnPEvent
->NdisReserved
[1];
3112 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3113 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3114 NDIS_STATUS NdisStatus
;
3116 if (Status
!= NDIS_STATUS_SUCCESS
)
3118 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3119 ExFreePool(NetPnPEvent
);
3120 Irp
->IoStatus
.Status
= Status
;
3121 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3125 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
3127 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
3129 NdisStatus
= (*AdapterBinding
->ProtocolBinding
->Chars
.PnPEventHandler
)(
3130 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
3133 if (NdisStatus
== NDIS_STATUS_PENDING
)
3135 NetPnPEvent
->NdisReserved
[1] = (ULONG_PTR
)CurrentEntry
->Flink
;
3138 else if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
3140 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3141 ExFreePool(NetPnPEvent
);
3142 Irp
->IoStatus
.Status
= NdisStatus
;
3143 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3147 CurrentEntry
= CurrentEntry
->Flink
;
3150 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3151 ExFreePool(NetPnPEvent
);
3153 Irp
->IoStatus
.Status
= NDIS_STATUS_SUCCESS
;
3154 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3162 NdisCancelSendPackets(
3163 IN NDIS_HANDLE NdisBindingHandle
,
3166 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3167 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3169 NDIS_DbgPrint(MAX_TRACE
, ("Called for ID %x.\n", CancelId
));
3171 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CancelSendPacketsHandler
)
3173 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CancelSendPacketsHandler
)(
3174 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
3185 NdisIMGetBindingContext(
3186 IN NDIS_HANDLE NdisBindingHandle
)
3194 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3195 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3197 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3199 return Adapter
->NdisMiniportBlock
.DeviceContext
;
3208 NdisIMGetDeviceContext(
3209 IN NDIS_HANDLE MiniportAdapterHandle
)
3217 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
3219 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3221 return Adapter
->NdisMiniportBlock
.DeviceContext
;