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"));
322 CopyBufferChainToBuffer(LookAheadBuffer
,
327 NdisStatus
= (*AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
)(
328 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
329 AdapterBinding
->NdisOpenBlock
.MacHandle
,
334 TotalBufferLength
- HeaderSize
);
336 NDIS_SET_PACKET_STATUS(PacketArray
[i
], NdisStatus
);
338 ExFreePool(LookAheadBuffer
);
342 CurrentEntry
= CurrentEntry
->Flink
;
345 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
351 IN NDIS_HANDLE MiniportAdapterHandle
,
352 IN NDIS_STATUS Status
,
353 IN BOOLEAN AddressingReset
)
355 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
356 PLIST_ENTRY CurrentEntry
;
357 PADAPTER_BINDING AdapterBinding
;
360 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
361 NdisMIndicateStatusComplete(Adapter
);
363 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
365 Adapter
->NdisMiniportBlock
.ResetStatus
= Status
;
367 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
369 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
371 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
373 (*AdapterBinding
->ProtocolBinding
->Chars
.ResetCompleteHandler
)(
374 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
377 CurrentEntry
= CurrentEntry
->Flink
;
380 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
385 IN NDIS_HANDLE MiniportAdapterHandle
,
386 IN NDIS_STATUS Status
)
388 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
389 PNDIS_REQUEST Request
;
390 PNDIS_REQUEST_MAC_BLOCK MacBlock
;
393 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
395 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
397 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
398 Request
= Adapter
->NdisMiniportBlock
.PendingRequest
;
399 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
401 MacBlock
= (PNDIS_REQUEST_MAC_BLOCK
)Request
->MacReserved
;
403 if( MacBlock
->Binding
->RequestCompleteHandler
) {
404 (*MacBlock
->Binding
->RequestCompleteHandler
)(
405 MacBlock
->Binding
->ProtocolBindingContext
,
410 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
411 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
412 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
414 KeLowerIrql(OldIrql
);
419 IN NDIS_HANDLE MiniportAdapterHandle
,
420 IN PNDIS_PACKET Packet
,
421 IN NDIS_STATUS Status
)
423 * FUNCTION: Forwards a message to the initiating protocol saying
424 * that a packet was handled
426 * NdisAdapterHandle = Handle input to MiniportInitialize
427 * Packet = Pointer to NDIS packet that was sent
428 * Status = Status of send operation
431 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
432 PADAPTER_BINDING AdapterBinding
;
434 PSCATTER_GATHER_LIST SGList
;
436 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
438 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
440 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
442 if (Adapter
->NdisMiniportBlock
.ScatterGatherListSize
!= 0)
444 NDIS_DbgPrint(MAX_TRACE
, ("Freeing Scatter/Gather list\n"));
446 SGList
= NDIS_PER_PACKET_INFO_FROM_PACKET(Packet
,
447 ScatterGatherListPacketInfo
);
449 Adapter
->NdisMiniportBlock
.SystemAdapterObject
->
450 DmaOperations
->PutScatterGatherList(
451 Adapter
->NdisMiniportBlock
.SystemAdapterObject
,
455 NDIS_PER_PACKET_INFO_FROM_PACKET(Packet
,
456 ScatterGatherListPacketInfo
) = NULL
;
459 (*AdapterBinding
->ProtocolBinding
->Chars
.SendCompleteHandler
)(
460 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
464 KeLowerIrql(OldIrql
);
469 MiniSendResourcesAvailable(
470 IN NDIS_HANDLE MiniportAdapterHandle
)
479 MiniTransferDataComplete(
480 IN NDIS_HANDLE MiniportAdapterHandle
,
481 IN PNDIS_PACKET Packet
,
482 IN NDIS_STATUS Status
,
483 IN UINT BytesTransferred
)
485 PADAPTER_BINDING AdapterBinding
;
488 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
490 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
492 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
493 (*AdapterBinding
->ProtocolBinding
->Chars
.TransferDataCompleteHandler
)(
494 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
498 KeLowerIrql(OldIrql
);
503 MiniAdapterHasAddress(
504 PLOGICAL_ADAPTER Adapter
,
507 * FUNCTION: Determines whether a packet has the same destination address as an adapter
509 * Adapter = Pointer to logical adapter object
510 * Packet = Pointer to NDIS packet
512 * TRUE if the destination address is that of the adapter, FALSE if not
518 PNDIS_BUFFER NdisBuffer
;
521 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
526 NDIS_DbgPrint(MIN_TRACE
, ("Adapter object was null\n"));
532 NDIS_DbgPrint(MIN_TRACE
, ("Packet was null\n"));
537 NdisQueryPacket(Packet
, NULL
, NULL
, &NdisBuffer
, NULL
);
541 NDIS_DbgPrint(MIN_TRACE
, ("Packet contains no buffers.\n"));
545 NdisQueryBuffer(NdisBuffer
, (PVOID
)&Start2
, &BufferLength
);
547 /* FIXME: Should handle fragmented packets */
549 switch (Adapter
->NdisMiniportBlock
.MediaType
)
551 case NdisMedium802_3
:
552 Length
= ETH_LENGTH_OF_ADDRESS
;
553 /* Destination address is the first field */
557 NDIS_DbgPrint(MIN_TRACE
, ("Adapter has unsupported media type (0x%X).\n", Adapter
->NdisMiniportBlock
.MediaType
));
561 if (BufferLength
< Length
)
563 NDIS_DbgPrint(MIN_TRACE
, ("Buffer is too small.\n"));
567 Start1
= (PUCHAR
)&Adapter
->Address
;
568 NDIS_DbgPrint(MAX_TRACE
, ("packet address: %x:%x:%x:%x:%x:%x adapter address: %x:%x:%x:%x:%x:%x\n",
569 *((char *)Start1
), *(((char *)Start1
)+1), *(((char *)Start1
)+2), *(((char *)Start1
)+3), *(((char *)Start1
)+4), *(((char *)Start1
)+5),
570 *((char *)Start2
), *(((char *)Start2
)+1), *(((char *)Start2
)+2), *(((char *)Start2
)+3), *(((char *)Start2
)+4), *(((char *)Start2
)+5))
573 return (RtlCompareMemory((PVOID
)Start1
, (PVOID
)Start2
, Length
) == Length
);
579 PNDIS_STRING AdapterName
)
581 * FUNCTION: Finds an adapter object by name
583 * AdapterName = Pointer to name of adapter
585 * Pointer to logical adapter object, or NULL if none was found.
586 * If found, the adapter is referenced for the caller. The caller
587 * is responsible for dereferencing after use
591 PLIST_ENTRY CurrentEntry
;
592 PLOGICAL_ADAPTER Adapter
= 0;
596 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
598 if(IsListEmpty(&AdapterListHead
))
600 NDIS_DbgPrint(MIN_TRACE
, ("No registered miniports for protocol to bind to\n"));
604 KeAcquireSpinLock(&AdapterListLock
, &OldIrql
);
606 CurrentEntry
= AdapterListHead
.Flink
;
608 while (CurrentEntry
!= &AdapterListHead
)
610 Adapter
= CONTAINING_RECORD(CurrentEntry
, LOGICAL_ADAPTER
, ListEntry
);
614 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Examining adapter 0x%lx\n", Adapter
));
615 NDIS_DbgPrint(DEBUG_MINIPORT
, ("AdapterName = %wZ\n", AdapterName
));
616 NDIS_DbgPrint(DEBUG_MINIPORT
, ("DeviceName = %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
618 if (RtlCompareUnicodeString(AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
, TRUE
) == 0)
624 CurrentEntry
= CurrentEntry
->Flink
;
627 KeReleaseSpinLock(&AdapterListLock
, OldIrql
);
631 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Leaving. Adapter found at 0x%x\n", Adapter
));
635 NDIS_DbgPrint(MIN_TRACE
, ("Leaving (adapter not found for %wZ).\n", AdapterName
));
643 MiniQueryInformation(
644 PLOGICAL_ADAPTER Adapter
,
650 * FUNCTION: Queries a logical adapter for properties
652 * Adapter = Pointer to the logical adapter object to query
653 * Oid = Specifies the Object ID to query for
654 * Size = Size of the passed buffer
655 * Buffer = Buffer for the output
656 * BytesWritten = Address of buffer to place number of bytes written
658 * Status of operation
661 NDIS_STATUS NdisStatus
;
662 PNDIS_REQUEST NdisRequest
;
664 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
666 NdisRequest
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_REQUEST
));
668 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
669 return NDIS_STATUS_RESOURCES
;
672 RtlZeroMemory(NdisRequest
, sizeof(NDIS_REQUEST
));
674 NdisRequest
->RequestType
= NdisRequestQueryInformation
;
675 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
= Oid
;
676 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
= Buffer
;
677 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
= Size
;
679 NdisStatus
= MiniDoRequest(Adapter
, NdisRequest
);
681 /* FIXME: Wait in pending case! */
683 ASSERT(NdisStatus
!= NDIS_STATUS_PENDING
);
685 *BytesWritten
= NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
;
687 ExFreePool(NdisRequest
);
693 MiniCheckForHang( PLOGICAL_ADAPTER Adapter
)
695 * FUNCTION: Checks to see if the miniport is hung
697 * Adapter = Pointer to the logical adapter object
699 * TRUE if the miniport is hung
700 * FALSE if the miniport is not hung
706 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
707 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)
708 Ret
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)(
709 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
);
710 KeLowerIrql(OldIrql
);
717 PLOGICAL_ADAPTER Adapter
,
718 PBOOLEAN AddressingReset
)
720 * FUNCTION: Resets the miniport
722 * Adapter = Pointer to the logical adapter object
723 * AddressingReset = Set to TRUE if we need to call MiniportSetInformation later
725 * Status of the operation
731 if (MiniIsBusy(Adapter
, NdisWorkItemResetRequested
)) {
732 MiniQueueWorkItem(Adapter
, NdisWorkItemResetRequested
, NULL
, FALSE
);
733 return NDIS_STATUS_PENDING
;
736 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
737 NdisMIndicateStatusComplete(Adapter
);
739 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
740 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
741 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
744 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
745 Adapter
->NdisMiniportBlock
.ResetStatus
= Status
;
746 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
748 KeLowerIrql(OldIrql
);
750 if (Status
!= NDIS_STATUS_PENDING
) {
751 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
752 NdisMIndicateStatusComplete(Adapter
);
761 PVOID DeferredContext
,
762 PVOID SystemArgument1
,
763 PVOID SystemArgument2
)
765 PLOGICAL_ADAPTER Adapter
= DeferredContext
;
766 BOOLEAN AddressingReset
= FALSE
;
769 if (MiniCheckForHang(Adapter
)) {
770 NDIS_DbgPrint(MIN_TRACE
, ("Miniport detected adapter hang\n"));
771 MiniReset(Adapter
, &AddressingReset
);
774 /* FIXME: We should call MiniportSetInformation if AddressingReset is TRUE */
781 PLOGICAL_ADAPTER Adapter
,
782 NDIS_WORK_ITEM_TYPE WorkItemType
,
783 PVOID WorkItemContext
,
786 * FUNCTION: Queues a work item for execution at a later time
788 * Adapter = Pointer to the logical adapter object to queue work item on
789 * WorkItemType = Type of work item to queue
790 * WorkItemContext = Pointer to context information for work item
792 * Status of operation
795 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
796 PIO_WORKITEM IoWorkItem
;
799 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
803 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
806 if (WorkItemType
== NdisWorkItemSend
)
808 NDIS_DbgPrint(MIN_TRACE
, ("Requeuing failed packet (%x).\n", WorkItemContext
));
809 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= WorkItemContext
;
813 //This should never happen
819 MiniportWorkItem
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_MINIPORT_WORK_ITEM
));
820 if (!MiniportWorkItem
)
822 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
823 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
827 MiniportWorkItem
->WorkItemType
= WorkItemType
;
828 MiniportWorkItem
->WorkItemContext
= WorkItemContext
;
830 /* safe due to adapter lock held */
831 MiniportWorkItem
->Link
.Next
= NULL
;
832 if (!Adapter
->WorkQueueHead
)
834 Adapter
->WorkQueueHead
= MiniportWorkItem
;
835 Adapter
->WorkQueueTail
= MiniportWorkItem
;
839 Adapter
->WorkQueueTail
->Link
.Next
= (PSINGLE_LIST_ENTRY
)MiniportWorkItem
;
840 Adapter
->WorkQueueTail
= MiniportWorkItem
;
844 IoWorkItem
= IoAllocateWorkItem(Adapter
->NdisMiniportBlock
.DeviceObject
);
846 IoQueueWorkItem(IoWorkItem
, MiniportWorker
, DelayedWorkQueue
, IoWorkItem
);
848 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
855 PLOGICAL_ADAPTER Adapter
,
856 NDIS_WORK_ITEM_TYPE
*WorkItemType
,
857 PVOID
*WorkItemContext
)
859 * FUNCTION: Dequeues a work item from the work queue of a logical adapter
861 * Adapter = Pointer to the logical adapter object to dequeue work item from
862 * AdapterBinding = Address of buffer for adapter binding for this request
863 * WorkItemType = Address of buffer for work item type
864 * WorkItemContext = Address of buffer for pointer to context information
866 * Adapter lock must be held when called
868 * Status of operation
871 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
874 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
876 MiniportWorkItem
= Adapter
->WorkQueueHead
;
878 if ((Packet
= Adapter
->NdisMiniportBlock
.FirstPendingPacket
))
880 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= NULL
;
882 *WorkItemType
= NdisWorkItemSend
;
883 *WorkItemContext
= Packet
;
885 return NDIS_STATUS_SUCCESS
;
887 else if (MiniportWorkItem
)
889 /* safe due to adapter lock held */
890 Adapter
->WorkQueueHead
= (PNDIS_MINIPORT_WORK_ITEM
)MiniportWorkItem
->Link
.Next
;
892 if (MiniportWorkItem
== Adapter
->WorkQueueTail
)
893 Adapter
->WorkQueueTail
= NULL
;
895 *WorkItemType
= MiniportWorkItem
->WorkItemType
;
896 *WorkItemContext
= MiniportWorkItem
->WorkItemContext
;
898 ExFreePool(MiniportWorkItem
);
900 return NDIS_STATUS_SUCCESS
;
904 NDIS_DbgPrint(MIN_TRACE
, ("No work item to dequeue\n"));
906 return NDIS_STATUS_FAILURE
;
913 PLOGICAL_ADAPTER Adapter
,
914 PNDIS_REQUEST NdisRequest
)
916 * FUNCTION: Sends a request to a miniport
918 * AdapterBinding = Pointer to binding used in the request
919 * NdisRequest = Pointer to NDIS request structure describing request
921 * Status of operation
926 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
928 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
930 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
931 Adapter
->NdisMiniportBlock
.PendingRequest
= NdisRequest
;
932 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
934 if (!Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CoRequestHandler
)
936 switch (NdisRequest
->RequestType
)
938 case NdisRequestQueryInformation
:
939 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.QueryInformationHandler
)(
940 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
941 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
,
942 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
,
943 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
,
944 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
,
945 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesNeeded
);
948 case NdisRequestSetInformation
:
949 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SetInformationHandler
)(
950 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
951 NdisRequest
->DATA
.SET_INFORMATION
.Oid
,
952 NdisRequest
->DATA
.SET_INFORMATION
.InformationBuffer
,
953 NdisRequest
->DATA
.SET_INFORMATION
.InformationBufferLength
,
954 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesRead
,
955 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesNeeded
);
959 NDIS_DbgPrint(MIN_TRACE
, ("Bad request type\n"));
960 Status
= NDIS_STATUS_FAILURE
;
965 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CoRequestHandler
)(
966 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
971 if (Status
!= NDIS_STATUS_PENDING
) {
972 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
973 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
974 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
977 KeLowerIrql(OldIrql
);
985 #undef NdisMSetInformationComplete
988 NdisMSetInformationComplete(
989 IN NDIS_HANDLE MiniportAdapterHandle
,
990 IN NDIS_STATUS Status
)
992 PLOGICAL_ADAPTER Adapter
=
993 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
996 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
997 if (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)
998 (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)(MiniportAdapterHandle
, Status
);
999 KeLowerIrql(OldIrql
);
1006 #undef NdisMQueryInformationComplete
1009 NdisMQueryInformationComplete(
1010 IN NDIS_HANDLE MiniportAdapterHandle
,
1011 IN NDIS_STATUS Status
)
1013 PLOGICAL_ADAPTER Adapter
=
1014 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
1017 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1018 if( Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)
1019 (Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)(MiniportAdapterHandle
, Status
);
1020 KeLowerIrql(OldIrql
);
1025 MiniportWorker(IN PDEVICE_OBJECT DeviceObject
, IN PVOID Context
)
1027 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
1028 KIRQL OldIrql
, RaiseOldIrql
;
1029 NDIS_STATUS NdisStatus
;
1030 PVOID WorkItemContext
;
1031 NDIS_WORK_ITEM_TYPE WorkItemType
;
1032 BOOLEAN AddressingReset
;
1034 IoFreeWorkItem((PIO_WORKITEM
)Context
);
1036 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1040 (Adapter
, &WorkItemType
, &WorkItemContext
);
1042 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1044 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1046 switch (WorkItemType
)
1048 case NdisWorkItemSend
:
1050 * called by ProSend when protocols want to send packets to the miniport
1053 if(Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)
1055 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1057 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1058 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1059 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1060 NdisStatus
= NDIS_STATUS_PENDING
;
1064 /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */
1065 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1067 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1068 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1069 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1071 KeLowerIrql(RaiseOldIrql
);
1073 NdisStatus
= NDIS_GET_PACKET_STATUS((PNDIS_PACKET
)WorkItemContext
);
1074 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1075 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1082 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1084 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1085 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1086 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1087 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1088 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1092 /* Send is called at DISPATCH_LEVEL for all serialized miniports */
1093 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1094 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1095 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1096 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1097 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1098 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1099 KeLowerIrql(RaiseOldIrql
);
1100 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1101 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1107 if( NdisStatus
!= NDIS_STATUS_PENDING
) {
1109 ( Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1113 case NdisWorkItemSendLoopback
:
1115 * called by ProSend when protocols want to send loopback packets
1117 /* XXX atm ProIndicatePacket sends a packet up via the loopback adapter only */
1118 NdisStatus
= ProIndicatePacket(Adapter
, (PNDIS_PACKET
)WorkItemContext
);
1120 if( NdisStatus
!= NDIS_STATUS_PENDING
)
1121 MiniSendComplete((NDIS_HANDLE
)Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1124 case NdisWorkItemReturnPackets
:
1127 case NdisWorkItemResetRequested
:
1128 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
1129 NdisMIndicateStatusComplete(Adapter
);
1131 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1132 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
1133 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1136 if (NdisStatus
== NDIS_STATUS_PENDING
)
1138 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1139 Adapter
->NdisMiniportBlock
.ResetStatus
= NDIS_STATUS_PENDING
;
1140 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1143 KeLowerIrql(OldIrql
);
1145 if (NdisStatus
!= NDIS_STATUS_PENDING
)
1146 MiniResetComplete(Adapter
, NdisStatus
, AddressingReset
);
1149 case NdisWorkItemResetInProgress
:
1152 case NdisWorkItemMiniportCallback
:
1155 case NdisWorkItemRequest
:
1156 NdisStatus
= MiniDoRequest(Adapter
, (PNDIS_REQUEST
)WorkItemContext
);
1158 if (NdisStatus
== NDIS_STATUS_PENDING
)
1161 switch (((PNDIS_REQUEST
)WorkItemContext
)->RequestType
)
1163 case NdisRequestQueryInformation
:
1164 NdisMQueryInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1167 case NdisRequestSetInformation
:
1168 NdisMSetInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1172 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS request type.\n"));
1178 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS work item type (%d).\n", WorkItemType
));
1189 IN NDIS_HANDLE MiniportHandle
,
1190 IN NDIS_STATUS GeneralStatus
,
1191 IN PVOID StatusBuffer
,
1192 IN UINT StatusBufferSize
)
1194 PLOGICAL_ADAPTER Adapter
= MiniportHandle
;
1195 PLIST_ENTRY CurrentEntry
;
1196 PADAPTER_BINDING AdapterBinding
;
1199 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1201 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1203 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1205 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1207 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusHandler
)(
1208 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
1213 CurrentEntry
= CurrentEntry
->Flink
;
1216 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1223 IN NDIS_HANDLE MiniportAdapterHandle
)
1225 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1226 PLIST_ENTRY CurrentEntry
;
1227 PADAPTER_BINDING AdapterBinding
;
1230 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1232 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1234 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1236 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1238 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusCompleteHandler
)(
1239 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
);
1241 CurrentEntry
= CurrentEntry
->Flink
;
1244 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1254 IN NDIS_HANDLE LogHandle
)
1256 PNDIS_LOG Log
= (PNDIS_LOG
)LogHandle
;
1257 PNDIS_MINIPORT_BLOCK Miniport
= Log
->Miniport
;
1260 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1262 KeAcquireSpinLock(&(Miniport
)->Lock
, &OldIrql
);
1263 Miniport
->Log
= NULL
;
1264 KeReleaseSpinLock(&(Miniport
)->Lock
, OldIrql
);
1275 IN NDIS_HANDLE MiniportAdapterHandle
,
1277 OUT PNDIS_HANDLE LogHandle
)
1279 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1283 NDIS_DbgPrint(MAX_TRACE
, ("called: MiniportAdapterHandle 0x%x, Size %ld\n", MiniportAdapterHandle
, Size
));
1285 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1287 if (Adapter
->NdisMiniportBlock
.Log
)
1290 return NDIS_STATUS_FAILURE
;
1293 Log
= ExAllocatePool(NonPagedPool
, Size
+ sizeof(NDIS_LOG
));
1297 return NDIS_STATUS_RESOURCES
;
1300 Adapter
->NdisMiniportBlock
.Log
= Log
;
1302 KeInitializeSpinLock(&Log
->LogLock
);
1304 Log
->Miniport
= &Adapter
->NdisMiniportBlock
;
1305 Log
->TotalSize
= Size
;
1306 Log
->CurrentSize
= 0;
1313 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1315 return NDIS_STATUS_SUCCESS
;
1323 NdisMDeregisterAdapterShutdownHandler(
1324 IN NDIS_HANDLE MiniportHandle
)
1326 * FUNCTION: de-registers a shutdown handler
1327 * ARGUMENTS: MiniportHandle: Handle passed into MiniportInitialize
1330 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1332 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1334 if(Adapter
->BugcheckContext
->ShutdownHandler
) {
1335 KeDeregisterBugCheckCallback(Adapter
->BugcheckContext
->CallbackRecord
);
1336 IoUnregisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1346 IN NDIS_HANDLE LogHandle
)
1348 PNDIS_LOG Log
= (PNDIS_LOG
) LogHandle
;
1351 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1354 KeAcquireSpinLock(&Log
->LogLock
, &OldIrql
);
1356 /* Set buffers size */
1357 Log
->CurrentSize
= 0;
1362 KeReleaseSpinLock(&Log
->LogLock
, OldIrql
);
1368 #undef NdisMIndicateStatus
1371 NdisMIndicateStatus(
1372 IN NDIS_HANDLE MiniportAdapterHandle
,
1373 IN NDIS_STATUS GeneralStatus
,
1374 IN PVOID StatusBuffer
,
1375 IN UINT StatusBufferSize
)
1377 MiniStatus(MiniportAdapterHandle
, GeneralStatus
, StatusBuffer
, StatusBufferSize
);
1383 #undef NdisMIndicateStatusComplete
1386 NdisMIndicateStatusComplete(
1387 IN NDIS_HANDLE MiniportAdapterHandle
)
1389 MiniStatusComplete(MiniportAdapterHandle
);
1398 NdisInitializeWrapper(
1399 OUT PNDIS_HANDLE NdisWrapperHandle
,
1400 IN PVOID SystemSpecific1
,
1401 IN PVOID SystemSpecific2
,
1402 IN PVOID SystemSpecific3
)
1404 * FUNCTION: Notifies the NDIS library that a new miniport is initializing
1406 * NdisWrapperHandle = Address of buffer to place NDIS wrapper handle
1407 * SystemSpecific1 = Pointer to the driver's driver object
1408 * SystemSpecific2 = Pointer to the driver's registry path
1409 * SystemSpecific3 = Always NULL
1411 * - SystemSpecific2 goes invalid so we copy it
1414 PNDIS_M_DRIVER_BLOCK Miniport
;
1415 PUNICODE_STRING RegistryPath
;
1416 WCHAR
*RegistryBuffer
;
1418 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1420 ASSERT(NdisWrapperHandle
);
1422 *NdisWrapperHandle
= NULL
;
1424 #if BREAK_ON_MINIPORT_INIT
1425 __asm__ ("int $3\n");
1428 Miniport
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DRIVER_BLOCK
));
1432 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1436 RtlZeroMemory(Miniport
, sizeof(NDIS_M_DRIVER_BLOCK
));
1438 KeInitializeSpinLock(&Miniport
->Lock
);
1440 Miniport
->DriverObject
= (PDRIVER_OBJECT
)SystemSpecific1
;
1442 /* set the miniport's driver registry path */
1443 RegistryPath
= ExAllocatePool(PagedPool
, sizeof(UNICODE_STRING
));
1446 ExFreePool(Miniport
);
1447 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1451 RegistryPath
->Length
= ((PUNICODE_STRING
)SystemSpecific2
)->Length
;
1452 RegistryPath
->MaximumLength
= RegistryPath
->Length
+ sizeof(WCHAR
); /* room for 0-term */
1454 RegistryBuffer
= ExAllocatePool(PagedPool
, RegistryPath
->MaximumLength
);
1457 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1458 ExFreePool(Miniport
);
1459 ExFreePool(RegistryPath
);
1463 RtlCopyMemory(RegistryBuffer
, ((PUNICODE_STRING
)SystemSpecific2
)->Buffer
, RegistryPath
->Length
);
1464 RegistryBuffer
[RegistryPath
->Length
/sizeof(WCHAR
)] = 0;
1466 RegistryPath
->Buffer
= RegistryBuffer
;
1467 Miniport
->RegistryPath
= RegistryPath
;
1469 InitializeListHead(&Miniport
->DeviceList
);
1471 /* Put miniport in global miniport list */
1472 ExInterlockedInsertTailList(&MiniportListHead
, &Miniport
->ListEntry
, &MiniportListLock
);
1474 *NdisWrapperHandle
= Miniport
;
1478 VOID NTAPI
NdisIBugcheckCallback(
1482 * FUNCTION: Internal callback for handling bugchecks - calls adapter's shutdown handler
1484 * Buffer: Pointer to a bugcheck callback context
1488 PMINIPORT_BUGCHECK_CONTEXT Context
= (PMINIPORT_BUGCHECK_CONTEXT
)Buffer
;
1489 ADAPTER_SHUTDOWN_HANDLER sh
= (ADAPTER_SHUTDOWN_HANDLER
)Context
->ShutdownHandler
;
1491 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1494 sh(Context
->DriverContext
);
1503 NdisMRegisterAdapterShutdownHandler(
1504 IN NDIS_HANDLE MiniportHandle
,
1505 IN PVOID ShutdownContext
,
1506 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
1508 * FUNCTION: Register a shutdown handler for an adapter
1510 * MiniportHandle: Handle originally passed into MiniportInitialize
1511 * ShutdownContext: Pre-initialized bugcheck context
1512 * ShutdownHandler: Function to call to handle the bugcheck
1514 * - I'm not sure about ShutdownContext
1517 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1518 PMINIPORT_BUGCHECK_CONTEXT BugcheckContext
;
1520 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1522 BugcheckContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_BUGCHECK_CONTEXT
));
1523 if(!BugcheckContext
)
1525 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1529 BugcheckContext
->ShutdownHandler
= ShutdownHandler
;
1530 BugcheckContext
->DriverContext
= ShutdownContext
;
1532 BugcheckContext
->CallbackRecord
= ExAllocatePool(NonPagedPool
, sizeof(KBUGCHECK_CALLBACK_RECORD
));
1533 if (!BugcheckContext
->CallbackRecord
) {
1534 ExFreePool(BugcheckContext
);
1538 Adapter
->BugcheckContext
= BugcheckContext
;
1540 KeInitializeCallbackRecord(BugcheckContext
->CallbackRecord
);
1542 KeRegisterBugCheckCallback(BugcheckContext
->CallbackRecord
, NdisIBugcheckCallback
,
1543 BugcheckContext
, sizeof(BugcheckContext
), (PUCHAR
)"Ndis Miniport");
1545 IoRegisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1551 PLOGICAL_ADAPTER Adapter
,
1552 NDIS_OID AddressOID
)
1554 * FUNCTION: Queries miniport for information
1556 * Adapter = Pointer to logical adapter
1557 * AddressOID = OID to use to query for current address
1559 * Status of operation
1563 NDIS_STATUS NdisStatus
;
1565 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1567 /* Get MAC options for adapter */
1568 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAC_OPTIONS
, sizeof(UINT
),
1569 &Adapter
->NdisMiniportBlock
.MacOptions
,
1572 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1574 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAC_OPTIONS failed. NdisStatus (0x%X).\n", NdisStatus
));
1578 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MacOptions (0x%X).\n", Adapter
->NdisMiniportBlock
.MacOptions
));
1580 /* Get current hardware address of adapter */
1581 NdisStatus
= MiniQueryInformation(Adapter
, AddressOID
, Adapter
->AddressLength
,
1582 &Adapter
->Address
, &BytesWritten
);
1584 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1586 NDIS_DbgPrint(MIN_TRACE
, ("Address OID (0x%X) failed. NdisStatus (0x%X).\n", AddressOID
, NdisStatus
));
1594 PUCHAR A
= (PUCHAR
)&Adapter
->Address
.Type
.Medium802_3
;
1596 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]));
1600 /* Get maximum lookahead buffer size of adapter */
1601 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_LOOKAHEAD
, sizeof(ULONG
),
1602 &Adapter
->NdisMiniportBlock
.MaximumLookahead
, &BytesWritten
);
1604 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1606 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1610 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MaxLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.MaximumLookahead
));
1612 /* Get current lookahead buffer size of adapter */
1613 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_CURRENT_LOOKAHEAD
, sizeof(ULONG
),
1614 &Adapter
->NdisMiniportBlock
.CurrentLookahead
, &BytesWritten
);
1616 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1618 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_CURRENT_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1622 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_SEND_PACKETS
, sizeof(ULONG
),
1623 &Adapter
->NdisMiniportBlock
.MaxSendPackets
, &BytesWritten
);
1625 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1627 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_SEND_PACKETS failed. NdisStatus (0x%X).\n", NdisStatus
));
1629 /* Set it to 1 if it fails because some drivers don't support this (?)*/
1630 Adapter
->NdisMiniportBlock
.MaxSendPackets
= 1;
1633 NDIS_DbgPrint(DEBUG_MINIPORT
, ("CurLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.CurrentLookahead
));
1635 return STATUS_SUCCESS
;
1641 NdisIForwardIrpAndWaitCompletionRoutine(
1646 PKEVENT Event
= Context
;
1648 if (Irp
->PendingReturned
)
1649 KeSetEvent(Event
, IO_NO_INCREMENT
, FALSE
);
1651 return STATUS_MORE_PROCESSING_REQUIRED
;
1657 NdisIForwardIrpAndWait(PLOGICAL_ADAPTER Adapter
, PIRP Irp
)
1662 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1663 IoCopyCurrentIrpStackLocationToNext(Irp
);
1664 IoSetCompletionRoutine(Irp
, NdisIForwardIrpAndWaitCompletionRoutine
, &Event
,
1666 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
1667 if (Status
== STATUS_PENDING
)
1669 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1670 Status
= Irp
->IoStatus
.Status
;
1678 NdisIPnPStartDevice(
1679 IN PDEVICE_OBJECT DeviceObject
,
1682 * FUNCTION: Handle the PnP start device event
1684 * DeviceObejct = Functional Device Object
1685 * Irp = IRP_MN_START_DEVICE I/O request packet
1687 * Status of operation
1690 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
1691 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1692 NDIS_WRAPPER_CONTEXT WrapperContext
;
1693 NDIS_STATUS NdisStatus
;
1694 NDIS_STATUS OpenErrorStatus
;
1696 UINT SelectedMediumIndex
= 0;
1697 NDIS_OID AddressOID
;
1698 BOOLEAN Success
= FALSE
;
1699 ULONG ResourceCount
;
1700 ULONG ResourceListSize
;
1701 UNICODE_STRING ParamName
;
1702 PNDIS_CONFIGURATION_PARAMETER ConfigParam
;
1703 NDIS_HANDLE ConfigHandle
;
1705 LARGE_INTEGER Timeout
;
1706 UINT MaxMulticastAddresses
;
1710 * Prepare wrapper context used by HW and configuration routines.
1713 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Start Device %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
1715 NDIS_DbgPrint(MAX_TRACE
, ("Inserting adapter 0x%x into adapter list\n", Adapter
));
1717 /* Put adapter in global adapter list */
1718 ExInterlockedInsertTailList(&AdapterListHead
, &Adapter
->ListEntry
, &AdapterListLock
);
1720 Status
= IoOpenDeviceRegistryKey(
1721 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
, PLUGPLAY_REGKEY_DRIVER
,
1722 KEY_ALL_ACCESS
, &WrapperContext
.RegistryHandle
);
1723 if (!NT_SUCCESS(Status
))
1725 NDIS_DbgPrint(MIN_TRACE
,("failed to open adapter-specific reg key\n"));
1726 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1730 NDIS_DbgPrint(MAX_TRACE
, ("opened device reg key\n"));
1732 WrapperContext
.DeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
1735 * Store the adapter resources used by HW routines such as
1736 * NdisMQueryAdapterResources.
1739 if (Stack
->Parameters
.StartDevice
.AllocatedResources
!= NULL
)
1741 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResources
->List
[0].
1742 PartialResourceList
.Count
;
1744 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1745 PartialDescriptors
[ResourceCount
]);
1747 Adapter
->NdisMiniportBlock
.AllocatedResources
=
1748 ExAllocatePool(PagedPool
, ResourceListSize
);
1749 if (Adapter
->NdisMiniportBlock
.AllocatedResources
== NULL
)
1751 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1752 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1753 return STATUS_INSUFFICIENT_RESOURCES
;
1756 Adapter
->NdisMiniportBlock
.Resources
=
1757 ExAllocatePool(PagedPool
, ResourceListSize
);
1758 if (!Adapter
->NdisMiniportBlock
.Resources
)
1760 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1761 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
1762 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
1763 return STATUS_INSUFFICIENT_RESOURCES
;
1766 RtlCopyMemory(Adapter
->NdisMiniportBlock
.Resources
,
1767 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1770 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResources
,
1771 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1775 if (Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
!= NULL
)
1777 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
->List
[0].
1778 PartialResourceList
.Count
;
1780 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1781 PartialDescriptors
[ResourceCount
]);
1783 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
=
1784 ExAllocatePool(PagedPool
, ResourceListSize
);
1785 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
== NULL
)
1787 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1788 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1789 return STATUS_INSUFFICIENT_RESOURCES
;
1792 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
,
1793 Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
,
1798 * Store the Bus Type, Bus Number and Slot information. It's used by
1799 * the hardware routines then.
1802 NdisOpenConfiguration(&NdisStatus
, &ConfigHandle
, (NDIS_HANDLE
)&WrapperContext
);
1804 Size
= sizeof(ULONG
);
1805 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1806 DevicePropertyLegacyBusType
, Size
,
1807 &Adapter
->NdisMiniportBlock
.BusType
, &Size
);
1808 if (!NT_SUCCESS(Status
) || (INTERFACE_TYPE
)Adapter
->NdisMiniportBlock
.BusType
== InterfaceTypeUndefined
)
1810 NdisInitUnicodeString(&ParamName
, L
"BusType");
1811 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1812 &ParamName
, NdisParameterInteger
);
1813 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1814 Adapter
->NdisMiniportBlock
.BusType
= ConfigParam
->ParameterData
.IntegerData
;
1816 Adapter
->NdisMiniportBlock
.BusType
= Isa
;
1819 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1820 DevicePropertyBusNumber
, Size
,
1821 &Adapter
->NdisMiniportBlock
.BusNumber
, &Size
);
1822 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.BusNumber
== 0xFFFFFFF0)
1824 NdisInitUnicodeString(&ParamName
, L
"BusNumber");
1825 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1826 &ParamName
, NdisParameterInteger
);
1827 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1828 Adapter
->NdisMiniportBlock
.BusNumber
= ConfigParam
->ParameterData
.IntegerData
;
1830 Adapter
->NdisMiniportBlock
.BusNumber
= 0;
1832 WrapperContext
.BusNumber
= Adapter
->NdisMiniportBlock
.BusNumber
;
1834 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1835 DevicePropertyAddress
, Size
,
1836 &Adapter
->NdisMiniportBlock
.SlotNumber
, &Size
);
1837 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.SlotNumber
== (NDIS_INTERFACE_TYPE
)-1)
1839 NdisInitUnicodeString(&ParamName
, L
"SlotNumber");
1840 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1841 &ParamName
, NdisParameterInteger
);
1842 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1843 Adapter
->NdisMiniportBlock
.SlotNumber
= ConfigParam
->ParameterData
.IntegerData
;
1845 Adapter
->NdisMiniportBlock
.SlotNumber
= 0;
1849 /* Convert slotnumber to PCI_SLOT_NUMBER */
1850 ULONG PciSlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
1851 PCI_SLOT_NUMBER SlotNumber
;
1853 SlotNumber
.u
.AsULONG
= 0;
1854 SlotNumber
.u
.bits
.DeviceNumber
= (PciSlotNumber
>> 16) & 0xFFFF;
1855 SlotNumber
.u
.bits
.FunctionNumber
= PciSlotNumber
& 0xFFFF;
1857 Adapter
->NdisMiniportBlock
.SlotNumber
= SlotNumber
.u
.AsULONG
;
1859 WrapperContext
.SlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
1861 NdisCloseConfiguration(ConfigHandle
);
1863 /* Set handlers (some NDIS macros require these) */
1864 Adapter
->NdisMiniportBlock
.EthRxCompleteHandler
= EthFilterDprIndicateReceiveComplete
;
1865 Adapter
->NdisMiniportBlock
.EthRxIndicateHandler
= EthFilterDprIndicateReceive
;
1866 Adapter
->NdisMiniportBlock
.SendCompleteHandler
= MiniSendComplete
;
1867 Adapter
->NdisMiniportBlock
.SendResourcesHandler
= MiniSendResourcesAvailable
;
1868 Adapter
->NdisMiniportBlock
.ResetCompleteHandler
= MiniResetComplete
;
1869 Adapter
->NdisMiniportBlock
.TDCompleteHandler
= MiniTransferDataComplete
;
1870 Adapter
->NdisMiniportBlock
.PacketIndicateHandler
= MiniIndicateReceivePacket
;
1871 Adapter
->NdisMiniportBlock
.StatusHandler
= MiniStatus
;
1872 Adapter
->NdisMiniportBlock
.StatusCompleteHandler
= MiniStatusComplete
;
1873 Adapter
->NdisMiniportBlock
.SendPacketsHandler
= ProSendPackets
;
1874 Adapter
->NdisMiniportBlock
.QueryCompleteHandler
= MiniRequestComplete
;
1875 Adapter
->NdisMiniportBlock
.SetCompleteHandler
= MiniRequestComplete
;
1878 * Call MiniportInitialize.
1881 NDIS_DbgPrint(MID_TRACE
, ("calling MiniportInitialize\n"));
1882 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.InitializeHandler
)(
1883 &OpenErrorStatus
, &SelectedMediumIndex
, &MediaArray
[0],
1884 MEDIA_ARRAY_SIZE
, Adapter
, (NDIS_HANDLE
)&WrapperContext
);
1886 ZwClose(WrapperContext
.RegistryHandle
);
1888 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1890 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() failed for an adapter.\n"));
1891 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1895 if (SelectedMediumIndex
>= MEDIA_ARRAY_SIZE
)
1897 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() selected a bad index\n"));
1898 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1899 return NDIS_STATUS_UNSUPPORTED_MEDIA
;
1902 Adapter
->NdisMiniportBlock
.MediaType
= MediaArray
[SelectedMediumIndex
];
1904 switch (Adapter
->NdisMiniportBlock
.MediaType
)
1906 case NdisMedium802_3
:
1907 Adapter
->MediumHeaderSize
= 14; /* XXX figure out what to do about LLC */
1908 AddressOID
= OID_802_3_CURRENT_ADDRESS
;
1909 Adapter
->AddressLength
= ETH_LENGTH_OF_ADDRESS
;
1910 NdisStatus
= DoQueries(Adapter
, AddressOID
);
1911 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1913 NdisStatus
= MiniQueryInformation(Adapter
, OID_802_3_MAXIMUM_LIST_SIZE
, sizeof(UINT
),
1914 &MaxMulticastAddresses
, &BytesWritten
);
1916 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1918 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1919 NDIS_DbgPrint(MIN_TRACE
, ("MiniQueryInformation failed (%x)\n", NdisStatus
));
1923 Success
= EthCreateFilter(MaxMulticastAddresses
,
1924 Adapter
->Address
.Type
.Medium802_3
,
1925 &Adapter
->NdisMiniportBlock
.EthDB
);
1927 ((PETHI_FILTER
)Adapter
->NdisMiniportBlock
.EthDB
)->Miniport
= (PNDIS_MINIPORT_BLOCK
)Adapter
;
1929 NdisStatus
= NDIS_STATUS_RESOURCES
;
1934 /* FIXME: Support other types of media */
1935 NDIS_DbgPrint(MIN_TRACE
, ("error: unsupported media\n"));
1937 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1938 return STATUS_UNSUCCESSFUL
;
1941 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1943 NDIS_DbgPrint(MIN_TRACE
, ("couldn't create filter (%x)\n", NdisStatus
));
1947 /* Check for a hang every two seconds if it wasn't set in MiniportInitialize */
1948 if (Adapter
->NdisMiniportBlock
.CheckForHangSeconds
== 0)
1949 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= 2;
1951 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
1952 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStarted
;
1954 IoSetDeviceInterfaceState(&Adapter
->NdisMiniportBlock
.SymbolicLinkName
, TRUE
);
1956 Timeout
.QuadPart
= Int32x32To64(Adapter
->NdisMiniportBlock
.CheckForHangSeconds
, -1000000);
1957 KeSetTimerEx(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
, Timeout
,
1958 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
* 1000,
1959 &Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
);
1961 /* Put adapter in adapter list for this miniport */
1962 ExInterlockedInsertTailList(&Adapter
->NdisMiniportBlock
.DriverHandle
->DeviceList
, &Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
1964 return STATUS_SUCCESS
;
1971 IN PDEVICE_OBJECT DeviceObject
,
1974 * FUNCTION: Handle the PnP stop device event
1976 * DeviceObejct = Functional Device Object
1977 * Irp = IRP_MN_STOP_DEVICE I/O request packet
1979 * Status of operation
1982 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1984 /* Remove adapter from adapter list for this miniport */
1985 ExInterlockedRemoveEntryList(&Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
1987 /* Remove adapter from global adapter list */
1988 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
1990 KeCancelTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
1992 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.HaltHandler
)(Adapter
);
1994 IoSetDeviceInterfaceState(&Adapter
->NdisMiniportBlock
.SymbolicLinkName
, FALSE
);
1996 if (Adapter
->NdisMiniportBlock
.AllocatedResources
)
1998 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
1999 Adapter
->NdisMiniportBlock
.AllocatedResources
= NULL
;
2001 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
)
2003 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
);
2004 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
= NULL
;
2007 if (Adapter
->NdisMiniportBlock
.Resources
)
2009 ExFreePool(Adapter
->NdisMiniportBlock
.Resources
);
2010 Adapter
->NdisMiniportBlock
.Resources
= NULL
;
2013 if (Adapter
->NdisMiniportBlock
.EthDB
)
2015 EthDeleteFilter(Adapter
->NdisMiniportBlock
.EthDB
);
2016 Adapter
->NdisMiniportBlock
.EthDB
= NULL
;
2019 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
2020 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStopped
;
2022 return STATUS_SUCCESS
;
2028 IN PDEVICE_OBJECT DeviceObject
,
2031 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
2032 PMINIPORT_BUGCHECK_CONTEXT Context
= Adapter
->BugcheckContext
;
2033 ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
= Context
->ShutdownHandler
;
2035 ASSERT(ShutdownHandler
);
2037 ShutdownHandler(Context
->DriverContext
);
2039 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2040 Irp
->IoStatus
.Information
= 0;
2042 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2044 return STATUS_SUCCESS
;
2049 NdisIDeviceIoControl(
2050 IN PDEVICE_OBJECT DeviceObject
,
2053 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2054 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2055 NDIS_STATUS Status
= STATUS_NOT_SUPPORTED
;
2057 Irp
->IoStatus
.Information
= 0;
2061 switch (Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
2063 case IOCTL_NDIS_QUERY_GLOBAL_STATS
:
2064 Status
= MiniQueryInformation(Adapter
,
2065 *(PNDIS_OID
)Irp
->AssociatedIrp
.SystemBuffer
,
2066 Stack
->Parameters
.DeviceIoControl
.OutputBufferLength
,
2067 MmGetSystemAddressForMdl(Irp
->MdlAddress
),
2068 &Irp
->IoStatus
.Information
);
2076 if (Status
!= NDIS_STATUS_PENDING
)
2078 Irp
->IoStatus
.Status
= Status
;
2079 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2082 IoMarkIrpPending(Irp
);
2091 IN PDEVICE_OBJECT DeviceObject
,
2094 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2095 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2098 switch (Stack
->MinorFunction
)
2100 case IRP_MN_START_DEVICE
:
2101 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2102 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2104 Status
= NdisIPnPStartDevice(DeviceObject
, Irp
);
2107 NDIS_DbgPrint(MIN_TRACE
, ("Lower driver failed device start\n"));
2108 Irp
->IoStatus
.Status
= Status
;
2109 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2112 case IRP_MN_STOP_DEVICE
:
2113 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2114 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2116 Status
= NdisIPnPStopDevice(DeviceObject
, Irp
);
2119 NDIS_DbgPrint(MIN_TRACE
, ("Lower driver failed device stop\n"));
2120 Irp
->IoStatus
.Status
= Status
;
2121 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2124 case IRP_MN_QUERY_REMOVE_DEVICE
:
2125 case IRP_MN_QUERY_STOP_DEVICE
:
2126 Status
= NdisIPnPQueryStopDevice(DeviceObject
, Irp
);
2127 Irp
->IoStatus
.Status
= Status
;
2128 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2131 case IRP_MN_CANCEL_REMOVE_DEVICE
:
2132 case IRP_MN_CANCEL_STOP_DEVICE
:
2133 Status
= NdisIPnPCancelStopDevice(DeviceObject
, Irp
);
2134 Irp
->IoStatus
.Status
= Status
;
2135 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2138 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
2139 Status
= NDIS_STATUS_SUCCESS
;
2140 Irp
->IoStatus
.Status
= Status
;
2141 Irp
->IoStatus
.Information
|= Adapter
->NdisMiniportBlock
.PnPFlags
;
2142 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2146 IoSkipCurrentIrpStackLocation(Irp
);
2147 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
2158 IN PDRIVER_OBJECT DriverObject
,
2159 IN PDEVICE_OBJECT PhysicalDeviceObject
)
2161 * FUNCTION: Create a device for an adapter found using PnP
2163 * DriverObject = Pointer to the miniport driver object
2164 * PhysicalDeviceObject = Pointer to the PDO for our adapter
2167 static const WCHAR ClassKeyName
[] = {'C','l','a','s','s','\\'};
2168 static const WCHAR LinkageKeyName
[] = {'\\','L','i','n','k','a','g','e',0};
2169 PNDIS_M_DRIVER_BLOCK Miniport
;
2170 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2171 WCHAR
*LinkageKeyBuffer
;
2172 ULONG DriverKeyLength
;
2173 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
2174 UNICODE_STRING ExportName
;
2175 PDEVICE_OBJECT DeviceObject
;
2176 PLOGICAL_ADAPTER Adapter
;
2180 * Gain the access to the miniport data structure first.
2183 MiniportPtr
= IoGetDriverObjectExtension(DriverObject
, (PVOID
)TAG('D','I','M','N'));
2184 if (MiniportPtr
== NULL
)
2186 NDIS_DbgPrint(MIN_TRACE
, ("Can't get driver object extension.\n"));
2187 return NDIS_STATUS_FAILURE
;
2189 Miniport
= *MiniportPtr
;
2192 * Get name of the Linkage registry key for our adapter. It's located under
2193 * the driver key for our driver and so we have basicly two ways to do it.
2194 * Either we can use IoOpenDriverRegistryKey or compose it using information
2195 * gathered by IoGetDeviceProperty. I choosed the second because
2196 * IoOpenDriverRegistryKey wasn't implemented at the time of writing.
2199 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2200 0, NULL
, &DriverKeyLength
);
2201 if (Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
&& Status
!= STATUS_SUCCESS
)
2203 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport driver key length.\n"));
2207 LinkageKeyBuffer
= ExAllocatePool(PagedPool
, DriverKeyLength
+
2208 sizeof(ClassKeyName
) + sizeof(LinkageKeyName
));
2209 if (LinkageKeyBuffer
== NULL
)
2211 NDIS_DbgPrint(MIN_TRACE
, ("Can't allocate memory for driver key name.\n"));
2212 return STATUS_INSUFFICIENT_RESOURCES
;
2215 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2216 DriverKeyLength
, LinkageKeyBuffer
+
2217 (sizeof(ClassKeyName
) / sizeof(WCHAR
)),
2219 if (!NT_SUCCESS(Status
))
2221 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport driver key.\n"));
2222 ExFreePool(LinkageKeyBuffer
);
2226 /* Compose the linkage key name. */
2227 RtlCopyMemory(LinkageKeyBuffer
, ClassKeyName
, sizeof(ClassKeyName
));
2228 RtlCopyMemory(LinkageKeyBuffer
+ ((sizeof(ClassKeyName
) + DriverKeyLength
) /
2229 sizeof(WCHAR
)) - 1, LinkageKeyName
, sizeof(LinkageKeyName
));
2231 NDIS_DbgPrint(DEBUG_MINIPORT
, ("LinkageKey: %S.\n", LinkageKeyBuffer
));
2234 * Now open the linkage key and read the "Export" and "RootDevice" values
2235 * which contains device name and root service respectively.
2238 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
2239 RtlInitUnicodeString(&ExportName
, NULL
);
2240 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
| RTL_QUERY_REGISTRY_DIRECT
;
2241 QueryTable
[0].Name
= L
"Export";
2242 QueryTable
[0].EntryContext
= &ExportName
;
2244 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
, LinkageKeyBuffer
,
2245 QueryTable
, NULL
, NULL
);
2246 ExFreePool(LinkageKeyBuffer
);
2247 if (!NT_SUCCESS(Status
))
2249 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport device name. (%x)\n", Status
));
2254 * Create the device object.
2257 NDIS_DbgPrint(MAX_TRACE
, ("creating device %wZ\n", &ExportName
));
2259 Status
= IoCreateDevice(Miniport
->DriverObject
, sizeof(LOGICAL_ADAPTER
),
2260 &ExportName
, FILE_DEVICE_PHYSICAL_NETCARD
,
2261 0, FALSE
, &DeviceObject
);
2262 if (!NT_SUCCESS(Status
))
2264 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device object.\n"));
2265 RtlFreeUnicodeString(&ExportName
);
2270 * Initialize the adapter structure.
2273 Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2274 KeInitializeSpinLock(&Adapter
->NdisMiniportBlock
.Lock
);
2275 InitializeListHead(&Adapter
->ProtocolListHead
);
2277 Status
= IoRegisterDeviceInterface(PhysicalDeviceObject
,
2278 &GUID_DEVINTERFACE_NET
,
2280 &Adapter
->NdisMiniportBlock
.SymbolicLinkName
);
2282 if (!NT_SUCCESS(Status
))
2284 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device interface.\n"));
2285 IoDeleteDevice(DeviceObject
);
2286 RtlFreeUnicodeString(&ExportName
);
2290 Adapter
->NdisMiniportBlock
.DriverHandle
= Miniport
;
2291 Adapter
->NdisMiniportBlock
.MiniportName
= ExportName
;
2292 Adapter
->NdisMiniportBlock
.DeviceObject
= DeviceObject
;
2293 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
= PhysicalDeviceObject
;
2294 Adapter
->NdisMiniportBlock
.NextDeviceObject
=
2295 IoAttachDeviceToDeviceStack(Adapter
->NdisMiniportBlock
.DeviceObject
,
2296 PhysicalDeviceObject
);
2298 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= 0;
2299 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceAdded
;
2301 KeInitializeTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
2302 KeInitializeDpc(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
, MiniportHangDpc
, Adapter
);
2304 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
2306 return STATUS_SUCCESS
;
2315 NdisMRegisterMiniport(
2316 IN NDIS_HANDLE NdisWrapperHandle
,
2317 IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics
,
2318 IN UINT CharacteristicsLength
)
2320 * FUNCTION: Registers a miniport's MiniportXxx entry points with the NDIS library
2322 * NdisWrapperHandle = Pointer to handle returned by NdisMInitializeWrapper
2323 * MiniportCharacteristics = Pointer to a buffer with miniport characteristics
2324 * CharacteristicsLength = Number of bytes in characteristics buffer
2326 * Status of operation
2330 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2331 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2334 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2336 switch (MiniportCharacteristics
->MajorNdisVersion
)
2339 MinSize
= sizeof(NDIS30_MINIPORT_CHARACTERISTICS
);
2343 MinSize
= sizeof(NDIS40_MINIPORT_CHARACTERISTICS
);
2347 MinSize
= sizeof(NDIS50_MINIPORT_CHARACTERISTICS
);
2351 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics version.\n"));
2352 return NDIS_STATUS_BAD_VERSION
;
2355 NDIS_DbgPrint(MIN_TRACE
, ("Initializing an NDIS %u.%u miniport\n",
2356 MiniportCharacteristics
->MajorNdisVersion
,
2357 MiniportCharacteristics
->MinorNdisVersion
));
2359 if (CharacteristicsLength
< MinSize
)
2361 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics length.\n"));
2362 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2365 /* Check if mandatory MiniportXxx functions are specified */
2366 if ((!MiniportCharacteristics
->HaltHandler
) ||
2367 (!MiniportCharacteristics
->InitializeHandler
)||
2368 (!MiniportCharacteristics
->ResetHandler
))
2370 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics.\n"));
2371 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2374 if (MiniportCharacteristics
->MajorNdisVersion
< 0x05)
2376 if ((!MiniportCharacteristics
->QueryInformationHandler
) ||
2377 (!MiniportCharacteristics
->SetInformationHandler
))
2379 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (Set/Query)\n"));
2380 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2385 if (((!MiniportCharacteristics
->QueryInformationHandler
) ||
2386 (!MiniportCharacteristics
->SetInformationHandler
)) &&
2387 (!MiniportCharacteristics
->CoRequestHandler
))
2389 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (Set/Query)\n"));
2390 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2394 if (MiniportCharacteristics
->MajorNdisVersion
== 0x03)
2396 if (!MiniportCharacteristics
->SendHandler
)
2398 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 3.0)\n"));
2399 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2402 else if (MiniportCharacteristics
->MajorNdisVersion
== 0x04)
2405 if ((!MiniportCharacteristics
->SendHandler
) &&
2406 (!MiniportCharacteristics
->SendPacketsHandler
))
2408 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 4.0)\n"));
2409 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2412 else if (MiniportCharacteristics
->MajorNdisVersion
== 0x05)
2414 /* TODO: Add more checks here */
2416 if ((!MiniportCharacteristics
->SendHandler
) &&
2417 (!MiniportCharacteristics
->SendPacketsHandler
) &&
2418 (!MiniportCharacteristics
->CoSendPacketsHandler
))
2420 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 5.0)\n"));
2421 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2425 /* TODO: verify NDIS5 and NDIS5.1 */
2427 RtlCopyMemory(&Miniport
->MiniportCharacteristics
, MiniportCharacteristics
, MinSize
);
2430 * NOTE: This is VERY unoptimal! Should we store the NDIS_M_DRIVER_BLOCK
2431 * structure in the driver extension or what?
2434 Status
= IoAllocateDriverObjectExtension(Miniport
->DriverObject
, (PVOID
)TAG('D','I','M','N'),
2435 sizeof(PNDIS_M_DRIVER_BLOCK
), (PVOID
*)&MiniportPtr
);
2436 if (!NT_SUCCESS(Status
))
2438 NDIS_DbgPrint(MIN_TRACE
, ("Can't allocate driver object extension.\n"));
2439 return NDIS_STATUS_RESOURCES
;
2442 *MiniportPtr
= Miniport
;
2444 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_PNP
] = NdisIDispatchPnp
;
2445 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] = NdisIShutdown
;
2446 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = NdisIDeviceIoControl
;
2447 Miniport
->DriverObject
->DriverExtension
->AddDevice
= NdisIAddDevice
;
2449 return NDIS_STATUS_SUCCESS
;
2456 #undef NdisMResetComplete
2460 IN NDIS_HANDLE MiniportAdapterHandle
,
2461 IN NDIS_STATUS Status
,
2462 IN BOOLEAN AddressingReset
)
2464 MiniResetComplete(MiniportAdapterHandle
, Status
, AddressingReset
);
2471 #undef NdisMSendComplete
2475 IN NDIS_HANDLE MiniportAdapterHandle
,
2476 IN PNDIS_PACKET Packet
,
2477 IN NDIS_STATUS Status
)
2479 * FUNCTION: Forwards a message to the initiating protocol saying
2480 * that a packet was handled
2482 * NdisAdapterHandle = Handle input to MiniportInitialize
2483 * Packet = Pointer to NDIS packet that was sent
2484 * Status = Status of send operation
2487 MiniSendComplete(MiniportAdapterHandle
, Packet
, Status
);
2494 #undef NdisMSendResourcesAvailable
2497 NdisMSendResourcesAvailable(
2498 IN NDIS_HANDLE MiniportAdapterHandle
)
2500 MiniSendResourcesAvailable(MiniportAdapterHandle
);
2507 #undef NdisMTransferDataComplete
2510 NdisMTransferDataComplete(
2511 IN NDIS_HANDLE MiniportAdapterHandle
,
2512 IN PNDIS_PACKET Packet
,
2513 IN NDIS_STATUS Status
,
2514 IN UINT BytesTransferred
)
2516 MiniTransferDataComplete(MiniportAdapterHandle
, Packet
, Status
, BytesTransferred
);
2523 #undef NdisMSetAttributes
2527 IN NDIS_HANDLE MiniportAdapterHandle
,
2528 IN NDIS_HANDLE MiniportAdapterContext
,
2529 IN BOOLEAN BusMaster
,
2530 IN NDIS_INTERFACE_TYPE AdapterType
)
2532 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2534 * MiniportAdapterHandle = Handle input to MiniportInitialize
2535 * MiniportAdapterContext = Pointer to context information
2536 * BusMaster = Specifies TRUE if the caller's NIC is a busmaster DMA device
2537 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2540 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2541 NdisMSetAttributesEx(MiniportAdapterHandle
, MiniportAdapterContext
, 0,
2542 BusMaster
? NDIS_ATTRIBUTE_BUS_MASTER
: 0,
2552 NdisMSetAttributesEx(
2553 IN NDIS_HANDLE MiniportAdapterHandle
,
2554 IN NDIS_HANDLE MiniportAdapterContext
,
2555 IN UINT CheckForHangTimeInSeconds OPTIONAL
,
2556 IN ULONG AttributeFlags
,
2557 IN NDIS_INTERFACE_TYPE AdapterType
)
2559 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2561 * MiniportAdapterHandle = Handle input to MiniportInitialize
2562 * MiniportAdapterContext = Pointer to context information
2563 * CheckForHangTimeInSeconds = Specifies interval in seconds at which
2564 * MiniportCheckForHang should be called
2565 * AttributeFlags = Bitmask that indicates specific attributes
2566 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2569 PLOGICAL_ADAPTER Adapter
= GET_LOGICAL_ADAPTER(MiniportAdapterHandle
);
2571 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2573 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
= MiniportAdapterContext
;
2574 Adapter
->NdisMiniportBlock
.Flags
= AttributeFlags
;
2575 Adapter
->NdisMiniportBlock
.AdapterType
= AdapterType
;
2576 if (CheckForHangTimeInSeconds
> 0)
2577 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= CheckForHangTimeInSeconds
;
2578 if (AttributeFlags
& NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER
)
2579 NDIS_DbgPrint(MAX_TRACE
, ("Intermediate drivers not supported yet.\n"));
2582 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.AdapterShutdownHandler
)
2584 NDIS_DbgPrint(MAX_TRACE
, ("Miniport set AdapterShutdownHandler in MiniportCharacteristics\n"));
2585 NdisMRegisterAdapterShutdownHandler(Adapter
,
2586 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
2587 Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.AdapterShutdownHandler
);
2598 IN ULONG MicrosecondsToSleep
)
2600 * FUNCTION: delay the thread's execution for MicrosecondsToSleep
2602 * MicrosecondsToSleep: duh...
2604 * - Because this is a blocking call, current IRQL must be < DISPATCH_LEVEL
2608 LARGE_INTEGER DueTime
;
2612 DueTime
.QuadPart
= (-1) * 10 * MicrosecondsToSleep
;
2614 KeInitializeTimer(&Timer
);
2615 KeSetTimer(&Timer
, DueTime
, 0);
2616 KeWaitForSingleObject(&Timer
, Executive
, KernelMode
, FALSE
, 0);
2625 NdisMSynchronizeWithInterrupt(
2626 IN PNDIS_MINIPORT_INTERRUPT Interrupt
,
2627 IN PVOID SynchronizeFunction
,
2628 IN PVOID SynchronizeContext
)
2630 return(KeSynchronizeExecution(Interrupt
->InterruptObject
,
2631 (PKSYNCHRONIZE_ROUTINE
)SynchronizeFunction
,
2632 SynchronizeContext
));
2642 IN NDIS_HANDLE LogHandle
,
2644 IN UINT LogBufferSize
)
2646 PUCHAR Buffer
= LogBuffer
;
2650 for (i
= 0; i
< LogBufferSize
; i
+= 16)
2652 DbgPrint("%08x |", i
);
2653 for (j
= 0; j
< 16; j
++)
2656 if (idx
< LogBufferSize
)
2657 DbgPrint(" %02x", Buffer
[idx
]);
2662 for (j
= 0; j
< 16; j
++)
2665 if (idx
== LogBufferSize
)
2667 if (Buffer
[idx
] >= ' ') /* FIXME: not portable! replace by if (isprint(Buffer[idx])) ? */
2668 DbgPrint("%c", Buffer
[idx
]);
2675 return NDIS_STATUS_FAILURE
;
2684 NdisTerminateWrapper(
2685 IN NDIS_HANDLE NdisWrapperHandle
,
2686 IN PVOID SystemSpecific
)
2688 * FUNCTION: Releases resources allocated by a call to NdisInitializeWrapper
2690 * NdisWrapperHandle = Handle returned by NdisInitializeWrapper (NDIS_M_DRIVER_BLOCK)
2691 * SystemSpecific = Always NULL
2694 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2696 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2698 ExFreePool(Miniport
->RegistryPath
->Buffer
);
2699 ExFreePool(Miniport
->RegistryPath
);
2700 ExInterlockedRemoveEntryList(&Miniport
->ListEntry
, &MiniportListLock
);
2701 ExFreePool(Miniport
);
2710 NdisMQueryAdapterInstanceName(
2711 OUT PNDIS_STRING AdapterInstanceName
,
2712 IN NDIS_HANDLE MiniportAdapterHandle
)
2720 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
2721 UNICODE_STRING AdapterName
;
2723 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2725 AdapterName
.Length
= 0;
2726 AdapterName
.MaximumLength
= Adapter
->NdisMiniportBlock
.MiniportName
.MaximumLength
;
2727 AdapterName
.Buffer
= ExAllocatePool(PagedPool
, AdapterName
.MaximumLength
);
2728 if (!AdapterName
.Buffer
) {
2729 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
2730 return NDIS_STATUS_RESOURCES
;
2733 RtlCopyUnicodeString(&AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
);
2735 *AdapterInstanceName
= AdapterName
;
2737 return NDIS_STATUS_SUCCESS
;
2745 NdisDeregisterAdapterShutdownHandler(
2746 IN NDIS_HANDLE NdisAdapterHandle
)
2754 NdisMDeregisterAdapterShutdownHandler(NdisAdapterHandle
);
2763 NdisRegisterAdapterShutdownHandler(
2764 IN NDIS_HANDLE NdisAdapterHandle
,
2765 IN PVOID ShutdownContext
,
2766 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
2774 NdisMRegisterAdapterShutdownHandler(NdisAdapterHandle
,
2784 NdisMGetDeviceProperty(
2785 IN NDIS_HANDLE MiniportAdapterHandle
,
2786 IN OUT PDEVICE_OBJECT
*PhysicalDeviceObject OPTIONAL
,
2787 IN OUT PDEVICE_OBJECT
*FunctionalDeviceObject OPTIONAL
,
2788 IN OUT PDEVICE_OBJECT
*NextDeviceObject OPTIONAL
,
2789 IN OUT PCM_RESOURCE_LIST
*AllocatedResources OPTIONAL
,
2790 IN OUT PCM_RESOURCE_LIST
*AllocatedResourcesTranslated OPTIONAL
)
2798 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
2800 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
2802 if (PhysicalDeviceObject
!= NULL
)
2803 *PhysicalDeviceObject
= Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
;
2805 if (FunctionalDeviceObject
!= NULL
)
2806 *FunctionalDeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
2808 if (NextDeviceObject
!= NULL
)
2809 *NextDeviceObject
= Adapter
->NdisMiniportBlock
.NextDeviceObject
;
2811 if (AllocatedResources
!= NULL
)
2812 *AllocatedResources
= Adapter
->NdisMiniportBlock
.AllocatedResources
;
2814 if (AllocatedResourcesTranslated
!= NULL
)
2815 *AllocatedResourcesTranslated
= Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
;
2823 NdisMRegisterUnloadHandler(
2824 IN NDIS_HANDLE NdisWrapperHandle
,
2825 IN PDRIVER_UNLOAD UnloadHandler
)
2833 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
2835 NDIS_DbgPrint(MAX_TRACE
, ("Miniport registered unload handler\n"));
2837 DriverBlock
->DriverObject
->DriverUnload
= UnloadHandler
;
2845 NdisMRegisterDevice(
2846 IN NDIS_HANDLE NdisWrapperHandle
,
2847 IN PNDIS_STRING DeviceName
,
2848 IN PNDIS_STRING SymbolicName
,
2849 IN PDRIVER_DISPATCH MajorFunctions
[],
2850 OUT PDEVICE_OBJECT
*pDeviceObject
,
2851 OUT NDIS_HANDLE
*NdisDeviceHandle
)
2859 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
2860 PNDIS_M_DEVICE_BLOCK DeviceBlock
;
2861 PDEVICE_OBJECT DeviceObject
;
2865 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
2867 Status
= IoCreateDevice(DriverBlock
->DriverObject
,
2868 0, /* This space is reserved for us. Should we use it? */
2870 FILE_DEVICE_NETWORK
,
2875 if (!NT_SUCCESS(Status
))
2877 NDIS_DbgPrint(MIN_TRACE
, ("IoCreateDevice failed (%x)\n", Status
));
2881 Status
= IoCreateSymbolicLink(SymbolicName
, DeviceName
);
2883 if (!NT_SUCCESS(Status
))
2885 NDIS_DbgPrint(MIN_TRACE
, ("IoCreateSymbolicLink failed (%x)\n", Status
));
2886 IoDeleteDevice(DeviceObject
);
2890 DeviceBlock
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DEVICE_BLOCK
));
2894 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
2895 IoDeleteDevice(DeviceObject
);
2896 IoDeleteSymbolicLink(SymbolicName
);
2897 return NDIS_STATUS_RESOURCES
;
2900 for (i
= 0; i
<= IRP_MJ_MAXIMUM_FUNCTION
; i
++)
2901 DriverBlock
->DriverObject
->MajorFunction
[i
] = MajorFunctions
[i
];
2903 DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_PNP
] = NdisIDispatchPnp
;
2905 DeviceBlock
->DeviceObject
= DeviceObject
;
2906 DeviceBlock
->SymbolicName
= SymbolicName
;
2908 *pDeviceObject
= DeviceObject
;
2909 *NdisDeviceHandle
= DeviceBlock
;
2911 return NDIS_STATUS_SUCCESS
;
2919 NdisMDeregisterDevice(
2920 IN NDIS_HANDLE NdisDeviceHandle
)
2928 PNDIS_M_DEVICE_BLOCK DeviceBlock
= NdisDeviceHandle
;
2930 IoDeleteDevice(DeviceBlock
->DeviceObject
);
2932 IoDeleteSymbolicLink(DeviceBlock
->SymbolicName
);
2934 ExFreePool(DeviceBlock
);
2936 return NDIS_STATUS_SUCCESS
;
2944 NdisQueryAdapterInstanceName(
2945 OUT PNDIS_STRING AdapterInstanceName
,
2946 IN NDIS_HANDLE NdisBindingHandle
)
2954 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
2955 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
2957 return NdisMQueryAdapterInstanceName(AdapterInstanceName
,
2966 NdisCompletePnPEvent(
2967 IN NDIS_STATUS Status
,
2968 IN NDIS_HANDLE NdisBindingHandle
,
2969 IN PNET_PNP_EVENT NetPnPEvent
)
2977 PIRP Irp
= (PIRP
)NetPnPEvent
->NdisReserved
[0];
2978 PLIST_ENTRY CurrentEntry
= (PLIST_ENTRY
)NetPnPEvent
->NdisReserved
[1];
2979 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
2980 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
2981 NDIS_STATUS NdisStatus
;
2983 if (Status
!= NDIS_STATUS_SUCCESS
)
2985 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
2986 ExFreePool(NetPnPEvent
);
2987 Irp
->IoStatus
.Status
= Status
;
2988 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2992 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
2994 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
2996 NdisStatus
= (*AdapterBinding
->ProtocolBinding
->Chars
.PnPEventHandler
)(
2997 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
3000 if (NdisStatus
== NDIS_STATUS_PENDING
)
3002 NetPnPEvent
->NdisReserved
[1] = (ULONG_PTR
)CurrentEntry
->Flink
;
3005 else if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
3007 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3008 ExFreePool(NetPnPEvent
);
3009 Irp
->IoStatus
.Status
= NdisStatus
;
3010 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3014 CurrentEntry
= CurrentEntry
->Flink
;
3017 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3018 ExFreePool(NetPnPEvent
);
3020 Irp
->IoStatus
.Status
= NDIS_STATUS_SUCCESS
;
3021 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3029 NdisCancelSendPackets(
3030 IN NDIS_HANDLE NdisBindingHandle
,
3033 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3034 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3036 NDIS_DbgPrint(MAX_TRACE
, ("Called for ID %x.\n", CancelId
));
3038 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CancelSendPacketsHandler
)
3040 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CancelSendPacketsHandler
)(
3041 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
3052 NdisIMGetBindingContext(
3053 IN NDIS_HANDLE NdisBindingHandle
)
3061 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3062 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3064 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3066 return Adapter
->NdisMiniportBlock
.DeviceContext
;
3075 NdisIMGetDeviceContext(
3076 IN NDIS_HANDLE MiniportAdapterHandle
)
3084 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
3086 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3088 return Adapter
->NdisMiniportBlock
.DeviceContext
;