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(DEBUG_MINIPORT
, ("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(MID_TRACE
, ("Adapter object was null\n"));
532 NDIS_DbgPrint(MID_TRACE
, ("Packet was null\n"));
537 NdisQueryPacket(Packet
, NULL
, NULL
, &NdisBuffer
, NULL
);
541 NDIS_DbgPrint(MID_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(MID_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(DEBUG_MINIPORT
, ("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(DEBUG_MINIPORT
, ("Leaving (adapter not found).\n"));
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 * If the specified buffer is too small, a new buffer is allocated,
659 * and the query is attempted again
661 * Status of operation
663 * Is there any way to use the buffer provided by the protocol?
666 NDIS_STATUS NdisStatus
;
667 PNDIS_REQUEST NdisRequest
;
669 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
671 NdisRequest
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_REQUEST
));
672 if (!NdisRequest
) return NDIS_STATUS_RESOURCES
;
674 RtlZeroMemory(NdisRequest
, sizeof(NDIS_REQUEST
));
676 NdisRequest
->RequestType
= NdisRequestQueryInformation
;
677 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
= Oid
;
678 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
= Buffer
;
679 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
= Size
;
681 NdisStatus
= MiniDoRequest(Adapter
, NdisRequest
);
683 /* FIXME: Wait in pending case! */
685 ASSERT(NdisStatus
!= NDIS_STATUS_PENDING
);
687 *BytesWritten
= NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
;
689 ExFreePool(NdisRequest
);
695 MiniCheckForHang( PLOGICAL_ADAPTER Adapter
)
697 * FUNCTION: Checks to see if the miniport is hung
699 * Adapter = Pointer to the logical adapter object
701 * TRUE if the miniport is hung
702 * FALSE if the miniport is not hung
708 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
709 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)
710 Ret
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)(
711 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
);
712 KeLowerIrql(OldIrql
);
719 PLOGICAL_ADAPTER Adapter
,
720 PBOOLEAN AddressingReset
)
722 * FUNCTION: Resets the miniport
724 * Adapter = Pointer to the logical adapter object
725 * AddressingReset = Set to TRUE if we need to call MiniportSetInformation later
727 * Status of the operation
733 if (MiniIsBusy(Adapter
, NdisWorkItemResetRequested
)) {
734 MiniQueueWorkItem(Adapter
, NdisWorkItemResetRequested
, NULL
, FALSE
);
735 return NDIS_STATUS_PENDING
;
738 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
739 NdisMIndicateStatusComplete(Adapter
);
741 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
742 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
743 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
746 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
747 Adapter
->NdisMiniportBlock
.ResetStatus
= Status
;
748 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
750 KeLowerIrql(OldIrql
);
752 if (Status
!= NDIS_STATUS_PENDING
) {
753 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
754 NdisMIndicateStatusComplete(Adapter
);
763 PVOID DeferredContext
,
764 PVOID SystemArgument1
,
765 PVOID SystemArgument2
)
767 PLOGICAL_ADAPTER Adapter
= DeferredContext
;
768 BOOLEAN AddressingReset
= FALSE
;
771 if (MiniCheckForHang(Adapter
)) {
772 NDIS_DbgPrint(MIN_TRACE
, ("Miniport detected adapter hang\n"));
773 MiniReset(Adapter
, &AddressingReset
);
776 /* FIXME: We should call MiniportSetInformation if AddressingReset is TRUE */
783 PLOGICAL_ADAPTER Adapter
,
784 NDIS_WORK_ITEM_TYPE WorkItemType
,
785 PVOID WorkItemContext
,
788 * FUNCTION: Queues a work item for execution at a later time
790 * Adapter = Pointer to the logical adapter object to queue work item on
791 * WorkItemType = Type of work item to queue
792 * WorkItemContext = Pointer to context information for work item
794 * Status of operation
797 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
798 PIO_WORKITEM IoWorkItem
;
801 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
805 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
808 if (WorkItemType
== NdisWorkItemSend
)
810 NDIS_DbgPrint(MIN_TRACE
, ("Requeuing failed packet (%x).\n", WorkItemContext
));
811 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= WorkItemContext
;
815 //This should never happen
821 MiniportWorkItem
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_MINIPORT_WORK_ITEM
));
822 if (!MiniportWorkItem
)
824 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
825 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
829 MiniportWorkItem
->WorkItemType
= WorkItemType
;
830 MiniportWorkItem
->WorkItemContext
= WorkItemContext
;
832 /* safe due to adapter lock held */
833 MiniportWorkItem
->Link
.Next
= NULL
;
834 if (!Adapter
->WorkQueueHead
)
836 Adapter
->WorkQueueHead
= MiniportWorkItem
;
837 Adapter
->WorkQueueTail
= MiniportWorkItem
;
841 Adapter
->WorkQueueTail
->Link
.Next
= (PSINGLE_LIST_ENTRY
)MiniportWorkItem
;
842 Adapter
->WorkQueueTail
= MiniportWorkItem
;
846 IoWorkItem
= IoAllocateWorkItem(Adapter
->NdisMiniportBlock
.DeviceObject
);
848 IoQueueWorkItem(IoWorkItem
, MiniportWorker
, DelayedWorkQueue
, IoWorkItem
);
850 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
857 PLOGICAL_ADAPTER Adapter
,
858 NDIS_WORK_ITEM_TYPE
*WorkItemType
,
859 PVOID
*WorkItemContext
)
861 * FUNCTION: Dequeues a work item from the work queue of a logical adapter
863 * Adapter = Pointer to the logical adapter object to dequeue work item from
864 * AdapterBinding = Address of buffer for adapter binding for this request
865 * WorkItemType = Address of buffer for work item type
866 * WorkItemContext = Address of buffer for pointer to context information
868 * Adapter lock must be held when called
870 * Status of operation
873 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
876 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
878 MiniportWorkItem
= Adapter
->WorkQueueHead
;
880 if ((Packet
= Adapter
->NdisMiniportBlock
.FirstPendingPacket
))
882 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= NULL
;
884 *WorkItemType
= NdisWorkItemSend
;
885 *WorkItemContext
= Packet
;
887 return NDIS_STATUS_SUCCESS
;
889 else if (MiniportWorkItem
)
891 /* safe due to adapter lock held */
892 Adapter
->WorkQueueHead
= (PNDIS_MINIPORT_WORK_ITEM
)MiniportWorkItem
->Link
.Next
;
894 if (MiniportWorkItem
== Adapter
->WorkQueueTail
)
895 Adapter
->WorkQueueTail
= NULL
;
897 *WorkItemType
= MiniportWorkItem
->WorkItemType
;
898 *WorkItemContext
= MiniportWorkItem
->WorkItemContext
;
900 ExFreePool(MiniportWorkItem
);
902 return NDIS_STATUS_SUCCESS
;
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 Status
= NDIS_STATUS_FAILURE
;
964 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CoRequestHandler
)(
965 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
970 if (Status
!= NDIS_STATUS_PENDING
) {
971 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
972 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
973 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
976 KeLowerIrql(OldIrql
);
984 #undef NdisMSetInformationComplete
987 NdisMSetInformationComplete(
988 IN NDIS_HANDLE MiniportAdapterHandle
,
989 IN NDIS_STATUS Status
)
991 PLOGICAL_ADAPTER Adapter
=
992 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
995 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
996 if (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)
997 (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)(MiniportAdapterHandle
, Status
);
998 KeLowerIrql(OldIrql
);
1005 #undef NdisMQueryInformationComplete
1008 NdisMQueryInformationComplete(
1009 IN NDIS_HANDLE MiniportAdapterHandle
,
1010 IN NDIS_STATUS Status
)
1012 PLOGICAL_ADAPTER Adapter
=
1013 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
1016 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1017 if( Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)
1018 (Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)(MiniportAdapterHandle
, Status
);
1019 KeLowerIrql(OldIrql
);
1024 MiniportWorker(IN PDEVICE_OBJECT DeviceObject
, IN PVOID Context
)
1026 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
1027 KIRQL OldIrql
, RaiseOldIrql
;
1028 NDIS_STATUS NdisStatus
;
1029 PVOID WorkItemContext
;
1030 NDIS_WORK_ITEM_TYPE WorkItemType
;
1031 BOOLEAN AddressingReset
;
1033 IoFreeWorkItem((PIO_WORKITEM
)Context
);
1035 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1039 (Adapter
, &WorkItemType
, &WorkItemContext
);
1041 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1043 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1045 switch (WorkItemType
)
1047 case NdisWorkItemSend
:
1049 * called by ProSend when protocols want to send packets to the miniport
1052 if(Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)
1054 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1056 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1057 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1058 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1059 NdisStatus
= NDIS_STATUS_PENDING
;
1063 /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */
1064 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1066 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1067 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1068 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1070 KeLowerIrql(RaiseOldIrql
);
1072 NdisStatus
= NDIS_GET_PACKET_STATUS((PNDIS_PACKET
)WorkItemContext
);
1073 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1074 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1081 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1083 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1084 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1085 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1086 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1087 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1091 /* Send is called at DISPATCH_LEVEL for all serialized miniports */
1092 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1093 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1094 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1095 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1096 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1097 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1098 KeLowerIrql(RaiseOldIrql
);
1099 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1100 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1106 if( NdisStatus
!= NDIS_STATUS_PENDING
) {
1108 ( Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1112 case NdisWorkItemSendLoopback
:
1114 * called by ProSend when protocols want to send loopback packets
1116 /* XXX atm ProIndicatePacket sends a packet up via the loopback adapter only */
1117 NdisStatus
= ProIndicatePacket(Adapter
, (PNDIS_PACKET
)WorkItemContext
);
1119 if( NdisStatus
!= NDIS_STATUS_PENDING
)
1120 MiniSendComplete((NDIS_HANDLE
)Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1123 case NdisWorkItemReturnPackets
:
1126 case NdisWorkItemResetRequested
:
1127 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
1128 NdisMIndicateStatusComplete(Adapter
);
1130 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1131 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
1132 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1135 if (NdisStatus
== NDIS_STATUS_PENDING
)
1137 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1138 Adapter
->NdisMiniportBlock
.ResetStatus
= NDIS_STATUS_PENDING
;
1139 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1142 KeLowerIrql(OldIrql
);
1144 if (NdisStatus
!= NDIS_STATUS_PENDING
)
1145 MiniResetComplete(Adapter
, NdisStatus
, AddressingReset
);
1148 case NdisWorkItemResetInProgress
:
1151 case NdisWorkItemMiniportCallback
:
1154 case NdisWorkItemRequest
:
1155 NdisStatus
= MiniDoRequest(Adapter
, (PNDIS_REQUEST
)WorkItemContext
);
1157 if (NdisStatus
== NDIS_STATUS_PENDING
)
1160 switch (((PNDIS_REQUEST
)WorkItemContext
)->RequestType
)
1162 case NdisRequestQueryInformation
:
1163 NdisMQueryInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1166 case NdisRequestSetInformation
:
1167 NdisMSetInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1171 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS request type.\n"));
1177 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS work item type (%d).\n", WorkItemType
));
1188 IN NDIS_HANDLE MiniportHandle
,
1189 IN NDIS_STATUS GeneralStatus
,
1190 IN PVOID StatusBuffer
,
1191 IN UINT StatusBufferSize
)
1193 PLOGICAL_ADAPTER Adapter
= MiniportHandle
;
1194 PLIST_ENTRY CurrentEntry
;
1195 PADAPTER_BINDING AdapterBinding
;
1198 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1200 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1202 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1204 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1206 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusHandler
)(
1207 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
1212 CurrentEntry
= CurrentEntry
->Flink
;
1215 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1222 IN NDIS_HANDLE MiniportAdapterHandle
)
1224 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1225 PLIST_ENTRY CurrentEntry
;
1226 PADAPTER_BINDING AdapterBinding
;
1229 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1231 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1233 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1235 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1237 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusCompleteHandler
)(
1238 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
);
1240 CurrentEntry
= CurrentEntry
->Flink
;
1243 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1253 IN NDIS_HANDLE LogHandle
)
1255 PNDIS_LOG Log
= (PNDIS_LOG
)LogHandle
;
1256 PNDIS_MINIPORT_BLOCK Miniport
= Log
->Miniport
;
1259 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1261 KeAcquireSpinLock(&(Miniport
)->Lock
, &OldIrql
);
1262 Miniport
->Log
= NULL
;
1263 KeReleaseSpinLock(&(Miniport
)->Lock
, OldIrql
);
1274 IN NDIS_HANDLE MiniportAdapterHandle
,
1276 OUT PNDIS_HANDLE LogHandle
)
1278 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1282 NDIS_DbgPrint(MAX_TRACE
, ("called: MiniportAdapterHandle 0x%x, Size %ld\n", MiniportAdapterHandle
, Size
));
1284 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1286 if (Adapter
->NdisMiniportBlock
.Log
)
1289 return NDIS_STATUS_FAILURE
;
1292 Log
= ExAllocatePool(NonPagedPool
, Size
+ sizeof(NDIS_LOG
));
1296 return NDIS_STATUS_RESOURCES
;
1299 Adapter
->NdisMiniportBlock
.Log
= Log
;
1301 KeInitializeSpinLock(&Log
->LogLock
);
1303 Log
->Miniport
= &Adapter
->NdisMiniportBlock
;
1304 Log
->TotalSize
= Size
;
1305 Log
->CurrentSize
= 0;
1312 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1314 return NDIS_STATUS_SUCCESS
;
1322 NdisMDeregisterAdapterShutdownHandler(
1323 IN NDIS_HANDLE MiniportHandle
)
1325 * FUNCTION: de-registers a shutdown handler
1326 * ARGUMENTS: MiniportHandle: Handle passed into MiniportInitialize
1329 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1331 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1333 if(Adapter
->BugcheckContext
->ShutdownHandler
) {
1334 KeDeregisterBugCheckCallback(Adapter
->BugcheckContext
->CallbackRecord
);
1335 IoUnregisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1345 IN NDIS_HANDLE LogHandle
)
1347 PNDIS_LOG Log
= (PNDIS_LOG
) LogHandle
;
1350 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1353 KeAcquireSpinLock(&Log
->LogLock
, &OldIrql
);
1355 /* Set buffers size */
1356 Log
->CurrentSize
= 0;
1361 KeReleaseSpinLock(&Log
->LogLock
, OldIrql
);
1367 #undef NdisMIndicateStatus
1370 NdisMIndicateStatus(
1371 IN NDIS_HANDLE MiniportAdapterHandle
,
1372 IN NDIS_STATUS GeneralStatus
,
1373 IN PVOID StatusBuffer
,
1374 IN UINT StatusBufferSize
)
1376 MiniStatus(MiniportAdapterHandle
, GeneralStatus
, StatusBuffer
, StatusBufferSize
);
1382 #undef NdisMIndicateStatusComplete
1385 NdisMIndicateStatusComplete(
1386 IN NDIS_HANDLE MiniportAdapterHandle
)
1388 MiniStatusComplete(MiniportAdapterHandle
);
1397 NdisInitializeWrapper(
1398 OUT PNDIS_HANDLE NdisWrapperHandle
,
1399 IN PVOID SystemSpecific1
,
1400 IN PVOID SystemSpecific2
,
1401 IN PVOID SystemSpecific3
)
1403 * FUNCTION: Notifies the NDIS library that a new miniport is initializing
1405 * NdisWrapperHandle = Address of buffer to place NDIS wrapper handle
1406 * SystemSpecific1 = Pointer to the driver's driver object
1407 * SystemSpecific2 = Pointer to the driver's registry path
1408 * SystemSpecific3 = Always NULL
1410 * - SystemSpecific2 goes invalid so we copy it
1413 PNDIS_M_DRIVER_BLOCK Miniport
;
1414 PUNICODE_STRING RegistryPath
;
1415 WCHAR
*RegistryBuffer
;
1417 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1419 ASSERT(NdisWrapperHandle
);
1421 *NdisWrapperHandle
= NULL
;
1423 #if BREAK_ON_MINIPORT_INIT
1424 __asm__ ("int $3\n");
1427 Miniport
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DRIVER_BLOCK
));
1431 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1435 RtlZeroMemory(Miniport
, sizeof(NDIS_M_DRIVER_BLOCK
));
1437 KeInitializeSpinLock(&Miniport
->Lock
);
1439 Miniport
->DriverObject
= (PDRIVER_OBJECT
)SystemSpecific1
;
1441 /* set the miniport's driver registry path */
1442 RegistryPath
= ExAllocatePool(PagedPool
, sizeof(UNICODE_STRING
));
1445 ExFreePool(Miniport
);
1446 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1450 RegistryPath
->Length
= ((PUNICODE_STRING
)SystemSpecific2
)->Length
;
1451 RegistryPath
->MaximumLength
= RegistryPath
->Length
+ sizeof(WCHAR
); /* room for 0-term */
1453 RegistryBuffer
= ExAllocatePool(PagedPool
, RegistryPath
->MaximumLength
);
1456 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1457 ExFreePool(Miniport
);
1458 ExFreePool(RegistryPath
);
1462 RtlCopyMemory(RegistryBuffer
, ((PUNICODE_STRING
)SystemSpecific2
)->Buffer
, RegistryPath
->Length
);
1463 RegistryBuffer
[RegistryPath
->Length
/sizeof(WCHAR
)] = 0;
1465 RegistryPath
->Buffer
= RegistryBuffer
;
1466 Miniport
->RegistryPath
= RegistryPath
;
1468 InitializeListHead(&Miniport
->DeviceList
);
1470 /* Put miniport in global miniport list */
1471 ExInterlockedInsertTailList(&MiniportListHead
, &Miniport
->ListEntry
, &MiniportListLock
);
1473 *NdisWrapperHandle
= Miniport
;
1477 VOID NTAPI
NdisIBugcheckCallback(
1481 * FUNCTION: Internal callback for handling bugchecks - calls adapter's shutdown handler
1483 * Buffer: Pointer to a bugcheck callback context
1487 PMINIPORT_BUGCHECK_CONTEXT Context
= (PMINIPORT_BUGCHECK_CONTEXT
)Buffer
;
1488 ADAPTER_SHUTDOWN_HANDLER sh
= (ADAPTER_SHUTDOWN_HANDLER
)Context
->ShutdownHandler
;
1490 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1493 sh(Context
->DriverContext
);
1502 NdisMRegisterAdapterShutdownHandler(
1503 IN NDIS_HANDLE MiniportHandle
,
1504 IN PVOID ShutdownContext
,
1505 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
1507 * FUNCTION: Register a shutdown handler for an adapter
1509 * MiniportHandle: Handle originally passed into MiniportInitialize
1510 * ShutdownContext: Pre-initialized bugcheck context
1511 * ShutdownHandler: Function to call to handle the bugcheck
1513 * - I'm not sure about ShutdownContext
1516 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1517 PMINIPORT_BUGCHECK_CONTEXT BugcheckContext
;
1519 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1521 BugcheckContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_BUGCHECK_CONTEXT
));
1522 if(!BugcheckContext
)
1524 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1528 BugcheckContext
->ShutdownHandler
= ShutdownHandler
;
1529 BugcheckContext
->DriverContext
= ShutdownContext
;
1531 BugcheckContext
->CallbackRecord
= ExAllocatePool(NonPagedPool
, sizeof(KBUGCHECK_CALLBACK_RECORD
));
1532 if (!BugcheckContext
->CallbackRecord
) {
1533 ExFreePool(BugcheckContext
);
1537 Adapter
->BugcheckContext
= BugcheckContext
;
1539 KeInitializeCallbackRecord(BugcheckContext
->CallbackRecord
);
1541 KeRegisterBugCheckCallback(BugcheckContext
->CallbackRecord
, NdisIBugcheckCallback
,
1542 BugcheckContext
, sizeof(BugcheckContext
), (PUCHAR
)"Ndis Miniport");
1544 IoRegisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1550 PLOGICAL_ADAPTER Adapter
,
1551 NDIS_OID AddressOID
)
1553 * FUNCTION: Queries miniport for information
1555 * Adapter = Pointer to logical adapter
1556 * AddressOID = OID to use to query for current address
1558 * Status of operation
1562 NDIS_STATUS NdisStatus
;
1564 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1566 /* Get MAC options for adapter */
1567 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAC_OPTIONS
, sizeof(UINT
),
1568 &Adapter
->NdisMiniportBlock
.MacOptions
,
1571 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1573 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAC_OPTIONS failed. NdisStatus (0x%X).\n", NdisStatus
));
1577 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MacOptions (0x%X).\n", Adapter
->NdisMiniportBlock
.MacOptions
));
1579 /* Get current hardware address of adapter */
1580 NdisStatus
= MiniQueryInformation(Adapter
, AddressOID
, Adapter
->AddressLength
,
1581 &Adapter
->Address
, &BytesWritten
);
1583 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1585 NDIS_DbgPrint(MIN_TRACE
, ("Address OID (0x%X) failed. NdisStatus (0x%X).\n", AddressOID
, NdisStatus
));
1593 PUCHAR A
= (PUCHAR
)&Adapter
->Address
.Type
.Medium802_3
;
1595 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]));
1599 /* Get maximum lookahead buffer size of adapter */
1600 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_LOOKAHEAD
, sizeof(ULONG
),
1601 &Adapter
->NdisMiniportBlock
.MaximumLookahead
, &BytesWritten
);
1603 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1605 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1609 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MaxLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.MaximumLookahead
));
1611 /* Get current lookahead buffer size of adapter */
1612 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_CURRENT_LOOKAHEAD
, sizeof(ULONG
),
1613 &Adapter
->NdisMiniportBlock
.CurrentLookahead
, &BytesWritten
);
1615 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1617 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_CURRENT_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1621 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_SEND_PACKETS
, sizeof(ULONG
),
1622 &Adapter
->NdisMiniportBlock
.MaxSendPackets
, &BytesWritten
);
1624 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1626 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_SEND_PACKETS failed. NdisStatus (0x%X).\n", NdisStatus
));
1628 /* Set it to 1 if it fails because some drivers don't support this (?)*/
1629 Adapter
->NdisMiniportBlock
.MaxSendPackets
= 1;
1632 NDIS_DbgPrint(DEBUG_MINIPORT
, ("CurLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.CurrentLookahead
));
1634 return STATUS_SUCCESS
;
1640 NdisIForwardIrpAndWaitCompletionRoutine(
1645 PKEVENT Event
= Context
;
1647 if (Irp
->PendingReturned
)
1648 KeSetEvent(Event
, IO_NO_INCREMENT
, FALSE
);
1650 return STATUS_MORE_PROCESSING_REQUIRED
;
1656 NdisIForwardIrpAndWait(PLOGICAL_ADAPTER Adapter
, PIRP Irp
)
1661 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1662 IoCopyCurrentIrpStackLocationToNext(Irp
);
1663 IoSetCompletionRoutine(Irp
, NdisIForwardIrpAndWaitCompletionRoutine
, &Event
,
1665 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
1666 if (Status
== STATUS_PENDING
)
1668 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1669 Status
= Irp
->IoStatus
.Status
;
1677 NdisIPnPStartDevice(
1678 IN PDEVICE_OBJECT DeviceObject
,
1681 * FUNCTION: Handle the PnP start device event
1683 * DeviceObejct = Functional Device Object
1684 * Irp = IRP_MN_START_DEVICE I/O request packet
1686 * Status of operation
1689 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
1690 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1691 NDIS_WRAPPER_CONTEXT WrapperContext
;
1692 NDIS_STATUS NdisStatus
;
1693 NDIS_STATUS OpenErrorStatus
;
1695 UINT SelectedMediumIndex
= 0;
1696 NDIS_OID AddressOID
;
1697 BOOLEAN Success
= FALSE
;
1698 ULONG ResourceCount
;
1699 ULONG ResourceListSize
;
1700 UNICODE_STRING ParamName
;
1701 PNDIS_CONFIGURATION_PARAMETER ConfigParam
;
1702 NDIS_HANDLE ConfigHandle
;
1704 LARGE_INTEGER Timeout
;
1705 UINT MaxMulticastAddresses
;
1709 * Prepare wrapper context used by HW and configuration routines.
1712 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Start Device %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
1714 NDIS_DbgPrint(MAX_TRACE
, ("Inserting adapter 0x%x into adapter list\n", Adapter
));
1716 /* Put adapter in global adapter list */
1717 ExInterlockedInsertTailList(&AdapterListHead
, &Adapter
->ListEntry
, &AdapterListLock
);
1719 Status
= IoOpenDeviceRegistryKey(
1720 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
, PLUGPLAY_REGKEY_DRIVER
,
1721 KEY_ALL_ACCESS
, &WrapperContext
.RegistryHandle
);
1722 if (!NT_SUCCESS(Status
))
1724 NDIS_DbgPrint(MIN_TRACE
,("failed to open adapter-specific reg key\n"));
1725 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1729 NDIS_DbgPrint(MAX_TRACE
, ("opened device reg key\n"));
1731 WrapperContext
.DeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
1734 * Store the adapter resources used by HW routines such as
1735 * NdisMQueryAdapterResources.
1738 if (Stack
->Parameters
.StartDevice
.AllocatedResources
!= NULL
)
1740 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResources
->List
[0].
1741 PartialResourceList
.Count
;
1743 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1744 PartialDescriptors
[ResourceCount
]);
1746 Adapter
->NdisMiniportBlock
.AllocatedResources
=
1747 ExAllocatePool(PagedPool
, ResourceListSize
);
1748 if (Adapter
->NdisMiniportBlock
.AllocatedResources
== NULL
)
1750 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1751 return STATUS_INSUFFICIENT_RESOURCES
;
1754 Adapter
->NdisMiniportBlock
.Resources
=
1755 ExAllocatePool(PagedPool
, ResourceListSize
);
1756 if (!Adapter
->NdisMiniportBlock
.Resources
)
1758 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
1759 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
1760 return STATUS_INSUFFICIENT_RESOURCES
;
1763 RtlCopyMemory(Adapter
->NdisMiniportBlock
.Resources
,
1764 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1767 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResources
,
1768 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1772 if (Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
!= NULL
)
1774 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
->List
[0].
1775 PartialResourceList
.Count
;
1777 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1778 PartialDescriptors
[ResourceCount
]);
1780 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
=
1781 ExAllocatePool(PagedPool
, ResourceListSize
);
1782 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
== NULL
)
1784 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1785 return STATUS_INSUFFICIENT_RESOURCES
;
1788 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
,
1789 Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
,
1794 * Store the Bus Type, Bus Number and Slot information. It's used by
1795 * the hardware routines then.
1798 NdisOpenConfiguration(&NdisStatus
, &ConfigHandle
, (NDIS_HANDLE
)&WrapperContext
);
1800 Size
= sizeof(ULONG
);
1801 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1802 DevicePropertyLegacyBusType
, Size
,
1803 &Adapter
->NdisMiniportBlock
.BusType
, &Size
);
1804 if (!NT_SUCCESS(Status
) || (INTERFACE_TYPE
)Adapter
->NdisMiniportBlock
.BusType
== InterfaceTypeUndefined
)
1806 NdisInitUnicodeString(&ParamName
, L
"BusType");
1807 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1808 &ParamName
, NdisParameterInteger
);
1809 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1810 Adapter
->NdisMiniportBlock
.BusType
= ConfigParam
->ParameterData
.IntegerData
;
1812 Adapter
->NdisMiniportBlock
.BusType
= Isa
;
1815 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1816 DevicePropertyBusNumber
, Size
,
1817 &Adapter
->NdisMiniportBlock
.BusNumber
, &Size
);
1818 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.BusNumber
== 0xFFFFFFF0)
1820 NdisInitUnicodeString(&ParamName
, L
"BusNumber");
1821 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1822 &ParamName
, NdisParameterInteger
);
1823 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1824 Adapter
->NdisMiniportBlock
.BusNumber
= ConfigParam
->ParameterData
.IntegerData
;
1826 Adapter
->NdisMiniportBlock
.BusNumber
= 0;
1828 WrapperContext
.BusNumber
= Adapter
->NdisMiniportBlock
.BusNumber
;
1830 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1831 DevicePropertyAddress
, Size
,
1832 &Adapter
->NdisMiniportBlock
.SlotNumber
, &Size
);
1833 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.SlotNumber
== (NDIS_INTERFACE_TYPE
)-1)
1835 NdisInitUnicodeString(&ParamName
, L
"SlotNumber");
1836 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1837 &ParamName
, NdisParameterInteger
);
1838 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1839 Adapter
->NdisMiniportBlock
.SlotNumber
= ConfigParam
->ParameterData
.IntegerData
;
1841 Adapter
->NdisMiniportBlock
.SlotNumber
= 0;
1845 /* Convert slotnumber to PCI_SLOT_NUMBER */
1846 ULONG PciSlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
1847 PCI_SLOT_NUMBER SlotNumber
;
1849 SlotNumber
.u
.AsULONG
= 0;
1850 SlotNumber
.u
.bits
.DeviceNumber
= (PciSlotNumber
>> 16) & 0xFFFF;
1851 SlotNumber
.u
.bits
.FunctionNumber
= PciSlotNumber
& 0xFFFF;
1853 Adapter
->NdisMiniportBlock
.SlotNumber
= SlotNumber
.u
.AsULONG
;
1855 WrapperContext
.SlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
1857 NdisCloseConfiguration(ConfigHandle
);
1859 /* Set handlers (some NDIS macros require these) */
1860 Adapter
->NdisMiniportBlock
.EthRxCompleteHandler
= EthFilterDprIndicateReceiveComplete
;
1861 Adapter
->NdisMiniportBlock
.EthRxIndicateHandler
= EthFilterDprIndicateReceive
;
1862 Adapter
->NdisMiniportBlock
.SendCompleteHandler
= MiniSendComplete
;
1863 Adapter
->NdisMiniportBlock
.SendResourcesHandler
= MiniSendResourcesAvailable
;
1864 Adapter
->NdisMiniportBlock
.ResetCompleteHandler
= MiniResetComplete
;
1865 Adapter
->NdisMiniportBlock
.TDCompleteHandler
= MiniTransferDataComplete
;
1866 Adapter
->NdisMiniportBlock
.PacketIndicateHandler
= MiniIndicateReceivePacket
;
1867 Adapter
->NdisMiniportBlock
.StatusHandler
= MiniStatus
;
1868 Adapter
->NdisMiniportBlock
.StatusCompleteHandler
= MiniStatusComplete
;
1869 Adapter
->NdisMiniportBlock
.SendPacketsHandler
= ProSendPackets
;
1870 Adapter
->NdisMiniportBlock
.QueryCompleteHandler
= MiniRequestComplete
;
1871 Adapter
->NdisMiniportBlock
.SetCompleteHandler
= MiniRequestComplete
;
1874 * Call MiniportInitialize.
1877 NDIS_DbgPrint(MID_TRACE
, ("calling MiniportInitialize\n"));
1878 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.InitializeHandler
)(
1879 &OpenErrorStatus
, &SelectedMediumIndex
, &MediaArray
[0],
1880 MEDIA_ARRAY_SIZE
, Adapter
, (NDIS_HANDLE
)&WrapperContext
);
1882 ZwClose(WrapperContext
.RegistryHandle
);
1884 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1886 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() failed for an adapter.\n"));
1887 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1891 if (SelectedMediumIndex
>= MEDIA_ARRAY_SIZE
)
1893 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() failed for an adapter\n"));
1894 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1895 return NDIS_STATUS_UNSUPPORTED_MEDIA
;
1898 Adapter
->NdisMiniportBlock
.MediaType
= MediaArray
[SelectedMediumIndex
];
1900 switch (Adapter
->NdisMiniportBlock
.MediaType
)
1902 case NdisMedium802_3
:
1903 Adapter
->MediumHeaderSize
= 14; /* XXX figure out what to do about LLC */
1904 AddressOID
= OID_802_3_CURRENT_ADDRESS
;
1905 Adapter
->AddressLength
= ETH_LENGTH_OF_ADDRESS
;
1906 NdisStatus
= DoQueries(Adapter
, AddressOID
);
1907 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1909 NdisStatus
= MiniQueryInformation(Adapter
, OID_802_3_MAXIMUM_LIST_SIZE
, sizeof(UINT
),
1910 &MaxMulticastAddresses
, &BytesWritten
);
1912 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1914 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1915 NDIS_DbgPrint(MAX_TRACE
, ("MiniQueryInformation failed (%x)\n", NdisStatus
));
1919 Success
= EthCreateFilter(MaxMulticastAddresses
,
1920 Adapter
->Address
.Type
.Medium802_3
,
1921 &Adapter
->NdisMiniportBlock
.EthDB
);
1923 ((PETHI_FILTER
)Adapter
->NdisMiniportBlock
.EthDB
)->Miniport
= (PNDIS_MINIPORT_BLOCK
)Adapter
;
1925 NdisStatus
= NDIS_STATUS_RESOURCES
;
1930 /* FIXME: Support other types of media */
1931 NDIS_DbgPrint(MIN_TRACE
, ("error: unsupported media\n"));
1933 /* FIXME - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); */
1934 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1935 return STATUS_UNSUCCESSFUL
;
1938 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1940 NDIS_DbgPrint(MAX_TRACE
, ("couldn't create filter (%x)\n", NdisStatus
));
1944 /* Check for a hang every two seconds if it wasn't set in MiniportInitialize */
1945 if (Adapter
->NdisMiniportBlock
.CheckForHangSeconds
== 0)
1946 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= 2;
1948 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
1949 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStarted
;
1951 IoSetDeviceInterfaceState(&Adapter
->NdisMiniportBlock
.SymbolicLinkName
, TRUE
);
1953 Timeout
.QuadPart
= Int32x32To64(Adapter
->NdisMiniportBlock
.CheckForHangSeconds
, -1000000);
1954 KeSetTimerEx(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
, Timeout
,
1955 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
* 1000,
1956 &Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
);
1958 /* Put adapter in adapter list for this miniport */
1959 ExInterlockedInsertTailList(&Adapter
->NdisMiniportBlock
.DriverHandle
->DeviceList
, &Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
1961 return STATUS_SUCCESS
;
1968 IN PDEVICE_OBJECT DeviceObject
,
1971 * FUNCTION: Handle the PnP stop device event
1973 * DeviceObejct = Functional Device Object
1974 * Irp = IRP_MN_STOP_DEVICE I/O request packet
1976 * Status of operation
1979 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1981 /* Remove adapter from adapter list for this miniport */
1982 ExInterlockedRemoveEntryList(&Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
1984 /* Remove adapter from global adapter list */
1985 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
1987 KeCancelTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
1989 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.HaltHandler
)(Adapter
);
1991 IoSetDeviceInterfaceState(&Adapter
->NdisMiniportBlock
.SymbolicLinkName
, FALSE
);
1993 if (Adapter
->NdisMiniportBlock
.AllocatedResources
)
1995 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
1996 Adapter
->NdisMiniportBlock
.AllocatedResources
= NULL
;
1998 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
)
2000 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
);
2001 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
= NULL
;
2004 if (Adapter
->NdisMiniportBlock
.Resources
)
2006 ExFreePool(Adapter
->NdisMiniportBlock
.Resources
);
2007 Adapter
->NdisMiniportBlock
.Resources
= NULL
;
2010 if (Adapter
->NdisMiniportBlock
.EthDB
)
2012 EthDeleteFilter(Adapter
->NdisMiniportBlock
.EthDB
);
2013 Adapter
->NdisMiniportBlock
.EthDB
= NULL
;
2016 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
2017 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStopped
;
2019 return STATUS_SUCCESS
;
2025 IN PDEVICE_OBJECT DeviceObject
,
2028 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
2029 PMINIPORT_BUGCHECK_CONTEXT Context
= Adapter
->BugcheckContext
;
2030 ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
= Context
->ShutdownHandler
;
2032 ASSERT(ShutdownHandler
);
2034 ShutdownHandler(Context
->DriverContext
);
2036 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2037 Irp
->IoStatus
.Information
= 0;
2039 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2041 return STATUS_SUCCESS
;
2046 NdisIDeviceIoControl(
2047 IN PDEVICE_OBJECT DeviceObject
,
2050 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2051 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2052 NDIS_STATUS Status
= STATUS_NOT_SUPPORTED
;
2054 Irp
->IoStatus
.Information
= 0;
2058 switch (Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
2060 case IOCTL_NDIS_QUERY_GLOBAL_STATS
:
2061 Status
= MiniQueryInformation(Adapter
,
2062 *(PNDIS_OID
)Irp
->AssociatedIrp
.SystemBuffer
,
2063 Stack
->Parameters
.DeviceIoControl
.OutputBufferLength
,
2064 MmGetSystemAddressForMdl(Irp
->MdlAddress
),
2065 &Irp
->IoStatus
.Information
);
2073 if (Status
!= NDIS_STATUS_PENDING
)
2075 Irp
->IoStatus
.Status
= Status
;
2076 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2079 IoMarkIrpPending(Irp
);
2088 IN PDEVICE_OBJECT DeviceObject
,
2091 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2092 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2095 switch (Stack
->MinorFunction
)
2097 case IRP_MN_START_DEVICE
:
2098 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2099 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2101 Status
= NdisIPnPStartDevice(DeviceObject
, Irp
);
2103 Irp
->IoStatus
.Status
= Status
;
2104 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2107 case IRP_MN_STOP_DEVICE
:
2108 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2109 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2111 Status
= NdisIPnPStopDevice(DeviceObject
, Irp
);
2113 Irp
->IoStatus
.Status
= Status
;
2114 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2117 case IRP_MN_QUERY_REMOVE_DEVICE
:
2118 case IRP_MN_QUERY_STOP_DEVICE
:
2119 Status
= NdisIPnPQueryStopDevice(DeviceObject
, Irp
);
2120 Irp
->IoStatus
.Status
= Status
;
2121 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2124 case IRP_MN_CANCEL_REMOVE_DEVICE
:
2125 case IRP_MN_CANCEL_STOP_DEVICE
:
2126 Status
= NdisIPnPCancelStopDevice(DeviceObject
, Irp
);
2127 Irp
->IoStatus
.Status
= Status
;
2128 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2131 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
2132 Status
= NDIS_STATUS_SUCCESS
;
2133 Irp
->IoStatus
.Status
= Status
;
2134 Irp
->IoStatus
.Information
|= Adapter
->NdisMiniportBlock
.PnPFlags
;
2135 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2139 IoSkipCurrentIrpStackLocation(Irp
);
2140 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
2151 IN PDRIVER_OBJECT DriverObject
,
2152 IN PDEVICE_OBJECT PhysicalDeviceObject
)
2154 * FUNCTION: Create a device for an adapter found using PnP
2156 * DriverObject = Pointer to the miniport driver object
2157 * PhysicalDeviceObject = Pointer to the PDO for our adapter
2160 static const WCHAR ClassKeyName
[] = {'C','l','a','s','s','\\'};
2161 static const WCHAR LinkageKeyName
[] = {'\\','L','i','n','k','a','g','e',0};
2162 PNDIS_M_DRIVER_BLOCK Miniport
;
2163 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2164 WCHAR
*LinkageKeyBuffer
;
2165 ULONG DriverKeyLength
;
2166 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
2167 UNICODE_STRING ExportName
;
2168 PDEVICE_OBJECT DeviceObject
;
2169 PLOGICAL_ADAPTER Adapter
;
2173 * Gain the access to the miniport data structure first.
2176 MiniportPtr
= IoGetDriverObjectExtension(DriverObject
, (PVOID
)TAG('D','I','M','N'));
2177 if (MiniportPtr
== NULL
)
2179 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't get driver object extension.\n"));
2180 return STATUS_UNSUCCESSFUL
;
2182 Miniport
= *MiniportPtr
;
2185 * Get name of the Linkage registry key for our adapter. It's located under
2186 * the driver key for our driver and so we have basicly two ways to do it.
2187 * Either we can use IoOpenDriverRegistryKey or compose it using information
2188 * gathered by IoGetDeviceProperty. I choosed the second because
2189 * IoOpenDriverRegistryKey wasn't implemented at the time of writing.
2192 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2193 0, NULL
, &DriverKeyLength
);
2194 if (Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
&& Status
!= STATUS_SUCCESS
)
2196 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't get miniport driver key length.\n"));
2200 LinkageKeyBuffer
= ExAllocatePool(PagedPool
, DriverKeyLength
+
2201 sizeof(ClassKeyName
) + sizeof(LinkageKeyName
));
2202 if (LinkageKeyBuffer
== NULL
)
2204 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't allocate memory for driver key name.\n"));
2205 return STATUS_INSUFFICIENT_RESOURCES
;
2208 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2209 DriverKeyLength
, LinkageKeyBuffer
+
2210 (sizeof(ClassKeyName
) / sizeof(WCHAR
)),
2212 if (!NT_SUCCESS(Status
))
2214 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't get miniport driver key.\n"));
2215 ExFreePool(LinkageKeyBuffer
);
2219 /* Compose the linkage key name. */
2220 RtlCopyMemory(LinkageKeyBuffer
, ClassKeyName
, sizeof(ClassKeyName
));
2221 RtlCopyMemory(LinkageKeyBuffer
+ ((sizeof(ClassKeyName
) + DriverKeyLength
) /
2222 sizeof(WCHAR
)) - 1, LinkageKeyName
, sizeof(LinkageKeyName
));
2224 NDIS_DbgPrint(DEBUG_MINIPORT
, ("LinkageKey: %S.\n", LinkageKeyBuffer
));
2227 * Now open the linkage key and read the "Export" and "RootDevice" values
2228 * which contains device name and root service respectively.
2231 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
2232 RtlInitUnicodeString(&ExportName
, NULL
);
2233 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
| RTL_QUERY_REGISTRY_DIRECT
;
2234 QueryTable
[0].Name
= L
"Export";
2235 QueryTable
[0].EntryContext
= &ExportName
;
2237 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
, LinkageKeyBuffer
,
2238 QueryTable
, NULL
, NULL
);
2239 ExFreePool(LinkageKeyBuffer
);
2240 if (!NT_SUCCESS(Status
))
2242 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't get miniport device name. (%x)\n", Status
));
2247 * Create the device object.
2250 NDIS_DbgPrint(MAX_TRACE
, ("creating device %wZ\n", &ExportName
));
2252 Status
= IoCreateDevice(Miniport
->DriverObject
, sizeof(LOGICAL_ADAPTER
),
2253 &ExportName
, FILE_DEVICE_PHYSICAL_NETCARD
,
2254 0, FALSE
, &DeviceObject
);
2255 if (!NT_SUCCESS(Status
))
2257 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device object.\n"));
2258 RtlFreeUnicodeString(&ExportName
);
2263 * Initialize the adapter structure.
2266 Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2267 KeInitializeSpinLock(&Adapter
->NdisMiniportBlock
.Lock
);
2268 InitializeListHead(&Adapter
->ProtocolListHead
);
2270 Status
= IoRegisterDeviceInterface(PhysicalDeviceObject
,
2271 &GUID_DEVINTERFACE_NET
,
2273 &Adapter
->NdisMiniportBlock
.SymbolicLinkName
);
2275 if (!NT_SUCCESS(Status
))
2277 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device interface.\n"));
2278 IoDeleteDevice(DeviceObject
);
2279 RtlFreeUnicodeString(&ExportName
);
2283 Adapter
->NdisMiniportBlock
.DriverHandle
= Miniport
;
2284 Adapter
->NdisMiniportBlock
.MiniportName
= ExportName
;
2285 Adapter
->NdisMiniportBlock
.DeviceObject
= DeviceObject
;
2286 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
= PhysicalDeviceObject
;
2287 Adapter
->NdisMiniportBlock
.NextDeviceObject
=
2288 IoAttachDeviceToDeviceStack(Adapter
->NdisMiniportBlock
.DeviceObject
,
2289 PhysicalDeviceObject
);
2291 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= 0;
2292 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceAdded
;
2294 KeInitializeTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
2295 KeInitializeDpc(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
, MiniportHangDpc
, Adapter
);
2297 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
2299 return STATUS_SUCCESS
;
2308 NdisMRegisterMiniport(
2309 IN NDIS_HANDLE NdisWrapperHandle
,
2310 IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics
,
2311 IN UINT CharacteristicsLength
)
2313 * FUNCTION: Registers a miniport's MiniportXxx entry points with the NDIS library
2315 * NdisWrapperHandle = Pointer to handle returned by NdisMInitializeWrapper
2316 * MiniportCharacteristics = Pointer to a buffer with miniport characteristics
2317 * CharacteristicsLength = Number of bytes in characteristics buffer
2319 * Status of operation
2323 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2324 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2327 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2329 switch (MiniportCharacteristics
->MajorNdisVersion
)
2332 MinSize
= sizeof(NDIS30_MINIPORT_CHARACTERISTICS
);
2336 MinSize
= sizeof(NDIS40_MINIPORT_CHARACTERISTICS
);
2340 MinSize
= sizeof(NDIS50_MINIPORT_CHARACTERISTICS
);
2344 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics version.\n"));
2345 return NDIS_STATUS_BAD_VERSION
;
2348 NDIS_DbgPrint(MIN_TRACE
, ("Initializing an NDIS %u.%u miniport\n",
2349 MiniportCharacteristics
->MajorNdisVersion
,
2350 MiniportCharacteristics
->MinorNdisVersion
));
2352 if (CharacteristicsLength
< MinSize
)
2354 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics length.\n"));
2355 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2358 /* Check if mandatory MiniportXxx functions are specified */
2359 if ((!MiniportCharacteristics
->HaltHandler
) ||
2360 (!MiniportCharacteristics
->InitializeHandler
)||
2361 (!MiniportCharacteristics
->ResetHandler
))
2363 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics.\n"));
2364 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2367 if (MiniportCharacteristics
->MajorNdisVersion
< 0x05)
2369 if ((!MiniportCharacteristics
->QueryInformationHandler
) ||
2370 (!MiniportCharacteristics
->SetInformationHandler
))
2372 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (Set/Query)\n"));
2373 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2378 if (((!MiniportCharacteristics
->QueryInformationHandler
) ||
2379 (!MiniportCharacteristics
->SetInformationHandler
)) &&
2380 (!MiniportCharacteristics
->CoRequestHandler
))
2382 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (Set/Query)\n"));
2383 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2387 if (MiniportCharacteristics
->MajorNdisVersion
== 0x03)
2389 if (!MiniportCharacteristics
->SendHandler
)
2391 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 3.0)\n"));
2392 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2395 else if (MiniportCharacteristics
->MajorNdisVersion
== 0x04)
2398 if ((!MiniportCharacteristics
->SendHandler
) &&
2399 (!MiniportCharacteristics
->SendPacketsHandler
))
2401 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 4.0)\n"));
2402 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2405 else if (MiniportCharacteristics
->MajorNdisVersion
== 0x05)
2407 /* TODO: Add more checks here */
2409 if ((!MiniportCharacteristics
->SendHandler
) &&
2410 (!MiniportCharacteristics
->SendPacketsHandler
) &&
2411 (!MiniportCharacteristics
->CoSendPacketsHandler
))
2413 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 5.0)\n"));
2414 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2418 /* TODO: verify NDIS5 and NDIS5.1 */
2420 RtlCopyMemory(&Miniport
->MiniportCharacteristics
, MiniportCharacteristics
, MinSize
);
2423 * NOTE: This is VERY unoptimal! Should we store the NDIS_M_DRIVER_BLOCK
2424 * structure in the driver extension or what?
2427 Status
= IoAllocateDriverObjectExtension(Miniport
->DriverObject
, (PVOID
)TAG('D','I','M','N'),
2428 sizeof(PNDIS_M_DRIVER_BLOCK
), (PVOID
*)&MiniportPtr
);
2429 if (!NT_SUCCESS(Status
))
2431 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't allocate driver object extension.\n"));
2432 return NDIS_STATUS_RESOURCES
;
2435 *MiniportPtr
= Miniport
;
2437 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_PNP
] = NdisIDispatchPnp
;
2438 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] = NdisIShutdown
;
2439 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = NdisIDeviceIoControl
;
2440 Miniport
->DriverObject
->DriverExtension
->AddDevice
= NdisIAddDevice
;
2442 return NDIS_STATUS_SUCCESS
;
2449 #undef NdisMResetComplete
2453 IN NDIS_HANDLE MiniportAdapterHandle
,
2454 IN NDIS_STATUS Status
,
2455 IN BOOLEAN AddressingReset
)
2457 MiniResetComplete(MiniportAdapterHandle
, Status
, AddressingReset
);
2464 #undef NdisMSendComplete
2468 IN NDIS_HANDLE MiniportAdapterHandle
,
2469 IN PNDIS_PACKET Packet
,
2470 IN NDIS_STATUS Status
)
2472 * FUNCTION: Forwards a message to the initiating protocol saying
2473 * that a packet was handled
2475 * NdisAdapterHandle = Handle input to MiniportInitialize
2476 * Packet = Pointer to NDIS packet that was sent
2477 * Status = Status of send operation
2480 MiniSendComplete(MiniportAdapterHandle
, Packet
, Status
);
2487 #undef NdisMSendResourcesAvailable
2490 NdisMSendResourcesAvailable(
2491 IN NDIS_HANDLE MiniportAdapterHandle
)
2493 MiniSendResourcesAvailable(MiniportAdapterHandle
);
2500 #undef NdisMTransferDataComplete
2503 NdisMTransferDataComplete(
2504 IN NDIS_HANDLE MiniportAdapterHandle
,
2505 IN PNDIS_PACKET Packet
,
2506 IN NDIS_STATUS Status
,
2507 IN UINT BytesTransferred
)
2509 MiniTransferDataComplete(MiniportAdapterHandle
, Packet
, Status
, BytesTransferred
);
2516 #undef NdisMSetAttributes
2520 IN NDIS_HANDLE MiniportAdapterHandle
,
2521 IN NDIS_HANDLE MiniportAdapterContext
,
2522 IN BOOLEAN BusMaster
,
2523 IN NDIS_INTERFACE_TYPE AdapterType
)
2525 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2527 * MiniportAdapterHandle = Handle input to MiniportInitialize
2528 * MiniportAdapterContext = Pointer to context information
2529 * BusMaster = Specifies TRUE if the caller's NIC is a busmaster DMA device
2530 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2533 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2534 NdisMSetAttributesEx(MiniportAdapterHandle
, MiniportAdapterContext
, 0,
2535 BusMaster
? NDIS_ATTRIBUTE_BUS_MASTER
: 0,
2545 NdisMSetAttributesEx(
2546 IN NDIS_HANDLE MiniportAdapterHandle
,
2547 IN NDIS_HANDLE MiniportAdapterContext
,
2548 IN UINT CheckForHangTimeInSeconds OPTIONAL
,
2549 IN ULONG AttributeFlags
,
2550 IN NDIS_INTERFACE_TYPE AdapterType
)
2552 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2554 * MiniportAdapterHandle = Handle input to MiniportInitialize
2555 * MiniportAdapterContext = Pointer to context information
2556 * CheckForHangTimeInSeconds = Specifies interval in seconds at which
2557 * MiniportCheckForHang should be called
2558 * AttributeFlags = Bitmask that indicates specific attributes
2559 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2562 PLOGICAL_ADAPTER Adapter
= GET_LOGICAL_ADAPTER(MiniportAdapterHandle
);
2564 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2566 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
= MiniportAdapterContext
;
2567 Adapter
->NdisMiniportBlock
.Flags
= AttributeFlags
;
2568 Adapter
->NdisMiniportBlock
.AdapterType
= AdapterType
;
2569 if (CheckForHangTimeInSeconds
> 0)
2570 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= CheckForHangTimeInSeconds
;
2571 if (AttributeFlags
& NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER
)
2572 NDIS_DbgPrint(MAX_TRACE
, ("Intermediate drivers not supported yet.\n"));
2575 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.AdapterShutdownHandler
)
2577 NDIS_DbgPrint(MAX_TRACE
, ("Miniport set AdapterShutdownHandler in MiniportCharacteristics\n"));
2578 NdisMRegisterAdapterShutdownHandler(Adapter
,
2579 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
2580 Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.AdapterShutdownHandler
);
2591 IN ULONG MicrosecondsToSleep
)
2593 * FUNCTION: delay the thread's execution for MicrosecondsToSleep
2595 * MicrosecondsToSleep: duh...
2597 * - Because this is a blocking call, current IRQL must be < DISPATCH_LEVEL
2601 LARGE_INTEGER DueTime
;
2605 DueTime
.QuadPart
= (-1) * 10 * MicrosecondsToSleep
;
2607 KeInitializeTimer(&Timer
);
2608 KeSetTimer(&Timer
, DueTime
, 0);
2609 KeWaitForSingleObject(&Timer
, Executive
, KernelMode
, FALSE
, 0);
2618 NdisMSynchronizeWithInterrupt(
2619 IN PNDIS_MINIPORT_INTERRUPT Interrupt
,
2620 IN PVOID SynchronizeFunction
,
2621 IN PVOID SynchronizeContext
)
2623 return(KeSynchronizeExecution(Interrupt
->InterruptObject
,
2624 (PKSYNCHRONIZE_ROUTINE
)SynchronizeFunction
,
2625 SynchronizeContext
));
2635 IN NDIS_HANDLE LogHandle
,
2637 IN UINT LogBufferSize
)
2639 PUCHAR Buffer
= LogBuffer
;
2643 for (i
= 0; i
< LogBufferSize
; i
+= 16)
2645 DbgPrint("%08x |", i
);
2646 for (j
= 0; j
< 16; j
++)
2649 if (idx
< LogBufferSize
)
2650 DbgPrint(" %02x", Buffer
[idx
]);
2655 for (j
= 0; j
< 16; j
++)
2658 if (idx
== LogBufferSize
)
2660 if (Buffer
[idx
] >= ' ') /* FIXME: not portable! replace by if (isprint(Buffer[idx])) ? */
2661 DbgPrint("%c", Buffer
[idx
]);
2668 return NDIS_STATUS_FAILURE
;
2677 NdisTerminateWrapper(
2678 IN NDIS_HANDLE NdisWrapperHandle
,
2679 IN PVOID SystemSpecific
)
2681 * FUNCTION: Releases resources allocated by a call to NdisInitializeWrapper
2683 * NdisWrapperHandle = Handle returned by NdisInitializeWrapper (NDIS_M_DRIVER_BLOCK)
2684 * SystemSpecific = Always NULL
2687 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2689 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2691 ExFreePool(Miniport
->RegistryPath
->Buffer
);
2692 ExFreePool(Miniport
->RegistryPath
);
2693 ExInterlockedRemoveEntryList(&Miniport
->ListEntry
, &MiniportListLock
);
2694 ExFreePool(Miniport
);
2703 NdisMQueryAdapterInstanceName(
2704 OUT PNDIS_STRING AdapterInstanceName
,
2705 IN NDIS_HANDLE MiniportAdapterHandle
)
2713 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
2714 UNICODE_STRING AdapterName
;
2716 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2718 AdapterName
.Length
= 0;
2719 AdapterName
.MaximumLength
= Adapter
->NdisMiniportBlock
.MiniportName
.MaximumLength
;
2720 AdapterName
.Buffer
= ExAllocatePool(PagedPool
, AdapterName
.MaximumLength
);
2721 if (!AdapterName
.Buffer
)
2722 return NDIS_STATUS_RESOURCES
;
2724 RtlCopyUnicodeString(&AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
);
2726 *AdapterInstanceName
= AdapterName
;
2728 return NDIS_STATUS_SUCCESS
;
2736 NdisDeregisterAdapterShutdownHandler(
2737 IN NDIS_HANDLE NdisAdapterHandle
)
2745 NdisMDeregisterAdapterShutdownHandler(NdisAdapterHandle
);
2754 NdisRegisterAdapterShutdownHandler(
2755 IN NDIS_HANDLE NdisAdapterHandle
,
2756 IN PVOID ShutdownContext
,
2757 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
2765 NdisMRegisterAdapterShutdownHandler(NdisAdapterHandle
,
2775 NdisMGetDeviceProperty(
2776 IN NDIS_HANDLE MiniportAdapterHandle
,
2777 IN OUT PDEVICE_OBJECT
*PhysicalDeviceObject OPTIONAL
,
2778 IN OUT PDEVICE_OBJECT
*FunctionalDeviceObject OPTIONAL
,
2779 IN OUT PDEVICE_OBJECT
*NextDeviceObject OPTIONAL
,
2780 IN OUT PCM_RESOURCE_LIST
*AllocatedResources OPTIONAL
,
2781 IN OUT PCM_RESOURCE_LIST
*AllocatedResourcesTranslated OPTIONAL
)
2789 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
2791 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
2793 if (PhysicalDeviceObject
!= NULL
)
2794 *PhysicalDeviceObject
= Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
;
2796 if (FunctionalDeviceObject
!= NULL
)
2797 *FunctionalDeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
2799 if (NextDeviceObject
!= NULL
)
2800 *NextDeviceObject
= Adapter
->NdisMiniportBlock
.NextDeviceObject
;
2802 if (AllocatedResources
!= NULL
)
2803 *AllocatedResources
= Adapter
->NdisMiniportBlock
.AllocatedResources
;
2805 if (AllocatedResourcesTranslated
!= NULL
)
2806 *AllocatedResourcesTranslated
= Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
;
2814 NdisMRegisterUnloadHandler(
2815 IN NDIS_HANDLE NdisWrapperHandle
,
2816 IN PDRIVER_UNLOAD UnloadHandler
)
2824 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
2826 NDIS_DbgPrint(MAX_TRACE
, ("Miniport registered unload handler\n"));
2828 DriverBlock
->DriverObject
->DriverUnload
= UnloadHandler
;
2836 NdisMRegisterDevice(
2837 IN NDIS_HANDLE NdisWrapperHandle
,
2838 IN PNDIS_STRING DeviceName
,
2839 IN PNDIS_STRING SymbolicName
,
2840 IN PDRIVER_DISPATCH MajorFunctions
[],
2841 OUT PDEVICE_OBJECT
*pDeviceObject
,
2842 OUT NDIS_HANDLE
*NdisDeviceHandle
)
2850 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
2851 PNDIS_M_DEVICE_BLOCK DeviceBlock
;
2852 PDEVICE_OBJECT DeviceObject
;
2856 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
2858 Status
= IoCreateDevice(DriverBlock
->DriverObject
,
2859 0, /* This space is reserved for us. Should we use it? */
2861 FILE_DEVICE_NETWORK
,
2866 if (!NT_SUCCESS(Status
))
2871 Status
= IoCreateSymbolicLink(SymbolicName
, DeviceName
);
2873 if (!NT_SUCCESS(Status
))
2875 IoDeleteDevice(DeviceObject
);
2879 DeviceBlock
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DEVICE_BLOCK
));
2883 IoDeleteDevice(DeviceObject
);
2884 IoDeleteSymbolicLink(SymbolicName
);
2885 return NDIS_STATUS_RESOURCES
;
2888 for (i
= 0; i
<= IRP_MJ_MAXIMUM_FUNCTION
; i
++)
2889 DriverBlock
->DriverObject
->MajorFunction
[i
] = MajorFunctions
[i
];
2891 DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_PNP
] = NdisIDispatchPnp
;
2893 DeviceBlock
->DeviceObject
= DeviceObject
;
2894 DeviceBlock
->SymbolicName
= SymbolicName
;
2896 *pDeviceObject
= DeviceObject
;
2897 *NdisDeviceHandle
= DeviceBlock
;
2899 return NDIS_STATUS_SUCCESS
;
2907 NdisMDeregisterDevice(
2908 IN NDIS_HANDLE NdisDeviceHandle
)
2916 PNDIS_M_DEVICE_BLOCK DeviceBlock
= NdisDeviceHandle
;
2918 IoDeleteDevice(DeviceBlock
->DeviceObject
);
2920 IoDeleteSymbolicLink(DeviceBlock
->SymbolicName
);
2922 ExFreePool(DeviceBlock
);
2924 return NDIS_STATUS_SUCCESS
;
2932 NdisQueryAdapterInstanceName(
2933 OUT PNDIS_STRING AdapterInstanceName
,
2934 IN NDIS_HANDLE NdisBindingHandle
)
2942 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
2943 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
2945 return NdisMQueryAdapterInstanceName(AdapterInstanceName
,
2954 NdisCompletePnPEvent(
2955 IN NDIS_STATUS Status
,
2956 IN NDIS_HANDLE NdisBindingHandle
,
2957 IN PNET_PNP_EVENT NetPnPEvent
)
2965 PIRP Irp
= (PIRP
)NetPnPEvent
->NdisReserved
[0];
2966 PLIST_ENTRY CurrentEntry
= (PLIST_ENTRY
)NetPnPEvent
->NdisReserved
[1];
2967 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
2968 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
2969 NDIS_STATUS NdisStatus
;
2971 if (Status
!= NDIS_STATUS_SUCCESS
)
2973 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
2974 ExFreePool(NetPnPEvent
);
2975 Irp
->IoStatus
.Status
= Status
;
2976 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2980 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
2982 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
2984 NdisStatus
= (*AdapterBinding
->ProtocolBinding
->Chars
.PnPEventHandler
)(
2985 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
2988 if (NdisStatus
== NDIS_STATUS_PENDING
)
2990 NetPnPEvent
->NdisReserved
[1] = (ULONG_PTR
)CurrentEntry
->Flink
;
2993 else if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2995 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
2996 ExFreePool(NetPnPEvent
);
2997 Irp
->IoStatus
.Status
= NdisStatus
;
2998 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3002 CurrentEntry
= CurrentEntry
->Flink
;
3005 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3006 ExFreePool(NetPnPEvent
);
3008 Irp
->IoStatus
.Status
= NDIS_STATUS_SUCCESS
;
3009 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3017 NdisCancelSendPackets(
3018 IN NDIS_HANDLE NdisBindingHandle
,
3021 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3022 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3024 NDIS_DbgPrint(MAX_TRACE
, ("Called for ID %x.\n", CancelId
));
3026 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CancelSendPacketsHandler
)
3028 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CancelSendPacketsHandler
)(
3029 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
3040 NdisIMGetBindingContext(
3041 IN NDIS_HANDLE NdisBindingHandle
)
3049 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3050 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3052 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3054 return Adapter
->NdisMiniportBlock
.DeviceContext
;
3063 NdisIMGetDeviceContext(
3064 IN NDIS_HANDLE MiniportAdapterHandle
)
3072 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
3074 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3076 return Adapter
->NdisMiniportBlock
.DeviceContext
;