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
;
361 MiniDoAddressingReset(Adapter
);
363 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
364 NdisMIndicateStatusComplete(Adapter
);
366 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
368 Adapter
->NdisMiniportBlock
.ResetStatus
= Status
;
370 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
372 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
374 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
376 (*AdapterBinding
->ProtocolBinding
->Chars
.ResetCompleteHandler
)(
377 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
380 CurrentEntry
= CurrentEntry
->Flink
;
383 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
388 IN NDIS_HANDLE MiniportAdapterHandle
,
389 IN NDIS_STATUS Status
)
391 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
392 PNDIS_REQUEST Request
;
393 PNDIS_REQUEST_MAC_BLOCK MacBlock
;
396 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
398 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
400 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
401 Request
= Adapter
->NdisMiniportBlock
.PendingRequest
;
402 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
404 MacBlock
= (PNDIS_REQUEST_MAC_BLOCK
)Request
->MacReserved
;
406 if( MacBlock
->Binding
->RequestCompleteHandler
) {
407 (*MacBlock
->Binding
->RequestCompleteHandler
)(
408 MacBlock
->Binding
->ProtocolBindingContext
,
413 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
414 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
415 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
417 KeLowerIrql(OldIrql
);
422 IN NDIS_HANDLE MiniportAdapterHandle
,
423 IN PNDIS_PACKET Packet
,
424 IN NDIS_STATUS Status
)
426 * FUNCTION: Forwards a message to the initiating protocol saying
427 * that a packet was handled
429 * NdisAdapterHandle = Handle input to MiniportInitialize
430 * Packet = Pointer to NDIS packet that was sent
431 * Status = Status of send operation
434 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
435 PADAPTER_BINDING AdapterBinding
;
437 PSCATTER_GATHER_LIST SGList
;
439 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
441 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
443 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
445 if (Adapter
->NdisMiniportBlock
.ScatterGatherListSize
!= 0)
447 NDIS_DbgPrint(MAX_TRACE
, ("Freeing Scatter/Gather list\n"));
449 SGList
= NDIS_PER_PACKET_INFO_FROM_PACKET(Packet
,
450 ScatterGatherListPacketInfo
);
452 Adapter
->NdisMiniportBlock
.SystemAdapterObject
->
453 DmaOperations
->PutScatterGatherList(
454 Adapter
->NdisMiniportBlock
.SystemAdapterObject
,
458 NDIS_PER_PACKET_INFO_FROM_PACKET(Packet
,
459 ScatterGatherListPacketInfo
) = NULL
;
462 (*AdapterBinding
->ProtocolBinding
->Chars
.SendCompleteHandler
)(
463 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
467 KeLowerIrql(OldIrql
);
472 MiniSendResourcesAvailable(
473 IN NDIS_HANDLE MiniportAdapterHandle
)
482 MiniTransferDataComplete(
483 IN NDIS_HANDLE MiniportAdapterHandle
,
484 IN PNDIS_PACKET Packet
,
485 IN NDIS_STATUS Status
,
486 IN UINT BytesTransferred
)
488 PADAPTER_BINDING AdapterBinding
;
491 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
493 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[1];
495 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
496 (*AdapterBinding
->ProtocolBinding
->Chars
.TransferDataCompleteHandler
)(
497 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
501 KeLowerIrql(OldIrql
);
506 MiniAdapterHasAddress(
507 PLOGICAL_ADAPTER Adapter
,
510 * FUNCTION: Determines whether a packet has the same destination address as an adapter
512 * Adapter = Pointer to logical adapter object
513 * Packet = Pointer to NDIS packet
515 * TRUE if the destination address is that of the adapter, FALSE if not
521 PNDIS_BUFFER NdisBuffer
;
524 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
529 NDIS_DbgPrint(MIN_TRACE
, ("Adapter object was null\n"));
535 NDIS_DbgPrint(MIN_TRACE
, ("Packet was null\n"));
540 NdisQueryPacket(Packet
, NULL
, NULL
, &NdisBuffer
, NULL
);
544 NDIS_DbgPrint(MIN_TRACE
, ("Packet contains no buffers.\n"));
548 NdisQueryBuffer(NdisBuffer
, (PVOID
)&Start2
, &BufferLength
);
550 /* FIXME: Should handle fragmented packets */
552 switch (Adapter
->NdisMiniportBlock
.MediaType
)
554 case NdisMedium802_3
:
555 Length
= ETH_LENGTH_OF_ADDRESS
;
556 /* Destination address is the first field */
560 NDIS_DbgPrint(MIN_TRACE
, ("Adapter has unsupported media type (0x%X).\n", Adapter
->NdisMiniportBlock
.MediaType
));
564 if (BufferLength
< Length
)
566 NDIS_DbgPrint(MIN_TRACE
, ("Buffer is too small.\n"));
570 Start1
= (PUCHAR
)&Adapter
->Address
;
571 NDIS_DbgPrint(MAX_TRACE
, ("packet address: %x:%x:%x:%x:%x:%x adapter address: %x:%x:%x:%x:%x:%x\n",
572 *((char *)Start1
), *(((char *)Start1
)+1), *(((char *)Start1
)+2), *(((char *)Start1
)+3), *(((char *)Start1
)+4), *(((char *)Start1
)+5),
573 *((char *)Start2
), *(((char *)Start2
)+1), *(((char *)Start2
)+2), *(((char *)Start2
)+3), *(((char *)Start2
)+4), *(((char *)Start2
)+5))
576 return (RtlCompareMemory((PVOID
)Start1
, (PVOID
)Start2
, Length
) == Length
);
582 PNDIS_STRING AdapterName
)
584 * FUNCTION: Finds an adapter object by name
586 * AdapterName = Pointer to name of adapter
588 * Pointer to logical adapter object, or NULL if none was found.
589 * If found, the adapter is referenced for the caller. The caller
590 * is responsible for dereferencing after use
594 PLIST_ENTRY CurrentEntry
;
595 PLOGICAL_ADAPTER Adapter
= 0;
599 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
601 if(IsListEmpty(&AdapterListHead
))
603 NDIS_DbgPrint(MIN_TRACE
, ("No registered miniports for protocol to bind to\n"));
607 KeAcquireSpinLock(&AdapterListLock
, &OldIrql
);
609 CurrentEntry
= AdapterListHead
.Flink
;
611 while (CurrentEntry
!= &AdapterListHead
)
613 Adapter
= CONTAINING_RECORD(CurrentEntry
, LOGICAL_ADAPTER
, ListEntry
);
617 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Examining adapter 0x%lx\n", Adapter
));
618 NDIS_DbgPrint(DEBUG_MINIPORT
, ("AdapterName = %wZ\n", AdapterName
));
619 NDIS_DbgPrint(DEBUG_MINIPORT
, ("DeviceName = %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
621 if (RtlCompareUnicodeString(AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
, TRUE
) == 0)
627 CurrentEntry
= CurrentEntry
->Flink
;
630 KeReleaseSpinLock(&AdapterListLock
, OldIrql
);
634 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Leaving. Adapter found at 0x%x\n", Adapter
));
638 NDIS_DbgPrint(MIN_TRACE
, ("Leaving (adapter not found for %wZ).\n", AdapterName
));
646 PLOGICAL_ADAPTER Adapter
,
652 NDIS_STATUS NdisStatus
;
653 PNDIS_REQUEST NdisRequest
;
655 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
657 NdisRequest
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_REQUEST
));
659 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
660 return NDIS_STATUS_RESOURCES
;
663 RtlZeroMemory(NdisRequest
, sizeof(NDIS_REQUEST
));
665 NdisRequest
->RequestType
= NdisRequestSetInformation
;
666 NdisRequest
->DATA
.SET_INFORMATION
.Oid
= Oid
;
667 NdisRequest
->DATA
.SET_INFORMATION
.InformationBuffer
= Buffer
;
668 NdisRequest
->DATA
.SET_INFORMATION
.InformationBufferLength
= Size
;
670 NdisStatus
= MiniDoRequest(Adapter
, NdisRequest
);
672 /* FIXME: Wait in pending case! */
674 ASSERT(NdisStatus
!= NDIS_STATUS_PENDING
);
676 *BytesRead
= NdisRequest
->DATA
.SET_INFORMATION
.BytesRead
;
678 ExFreePool(NdisRequest
);
684 MiniQueryInformation(
685 PLOGICAL_ADAPTER Adapter
,
691 * FUNCTION: Queries a logical adapter for properties
693 * Adapter = Pointer to the logical adapter object to query
694 * Oid = Specifies the Object ID to query for
695 * Size = Size of the passed buffer
696 * Buffer = Buffer for the output
697 * BytesWritten = Address of buffer to place number of bytes written
699 * Status of operation
702 NDIS_STATUS NdisStatus
;
703 PNDIS_REQUEST NdisRequest
;
705 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
707 NdisRequest
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_REQUEST
));
709 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
710 return NDIS_STATUS_RESOURCES
;
713 RtlZeroMemory(NdisRequest
, sizeof(NDIS_REQUEST
));
715 NdisRequest
->RequestType
= NdisRequestQueryInformation
;
716 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
= Oid
;
717 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
= Buffer
;
718 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
= Size
;
720 NdisStatus
= MiniDoRequest(Adapter
, NdisRequest
);
722 /* FIXME: Wait in pending case! */
724 ASSERT(NdisStatus
!= NDIS_STATUS_PENDING
);
726 *BytesWritten
= NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
;
728 ExFreePool(NdisRequest
);
734 MiniCheckForHang( PLOGICAL_ADAPTER Adapter
)
736 * FUNCTION: Checks to see if the miniport is hung
738 * Adapter = Pointer to the logical adapter object
740 * TRUE if the miniport is hung
741 * FALSE if the miniport is not hung
747 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
748 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)
749 Ret
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CheckForHangHandler
)(
750 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
);
751 KeLowerIrql(OldIrql
);
757 MiniDoAddressingReset(PLOGICAL_ADAPTER Adapter
)
761 MiniSetInformation(Adapter
,
762 OID_GEN_CURRENT_LOOKAHEAD
,
764 &Adapter
->NdisMiniportBlock
.CurrentLookahead
,
767 /* FIXME: Set more stuff */
772 PLOGICAL_ADAPTER Adapter
)
774 * FUNCTION: Resets the miniport
776 * Adapter = Pointer to the logical adapter object
778 * Status of the operation
783 BOOLEAN AddressingReset
= TRUE
;
785 if (MiniIsBusy(Adapter
, NdisWorkItemResetRequested
)) {
786 MiniQueueWorkItem(Adapter
, NdisWorkItemResetRequested
, NULL
, FALSE
);
787 return NDIS_STATUS_PENDING
;
790 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
791 NdisMIndicateStatusComplete(Adapter
);
793 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
794 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
795 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
798 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
799 Adapter
->NdisMiniportBlock
.ResetStatus
= Status
;
800 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
802 KeLowerIrql(OldIrql
);
804 if (Status
!= NDIS_STATUS_PENDING
) {
806 MiniDoAddressingReset(Adapter
);
808 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_END
, NULL
, 0);
809 NdisMIndicateStatusComplete(Adapter
);
818 PVOID DeferredContext
,
819 PVOID SystemArgument1
,
820 PVOID SystemArgument2
)
822 PLOGICAL_ADAPTER Adapter
= DeferredContext
;
824 if (MiniCheckForHang(Adapter
)) {
825 NDIS_DbgPrint(MIN_TRACE
, ("Miniport detected adapter hang\n"));
834 PLOGICAL_ADAPTER Adapter
,
835 NDIS_WORK_ITEM_TYPE WorkItemType
,
836 PVOID WorkItemContext
,
839 * FUNCTION: Queues a work item for execution at a later time
841 * Adapter = Pointer to the logical adapter object to queue work item on
842 * WorkItemType = Type of work item to queue
843 * WorkItemContext = Pointer to context information for work item
845 * Status of operation
848 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
849 PIO_WORKITEM IoWorkItem
;
852 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
856 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
859 if (WorkItemType
== NdisWorkItemSend
)
861 NDIS_DbgPrint(MIN_TRACE
, ("Requeuing failed packet (%x).\n", WorkItemContext
));
862 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= WorkItemContext
;
866 //This should never happen
872 MiniportWorkItem
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_MINIPORT_WORK_ITEM
));
873 if (!MiniportWorkItem
)
875 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
876 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
880 MiniportWorkItem
->WorkItemType
= WorkItemType
;
881 MiniportWorkItem
->WorkItemContext
= WorkItemContext
;
883 /* safe due to adapter lock held */
884 MiniportWorkItem
->Link
.Next
= NULL
;
885 if (!Adapter
->WorkQueueHead
)
887 Adapter
->WorkQueueHead
= MiniportWorkItem
;
888 Adapter
->WorkQueueTail
= MiniportWorkItem
;
892 Adapter
->WorkQueueTail
->Link
.Next
= (PSINGLE_LIST_ENTRY
)MiniportWorkItem
;
893 Adapter
->WorkQueueTail
= MiniportWorkItem
;
897 IoWorkItem
= IoAllocateWorkItem(Adapter
->NdisMiniportBlock
.DeviceObject
);
899 IoQueueWorkItem(IoWorkItem
, MiniportWorker
, DelayedWorkQueue
, IoWorkItem
);
901 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
908 PLOGICAL_ADAPTER Adapter
,
909 NDIS_WORK_ITEM_TYPE
*WorkItemType
,
910 PVOID
*WorkItemContext
)
912 * FUNCTION: Dequeues a work item from the work queue of a logical adapter
914 * Adapter = Pointer to the logical adapter object to dequeue work item from
915 * AdapterBinding = Address of buffer for adapter binding for this request
916 * WorkItemType = Address of buffer for work item type
917 * WorkItemContext = Address of buffer for pointer to context information
919 * Adapter lock must be held when called
921 * Status of operation
924 PNDIS_MINIPORT_WORK_ITEM MiniportWorkItem
;
927 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
929 MiniportWorkItem
= Adapter
->WorkQueueHead
;
931 if ((Packet
= Adapter
->NdisMiniportBlock
.FirstPendingPacket
))
933 Adapter
->NdisMiniportBlock
.FirstPendingPacket
= NULL
;
935 *WorkItemType
= NdisWorkItemSend
;
936 *WorkItemContext
= Packet
;
938 return NDIS_STATUS_SUCCESS
;
940 else if (MiniportWorkItem
)
942 /* safe due to adapter lock held */
943 Adapter
->WorkQueueHead
= (PNDIS_MINIPORT_WORK_ITEM
)MiniportWorkItem
->Link
.Next
;
945 if (MiniportWorkItem
== Adapter
->WorkQueueTail
)
946 Adapter
->WorkQueueTail
= NULL
;
948 *WorkItemType
= MiniportWorkItem
->WorkItemType
;
949 *WorkItemContext
= MiniportWorkItem
->WorkItemContext
;
951 ExFreePool(MiniportWorkItem
);
953 return NDIS_STATUS_SUCCESS
;
957 NDIS_DbgPrint(MIN_TRACE
, ("No work item to dequeue\n"));
959 return NDIS_STATUS_FAILURE
;
966 PLOGICAL_ADAPTER Adapter
,
967 PNDIS_REQUEST NdisRequest
)
969 * FUNCTION: Sends a request to a miniport
971 * AdapterBinding = Pointer to binding used in the request
972 * NdisRequest = Pointer to NDIS request structure describing request
974 * Status of operation
979 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
981 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
983 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
984 Adapter
->NdisMiniportBlock
.PendingRequest
= NdisRequest
;
985 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
987 if (!Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CoRequestHandler
)
989 switch (NdisRequest
->RequestType
)
991 case NdisRequestQueryInformation
:
992 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.QueryInformationHandler
)(
993 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
994 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
,
995 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
,
996 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
,
997 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
,
998 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesNeeded
);
1001 case NdisRequestSetInformation
:
1002 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SetInformationHandler
)(
1003 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1004 NdisRequest
->DATA
.SET_INFORMATION
.Oid
,
1005 NdisRequest
->DATA
.SET_INFORMATION
.InformationBuffer
,
1006 NdisRequest
->DATA
.SET_INFORMATION
.InformationBufferLength
,
1007 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesRead
,
1008 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesNeeded
);
1012 NDIS_DbgPrint(MIN_TRACE
, ("Bad request type\n"));
1013 Status
= NDIS_STATUS_FAILURE
;
1018 Status
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CoRequestHandler
)(
1019 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1024 if (Status
!= NDIS_STATUS_PENDING
) {
1025 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1026 Adapter
->NdisMiniportBlock
.PendingRequest
= NULL
;
1027 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1030 KeLowerIrql(OldIrql
);
1038 #undef NdisMSetInformationComplete
1041 NdisMSetInformationComplete(
1042 IN NDIS_HANDLE MiniportAdapterHandle
,
1043 IN NDIS_STATUS Status
)
1045 PLOGICAL_ADAPTER Adapter
=
1046 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
1049 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1050 if (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)
1051 (Adapter
->NdisMiniportBlock
.SetCompleteHandler
)(MiniportAdapterHandle
, Status
);
1052 KeLowerIrql(OldIrql
);
1059 #undef NdisMQueryInformationComplete
1062 NdisMQueryInformationComplete(
1063 IN NDIS_HANDLE MiniportAdapterHandle
,
1064 IN NDIS_STATUS Status
)
1066 PLOGICAL_ADAPTER Adapter
=
1067 (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
1070 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1071 if( Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)
1072 (Adapter
->NdisMiniportBlock
.QueryCompleteHandler
)(MiniportAdapterHandle
, Status
);
1073 KeLowerIrql(OldIrql
);
1078 MiniportWorker(IN PDEVICE_OBJECT DeviceObject
, IN PVOID Context
)
1080 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
1081 KIRQL OldIrql
, RaiseOldIrql
;
1082 NDIS_STATUS NdisStatus
;
1083 PVOID WorkItemContext
;
1084 NDIS_WORK_ITEM_TYPE WorkItemType
;
1085 BOOLEAN AddressingReset
;
1087 IoFreeWorkItem((PIO_WORKITEM
)Context
);
1089 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1093 (Adapter
, &WorkItemType
, &WorkItemContext
);
1095 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1097 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1099 switch (WorkItemType
)
1101 case NdisWorkItemSend
:
1103 * called by ProSend when protocols want to send packets to the miniport
1106 if(Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)
1108 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1110 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1111 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1112 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1113 NdisStatus
= NDIS_STATUS_PENDING
;
1117 /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */
1118 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1120 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
1121 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
1122 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
1124 KeLowerIrql(RaiseOldIrql
);
1126 NdisStatus
= NDIS_GET_PACKET_STATUS((PNDIS_PACKET
)WorkItemContext
);
1127 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1128 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1135 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
1137 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1138 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1139 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1140 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1141 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1145 /* Send is called at DISPATCH_LEVEL for all serialized miniports */
1146 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
1147 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
1148 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
1149 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
,
1150 ((PNDIS_PACKET
)WorkItemContext
)->Private
.Flags
);
1151 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
1152 KeLowerIrql(RaiseOldIrql
);
1153 if( NdisStatus
== NDIS_STATUS_RESOURCES
) {
1154 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
, TRUE
);
1160 if( NdisStatus
!= NDIS_STATUS_PENDING
) {
1162 ( Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1166 case NdisWorkItemSendLoopback
:
1168 * called by ProSend when protocols want to send loopback packets
1170 /* XXX atm ProIndicatePacket sends a packet up via the loopback adapter only */
1171 NdisStatus
= ProIndicatePacket(Adapter
, (PNDIS_PACKET
)WorkItemContext
);
1173 if( NdisStatus
!= NDIS_STATUS_PENDING
)
1174 MiniSendComplete((NDIS_HANDLE
)Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
1177 case NdisWorkItemReturnPackets
:
1180 case NdisWorkItemResetRequested
:
1181 NdisMIndicateStatus(Adapter
, NDIS_STATUS_RESET_START
, NULL
, 0);
1182 NdisMIndicateStatusComplete(Adapter
);
1184 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1185 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.ResetHandler
)(
1186 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
1189 KeAcquireSpinLockAtDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1190 Adapter
->NdisMiniportBlock
.ResetStatus
= NdisStatus
;
1191 KeReleaseSpinLockFromDpcLevel(&Adapter
->NdisMiniportBlock
.Lock
);
1193 KeLowerIrql(OldIrql
);
1195 if (NdisStatus
!= NDIS_STATUS_PENDING
)
1196 MiniResetComplete(Adapter
, NdisStatus
, AddressingReset
);
1199 case NdisWorkItemResetInProgress
:
1202 case NdisWorkItemMiniportCallback
:
1205 case NdisWorkItemRequest
:
1206 NdisStatus
= MiniDoRequest(Adapter
, (PNDIS_REQUEST
)WorkItemContext
);
1208 if (NdisStatus
== NDIS_STATUS_PENDING
)
1211 switch (((PNDIS_REQUEST
)WorkItemContext
)->RequestType
)
1213 case NdisRequestQueryInformation
:
1214 NdisMQueryInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1217 case NdisRequestSetInformation
:
1218 NdisMSetInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
1222 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS request type.\n"));
1228 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS work item type (%d).\n", WorkItemType
));
1239 IN NDIS_HANDLE MiniportHandle
,
1240 IN NDIS_STATUS GeneralStatus
,
1241 IN PVOID StatusBuffer
,
1242 IN UINT StatusBufferSize
)
1244 PLOGICAL_ADAPTER Adapter
= MiniportHandle
;
1245 PLIST_ENTRY CurrentEntry
;
1246 PADAPTER_BINDING AdapterBinding
;
1249 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1251 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1253 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1255 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1257 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusHandler
)(
1258 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
1263 CurrentEntry
= CurrentEntry
->Flink
;
1266 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1273 IN NDIS_HANDLE MiniportAdapterHandle
)
1275 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1276 PLIST_ENTRY CurrentEntry
;
1277 PADAPTER_BINDING AdapterBinding
;
1280 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1282 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
1284 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
1286 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
1288 (*AdapterBinding
->ProtocolBinding
->Chars
.StatusCompleteHandler
)(
1289 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
);
1291 CurrentEntry
= CurrentEntry
->Flink
;
1294 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1304 IN NDIS_HANDLE LogHandle
)
1306 PNDIS_LOG Log
= (PNDIS_LOG
)LogHandle
;
1307 PNDIS_MINIPORT_BLOCK Miniport
= Log
->Miniport
;
1310 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1312 KeAcquireSpinLock(&(Miniport
)->Lock
, &OldIrql
);
1313 Miniport
->Log
= NULL
;
1314 KeReleaseSpinLock(&(Miniport
)->Lock
, OldIrql
);
1325 IN NDIS_HANDLE MiniportAdapterHandle
,
1327 OUT PNDIS_HANDLE LogHandle
)
1329 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
1333 NDIS_DbgPrint(MAX_TRACE
, ("called: MiniportAdapterHandle 0x%x, Size %ld\n", MiniportAdapterHandle
, Size
));
1335 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
1337 if (Adapter
->NdisMiniportBlock
.Log
)
1340 return NDIS_STATUS_FAILURE
;
1343 Log
= ExAllocatePool(NonPagedPool
, Size
+ sizeof(NDIS_LOG
));
1347 return NDIS_STATUS_RESOURCES
;
1350 Adapter
->NdisMiniportBlock
.Log
= Log
;
1352 KeInitializeSpinLock(&Log
->LogLock
);
1354 Log
->Miniport
= &Adapter
->NdisMiniportBlock
;
1355 Log
->TotalSize
= Size
;
1356 Log
->CurrentSize
= 0;
1363 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
1365 return NDIS_STATUS_SUCCESS
;
1373 NdisMDeregisterAdapterShutdownHandler(
1374 IN NDIS_HANDLE MiniportHandle
)
1376 * FUNCTION: de-registers a shutdown handler
1377 * ARGUMENTS: MiniportHandle: Handle passed into MiniportInitialize
1380 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1382 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1384 if(Adapter
->BugcheckContext
->ShutdownHandler
) {
1385 KeDeregisterBugCheckCallback(Adapter
->BugcheckContext
->CallbackRecord
);
1386 IoUnregisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1396 IN NDIS_HANDLE LogHandle
)
1398 PNDIS_LOG Log
= (PNDIS_LOG
) LogHandle
;
1401 NDIS_DbgPrint(MAX_TRACE
, ("called: LogHandle 0x%x\n", LogHandle
));
1404 KeAcquireSpinLock(&Log
->LogLock
, &OldIrql
);
1406 /* Set buffers size */
1407 Log
->CurrentSize
= 0;
1412 KeReleaseSpinLock(&Log
->LogLock
, OldIrql
);
1418 #undef NdisMIndicateStatus
1421 NdisMIndicateStatus(
1422 IN NDIS_HANDLE MiniportAdapterHandle
,
1423 IN NDIS_STATUS GeneralStatus
,
1424 IN PVOID StatusBuffer
,
1425 IN UINT StatusBufferSize
)
1427 MiniStatus(MiniportAdapterHandle
, GeneralStatus
, StatusBuffer
, StatusBufferSize
);
1433 #undef NdisMIndicateStatusComplete
1436 NdisMIndicateStatusComplete(
1437 IN NDIS_HANDLE MiniportAdapterHandle
)
1439 MiniStatusComplete(MiniportAdapterHandle
);
1448 NdisInitializeWrapper(
1449 OUT PNDIS_HANDLE NdisWrapperHandle
,
1450 IN PVOID SystemSpecific1
,
1451 IN PVOID SystemSpecific2
,
1452 IN PVOID SystemSpecific3
)
1454 * FUNCTION: Notifies the NDIS library that a new miniport is initializing
1456 * NdisWrapperHandle = Address of buffer to place NDIS wrapper handle
1457 * SystemSpecific1 = Pointer to the driver's driver object
1458 * SystemSpecific2 = Pointer to the driver's registry path
1459 * SystemSpecific3 = Always NULL
1461 * - SystemSpecific2 goes invalid so we copy it
1464 PNDIS_M_DRIVER_BLOCK Miniport
;
1465 PUNICODE_STRING RegistryPath
;
1466 WCHAR
*RegistryBuffer
;
1468 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1470 ASSERT(NdisWrapperHandle
);
1472 *NdisWrapperHandle
= NULL
;
1474 #if BREAK_ON_MINIPORT_INIT
1478 Miniport
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DRIVER_BLOCK
));
1482 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1486 RtlZeroMemory(Miniport
, sizeof(NDIS_M_DRIVER_BLOCK
));
1488 KeInitializeSpinLock(&Miniport
->Lock
);
1490 Miniport
->DriverObject
= (PDRIVER_OBJECT
)SystemSpecific1
;
1492 /* set the miniport's driver registry path */
1493 RegistryPath
= ExAllocatePool(PagedPool
, sizeof(UNICODE_STRING
));
1496 ExFreePool(Miniport
);
1497 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1501 RegistryPath
->Length
= ((PUNICODE_STRING
)SystemSpecific2
)->Length
;
1502 RegistryPath
->MaximumLength
= RegistryPath
->Length
+ sizeof(WCHAR
); /* room for 0-term */
1504 RegistryBuffer
= ExAllocatePool(PagedPool
, RegistryPath
->MaximumLength
);
1507 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1508 ExFreePool(Miniport
);
1509 ExFreePool(RegistryPath
);
1513 RtlCopyMemory(RegistryBuffer
, ((PUNICODE_STRING
)SystemSpecific2
)->Buffer
, RegistryPath
->Length
);
1514 RegistryBuffer
[RegistryPath
->Length
/sizeof(WCHAR
)] = 0;
1516 RegistryPath
->Buffer
= RegistryBuffer
;
1517 Miniport
->RegistryPath
= RegistryPath
;
1519 InitializeListHead(&Miniport
->DeviceList
);
1521 /* Put miniport in global miniport list */
1522 ExInterlockedInsertTailList(&MiniportListHead
, &Miniport
->ListEntry
, &MiniportListLock
);
1524 *NdisWrapperHandle
= Miniport
;
1528 VOID NTAPI
NdisIBugcheckCallback(
1532 * FUNCTION: Internal callback for handling bugchecks - calls adapter's shutdown handler
1534 * Buffer: Pointer to a bugcheck callback context
1538 PMINIPORT_BUGCHECK_CONTEXT Context
= (PMINIPORT_BUGCHECK_CONTEXT
)Buffer
;
1539 ADAPTER_SHUTDOWN_HANDLER sh
= (ADAPTER_SHUTDOWN_HANDLER
)Context
->ShutdownHandler
;
1541 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1544 sh(Context
->DriverContext
);
1553 NdisMRegisterAdapterShutdownHandler(
1554 IN NDIS_HANDLE MiniportHandle
,
1555 IN PVOID ShutdownContext
,
1556 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
1558 * FUNCTION: Register a shutdown handler for an adapter
1560 * MiniportHandle: Handle originally passed into MiniportInitialize
1561 * ShutdownContext: Pre-initialized bugcheck context
1562 * ShutdownHandler: Function to call to handle the bugcheck
1564 * - I'm not sure about ShutdownContext
1567 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1568 PMINIPORT_BUGCHECK_CONTEXT BugcheckContext
;
1570 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1572 BugcheckContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_BUGCHECK_CONTEXT
));
1573 if(!BugcheckContext
)
1575 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1579 BugcheckContext
->ShutdownHandler
= ShutdownHandler
;
1580 BugcheckContext
->DriverContext
= ShutdownContext
;
1582 BugcheckContext
->CallbackRecord
= ExAllocatePool(NonPagedPool
, sizeof(KBUGCHECK_CALLBACK_RECORD
));
1583 if (!BugcheckContext
->CallbackRecord
) {
1584 ExFreePool(BugcheckContext
);
1588 Adapter
->BugcheckContext
= BugcheckContext
;
1590 KeInitializeCallbackRecord(BugcheckContext
->CallbackRecord
);
1592 KeRegisterBugCheckCallback(BugcheckContext
->CallbackRecord
, NdisIBugcheckCallback
,
1593 BugcheckContext
, sizeof(BugcheckContext
), (PUCHAR
)"Ndis Miniport");
1595 IoRegisterShutdownNotification(Adapter
->NdisMiniportBlock
.DeviceObject
);
1601 PLOGICAL_ADAPTER Adapter
,
1602 NDIS_OID AddressOID
)
1604 * FUNCTION: Queries miniport for information
1606 * Adapter = Pointer to logical adapter
1607 * AddressOID = OID to use to query for current address
1609 * Status of operation
1613 NDIS_STATUS NdisStatus
;
1615 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1617 /* Get MAC options for adapter */
1618 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAC_OPTIONS
, sizeof(UINT
),
1619 &Adapter
->NdisMiniportBlock
.MacOptions
,
1622 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1624 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAC_OPTIONS failed. NdisStatus (0x%X).\n", NdisStatus
));
1628 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MacOptions (0x%X).\n", Adapter
->NdisMiniportBlock
.MacOptions
));
1630 /* Get current hardware address of adapter */
1631 NdisStatus
= MiniQueryInformation(Adapter
, AddressOID
, Adapter
->AddressLength
,
1632 &Adapter
->Address
, &BytesWritten
);
1634 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1636 NDIS_DbgPrint(MIN_TRACE
, ("Address OID (0x%X) failed. NdisStatus (0x%X).\n", AddressOID
, NdisStatus
));
1644 PUCHAR A
= (PUCHAR
)&Adapter
->Address
.Type
.Medium802_3
;
1646 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]));
1650 /* Get maximum lookahead buffer size of adapter */
1651 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_LOOKAHEAD
, sizeof(ULONG
),
1652 &Adapter
->NdisMiniportBlock
.MaximumLookahead
, &BytesWritten
);
1654 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1656 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1660 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MaxLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.MaximumLookahead
));
1662 /* Get current lookahead buffer size of adapter */
1663 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_CURRENT_LOOKAHEAD
, sizeof(ULONG
),
1664 &Adapter
->NdisMiniportBlock
.CurrentLookahead
, &BytesWritten
);
1666 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1668 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_CURRENT_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1672 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_SEND_PACKETS
, sizeof(ULONG
),
1673 &Adapter
->NdisMiniportBlock
.MaxSendPackets
, &BytesWritten
);
1675 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1677 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_SEND_PACKETS failed. NdisStatus (0x%X).\n", NdisStatus
));
1679 /* Set it to 1 if it fails because some drivers don't support this (?)*/
1680 Adapter
->NdisMiniportBlock
.MaxSendPackets
= 1;
1683 NDIS_DbgPrint(DEBUG_MINIPORT
, ("CurLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.CurrentLookahead
));
1685 return STATUS_SUCCESS
;
1691 NdisIForwardIrpAndWaitCompletionRoutine(
1696 PKEVENT Event
= Context
;
1698 if (Irp
->PendingReturned
)
1699 KeSetEvent(Event
, IO_NO_INCREMENT
, FALSE
);
1701 return STATUS_MORE_PROCESSING_REQUIRED
;
1707 NdisIForwardIrpAndWait(PLOGICAL_ADAPTER Adapter
, PIRP Irp
)
1712 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1713 IoCopyCurrentIrpStackLocationToNext(Irp
);
1714 IoSetCompletionRoutine(Irp
, NdisIForwardIrpAndWaitCompletionRoutine
, &Event
,
1716 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
1717 if (Status
== STATUS_PENDING
)
1719 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1720 Status
= Irp
->IoStatus
.Status
;
1728 IN PDEVICE_OBJECT DeviceObject
,
1731 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
1732 Irp
->IoStatus
.Information
= 0;
1734 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1736 return STATUS_SUCCESS
;
1742 NdisIPnPStartDevice(
1743 IN PDEVICE_OBJECT DeviceObject
,
1746 * FUNCTION: Handle the PnP start device event
1748 * DeviceObejct = Functional Device Object
1749 * Irp = IRP_MN_START_DEVICE I/O request packet
1751 * Status of operation
1754 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
1755 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1756 NDIS_WRAPPER_CONTEXT WrapperContext
;
1757 NDIS_STATUS NdisStatus
;
1758 NDIS_STATUS OpenErrorStatus
;
1760 UINT SelectedMediumIndex
= 0;
1761 NDIS_OID AddressOID
;
1762 BOOLEAN Success
= FALSE
;
1763 ULONG ResourceCount
;
1764 ULONG ResourceListSize
;
1765 UNICODE_STRING ParamName
;
1766 PNDIS_CONFIGURATION_PARAMETER ConfigParam
;
1767 NDIS_HANDLE ConfigHandle
;
1769 LARGE_INTEGER Timeout
;
1770 UINT MaxMulticastAddresses
;
1774 * Prepare wrapper context used by HW and configuration routines.
1777 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Start Device %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
1779 NDIS_DbgPrint(MAX_TRACE
, ("Inserting adapter 0x%x into adapter list\n", Adapter
));
1781 /* Put adapter in global adapter list */
1782 ExInterlockedInsertTailList(&AdapterListHead
, &Adapter
->ListEntry
, &AdapterListLock
);
1784 Status
= IoOpenDeviceRegistryKey(
1785 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
, PLUGPLAY_REGKEY_DRIVER
,
1786 KEY_ALL_ACCESS
, &WrapperContext
.RegistryHandle
);
1787 if (!NT_SUCCESS(Status
))
1789 NDIS_DbgPrint(MIN_TRACE
,("failed to open adapter-specific reg key\n"));
1790 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1794 NDIS_DbgPrint(MAX_TRACE
, ("opened device reg key\n"));
1796 WrapperContext
.DeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
1799 * Store the adapter resources used by HW routines such as
1800 * NdisMQueryAdapterResources.
1803 if (Stack
->Parameters
.StartDevice
.AllocatedResources
!= NULL
)
1805 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResources
->List
[0].
1806 PartialResourceList
.Count
;
1808 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1809 PartialDescriptors
[ResourceCount
]);
1811 Adapter
->NdisMiniportBlock
.AllocatedResources
=
1812 ExAllocatePool(PagedPool
, ResourceListSize
);
1813 if (Adapter
->NdisMiniportBlock
.AllocatedResources
== NULL
)
1815 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1816 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1817 return STATUS_INSUFFICIENT_RESOURCES
;
1820 Adapter
->NdisMiniportBlock
.Resources
=
1821 ExAllocatePool(PagedPool
, ResourceListSize
);
1822 if (!Adapter
->NdisMiniportBlock
.Resources
)
1824 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1825 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
1826 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
1827 return STATUS_INSUFFICIENT_RESOURCES
;
1830 RtlCopyMemory(Adapter
->NdisMiniportBlock
.Resources
,
1831 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1834 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResources
,
1835 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1839 if (Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
!= NULL
)
1841 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
->List
[0].
1842 PartialResourceList
.Count
;
1844 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1845 PartialDescriptors
[ResourceCount
]);
1847 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
=
1848 ExAllocatePool(PagedPool
, ResourceListSize
);
1849 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
== NULL
)
1851 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
1852 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1853 return STATUS_INSUFFICIENT_RESOURCES
;
1856 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
,
1857 Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
,
1862 * Store the Bus Type, Bus Number and Slot information. It's used by
1863 * the hardware routines then.
1866 NdisOpenConfiguration(&NdisStatus
, &ConfigHandle
, (NDIS_HANDLE
)&WrapperContext
);
1867 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1869 NDIS_DbgPrint(MIN_TRACE
, ("Failed to open configuration key\n"));
1870 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1874 Size
= sizeof(ULONG
);
1875 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1876 DevicePropertyLegacyBusType
, Size
,
1877 &Adapter
->NdisMiniportBlock
.BusType
, &Size
);
1878 if (!NT_SUCCESS(Status
) || (INTERFACE_TYPE
)Adapter
->NdisMiniportBlock
.BusType
== InterfaceTypeUndefined
)
1880 NdisInitUnicodeString(&ParamName
, L
"BusType");
1881 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1882 &ParamName
, NdisParameterInteger
);
1883 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1884 Adapter
->NdisMiniportBlock
.BusType
= ConfigParam
->ParameterData
.IntegerData
;
1886 Adapter
->NdisMiniportBlock
.BusType
= Isa
;
1889 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1890 DevicePropertyBusNumber
, Size
,
1891 &Adapter
->NdisMiniportBlock
.BusNumber
, &Size
);
1892 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.BusNumber
== 0xFFFFFFF0)
1894 NdisInitUnicodeString(&ParamName
, L
"BusNumber");
1895 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1896 &ParamName
, NdisParameterInteger
);
1897 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1898 Adapter
->NdisMiniportBlock
.BusNumber
= ConfigParam
->ParameterData
.IntegerData
;
1900 Adapter
->NdisMiniportBlock
.BusNumber
= 0;
1902 WrapperContext
.BusNumber
= Adapter
->NdisMiniportBlock
.BusNumber
;
1904 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1905 DevicePropertyAddress
, Size
,
1906 &Adapter
->NdisMiniportBlock
.SlotNumber
, &Size
);
1907 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.SlotNumber
== (NDIS_INTERFACE_TYPE
)-1)
1909 NdisInitUnicodeString(&ParamName
, L
"SlotNumber");
1910 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1911 &ParamName
, NdisParameterInteger
);
1912 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1913 Adapter
->NdisMiniportBlock
.SlotNumber
= ConfigParam
->ParameterData
.IntegerData
;
1915 Adapter
->NdisMiniportBlock
.SlotNumber
= 0;
1919 /* Convert slotnumber to PCI_SLOT_NUMBER */
1920 ULONG PciSlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
1921 PCI_SLOT_NUMBER SlotNumber
;
1923 SlotNumber
.u
.AsULONG
= 0;
1924 SlotNumber
.u
.bits
.DeviceNumber
= (PciSlotNumber
>> 16) & 0xFFFF;
1925 SlotNumber
.u
.bits
.FunctionNumber
= PciSlotNumber
& 0xFFFF;
1927 Adapter
->NdisMiniportBlock
.SlotNumber
= SlotNumber
.u
.AsULONG
;
1929 WrapperContext
.SlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
1931 NdisCloseConfiguration(ConfigHandle
);
1933 /* Set handlers (some NDIS macros require these) */
1934 Adapter
->NdisMiniportBlock
.EthRxCompleteHandler
= EthFilterDprIndicateReceiveComplete
;
1935 Adapter
->NdisMiniportBlock
.EthRxIndicateHandler
= EthFilterDprIndicateReceive
;
1936 Adapter
->NdisMiniportBlock
.SendCompleteHandler
= MiniSendComplete
;
1937 Adapter
->NdisMiniportBlock
.SendResourcesHandler
= MiniSendResourcesAvailable
;
1938 Adapter
->NdisMiniportBlock
.ResetCompleteHandler
= MiniResetComplete
;
1939 Adapter
->NdisMiniportBlock
.TDCompleteHandler
= MiniTransferDataComplete
;
1940 Adapter
->NdisMiniportBlock
.PacketIndicateHandler
= MiniIndicateReceivePacket
;
1941 Adapter
->NdisMiniportBlock
.StatusHandler
= MiniStatus
;
1942 Adapter
->NdisMiniportBlock
.StatusCompleteHandler
= MiniStatusComplete
;
1943 Adapter
->NdisMiniportBlock
.SendPacketsHandler
= ProSendPackets
;
1944 Adapter
->NdisMiniportBlock
.QueryCompleteHandler
= MiniRequestComplete
;
1945 Adapter
->NdisMiniportBlock
.SetCompleteHandler
= MiniRequestComplete
;
1948 * Call MiniportInitialize.
1951 NDIS_DbgPrint(MID_TRACE
, ("calling MiniportInitialize\n"));
1952 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.InitializeHandler
)(
1953 &OpenErrorStatus
, &SelectedMediumIndex
, &MediaArray
[0],
1954 MEDIA_ARRAY_SIZE
, Adapter
, (NDIS_HANDLE
)&WrapperContext
);
1956 ZwClose(WrapperContext
.RegistryHandle
);
1958 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1960 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() failed for an adapter.\n"));
1961 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1965 if (SelectedMediumIndex
>= MEDIA_ARRAY_SIZE
)
1967 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() selected a bad index\n"));
1968 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1969 return NDIS_STATUS_UNSUPPORTED_MEDIA
;
1972 Adapter
->NdisMiniportBlock
.MediaType
= MediaArray
[SelectedMediumIndex
];
1974 switch (Adapter
->NdisMiniportBlock
.MediaType
)
1976 case NdisMedium802_3
:
1977 Adapter
->MediumHeaderSize
= 14; /* XXX figure out what to do about LLC */
1978 AddressOID
= OID_802_3_CURRENT_ADDRESS
;
1979 Adapter
->AddressLength
= ETH_LENGTH_OF_ADDRESS
;
1980 NdisStatus
= DoQueries(Adapter
, AddressOID
);
1981 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1983 NdisStatus
= MiniQueryInformation(Adapter
, OID_802_3_MAXIMUM_LIST_SIZE
, sizeof(UINT
),
1984 &MaxMulticastAddresses
, &BytesWritten
);
1986 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1988 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1989 NDIS_DbgPrint(MIN_TRACE
, ("MiniQueryInformation failed (%x)\n", NdisStatus
));
1993 Success
= EthCreateFilter(MaxMulticastAddresses
,
1994 Adapter
->Address
.Type
.Medium802_3
,
1995 &Adapter
->NdisMiniportBlock
.EthDB
);
1997 ((PETHI_FILTER
)Adapter
->NdisMiniportBlock
.EthDB
)->Miniport
= (PNDIS_MINIPORT_BLOCK
)Adapter
;
1999 NdisStatus
= NDIS_STATUS_RESOURCES
;
2004 /* FIXME: Support other types of media */
2005 NDIS_DbgPrint(MIN_TRACE
, ("error: unsupported media\n"));
2007 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
2008 return STATUS_UNSUCCESSFUL
;
2011 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
2013 NDIS_DbgPrint(MIN_TRACE
, ("couldn't create filter (%x)\n", NdisStatus
));
2017 /* Check for a hang every two seconds if it wasn't set in MiniportInitialize */
2018 if (Adapter
->NdisMiniportBlock
.CheckForHangSeconds
== 0)
2019 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= 2;
2021 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
2022 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStarted
;
2024 IoSetDeviceInterfaceState(&Adapter
->NdisMiniportBlock
.SymbolicLinkName
, TRUE
);
2026 Timeout
.QuadPart
= Int32x32To64(Adapter
->NdisMiniportBlock
.CheckForHangSeconds
, -1000000);
2027 KeSetTimerEx(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
, Timeout
,
2028 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
* 1000,
2029 &Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
);
2031 /* Put adapter in adapter list for this miniport */
2032 ExInterlockedInsertTailList(&Adapter
->NdisMiniportBlock
.DriverHandle
->DeviceList
, &Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
2034 return STATUS_SUCCESS
;
2041 IN PDEVICE_OBJECT DeviceObject
,
2044 * FUNCTION: Handle the PnP stop device event
2046 * DeviceObejct = Functional Device Object
2047 * Irp = IRP_MN_STOP_DEVICE I/O request packet
2049 * Status of operation
2052 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2054 /* Remove adapter from adapter list for this miniport */
2055 ExInterlockedRemoveEntryList(&Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
2057 /* Remove adapter from global adapter list */
2058 ExInterlockedRemoveEntryList(&Adapter
->ListEntry
, &AdapterListLock
);
2060 KeCancelTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
2062 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.HaltHandler
)(Adapter
);
2064 IoSetDeviceInterfaceState(&Adapter
->NdisMiniportBlock
.SymbolicLinkName
, FALSE
);
2066 if (Adapter
->NdisMiniportBlock
.AllocatedResources
)
2068 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
2069 Adapter
->NdisMiniportBlock
.AllocatedResources
= NULL
;
2071 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
)
2073 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
);
2074 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
= NULL
;
2077 if (Adapter
->NdisMiniportBlock
.Resources
)
2079 ExFreePool(Adapter
->NdisMiniportBlock
.Resources
);
2080 Adapter
->NdisMiniportBlock
.Resources
= NULL
;
2083 if (Adapter
->NdisMiniportBlock
.EthDB
)
2085 EthDeleteFilter(Adapter
->NdisMiniportBlock
.EthDB
);
2086 Adapter
->NdisMiniportBlock
.EthDB
= NULL
;
2089 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
2090 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStopped
;
2092 return STATUS_SUCCESS
;
2098 IN PDEVICE_OBJECT DeviceObject
,
2101 PLOGICAL_ADAPTER Adapter
= DeviceObject
->DeviceExtension
;
2102 PMINIPORT_BUGCHECK_CONTEXT Context
= Adapter
->BugcheckContext
;
2103 ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
= Context
->ShutdownHandler
;
2105 ASSERT(ShutdownHandler
);
2107 ShutdownHandler(Context
->DriverContext
);
2109 Irp
->IoStatus
.Status
= STATUS_SUCCESS
;
2110 Irp
->IoStatus
.Information
= 0;
2112 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2114 return STATUS_SUCCESS
;
2119 NdisIDeviceIoControl(
2120 IN PDEVICE_OBJECT DeviceObject
,
2123 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2124 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2125 NDIS_STATUS Status
= STATUS_NOT_SUPPORTED
;
2128 Irp
->IoStatus
.Information
= 0;
2132 switch (Stack
->Parameters
.DeviceIoControl
.IoControlCode
)
2134 case IOCTL_NDIS_QUERY_GLOBAL_STATS
:
2135 Status
= MiniQueryInformation(Adapter
,
2136 *(PNDIS_OID
)Irp
->AssociatedIrp
.SystemBuffer
,
2137 Stack
->Parameters
.DeviceIoControl
.OutputBufferLength
,
2138 MmGetSystemAddressForMdl(Irp
->MdlAddress
),
2140 Irp
->IoStatus
.Information
= Written
;
2148 if (Status
!= NDIS_STATUS_PENDING
)
2150 Irp
->IoStatus
.Status
= Status
;
2151 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2154 IoMarkIrpPending(Irp
);
2163 IN PDEVICE_OBJECT DeviceObject
,
2166 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
2167 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2170 switch (Stack
->MinorFunction
)
2172 case IRP_MN_START_DEVICE
:
2173 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2174 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2176 Status
= NdisIPnPStartDevice(DeviceObject
, Irp
);
2179 NDIS_DbgPrint(MIN_TRACE
, ("Lower driver failed device start\n"));
2180 Irp
->IoStatus
.Status
= Status
;
2181 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2184 case IRP_MN_STOP_DEVICE
:
2185 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
2186 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
2188 Status
= NdisIPnPStopDevice(DeviceObject
, Irp
);
2191 NDIS_DbgPrint(MIN_TRACE
, ("Lower driver failed device stop\n"));
2192 Irp
->IoStatus
.Status
= Status
;
2193 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2196 case IRP_MN_QUERY_REMOVE_DEVICE
:
2197 case IRP_MN_QUERY_STOP_DEVICE
:
2198 Status
= NdisIPnPQueryStopDevice(DeviceObject
, Irp
);
2199 Irp
->IoStatus
.Status
= Status
;
2200 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2203 case IRP_MN_CANCEL_REMOVE_DEVICE
:
2204 case IRP_MN_CANCEL_STOP_DEVICE
:
2205 Status
= NdisIPnPCancelStopDevice(DeviceObject
, Irp
);
2206 Irp
->IoStatus
.Status
= Status
;
2207 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2210 case IRP_MN_QUERY_PNP_DEVICE_STATE
:
2211 Status
= NDIS_STATUS_SUCCESS
;
2212 Irp
->IoStatus
.Status
= Status
;
2213 Irp
->IoStatus
.Information
|= Adapter
->NdisMiniportBlock
.PnPFlags
;
2214 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
2218 IoSkipCurrentIrpStackLocation(Irp
);
2219 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
2230 IN PDRIVER_OBJECT DriverObject
,
2231 IN PDEVICE_OBJECT PhysicalDeviceObject
)
2233 * FUNCTION: Create a device for an adapter found using PnP
2235 * DriverObject = Pointer to the miniport driver object
2236 * PhysicalDeviceObject = Pointer to the PDO for our adapter
2239 static const WCHAR ClassKeyName
[] = {'C','l','a','s','s','\\'};
2240 static const WCHAR LinkageKeyName
[] = {'\\','L','i','n','k','a','g','e',0};
2241 PNDIS_M_DRIVER_BLOCK Miniport
;
2242 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2243 WCHAR
*LinkageKeyBuffer
;
2244 ULONG DriverKeyLength
;
2245 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
2246 UNICODE_STRING ExportName
;
2247 PDEVICE_OBJECT DeviceObject
;
2248 PLOGICAL_ADAPTER Adapter
;
2252 * Gain the access to the miniport data structure first.
2255 MiniportPtr
= IoGetDriverObjectExtension(DriverObject
, (PVOID
)'NMID');
2256 if (MiniportPtr
== NULL
)
2258 NDIS_DbgPrint(MIN_TRACE
, ("Can't get driver object extension.\n"));
2259 return NDIS_STATUS_FAILURE
;
2261 Miniport
= *MiniportPtr
;
2264 * Get name of the Linkage registry key for our adapter. It's located under
2265 * the driver key for our driver and so we have basicly two ways to do it.
2266 * Either we can use IoOpenDriverRegistryKey or compose it using information
2267 * gathered by IoGetDeviceProperty. I choosed the second because
2268 * IoOpenDriverRegistryKey wasn't implemented at the time of writing.
2271 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2272 0, NULL
, &DriverKeyLength
);
2273 if (Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
&& Status
!= STATUS_SUCCESS
)
2275 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport driver key length.\n"));
2279 LinkageKeyBuffer
= ExAllocatePool(PagedPool
, DriverKeyLength
+
2280 sizeof(ClassKeyName
) + sizeof(LinkageKeyName
));
2281 if (LinkageKeyBuffer
== NULL
)
2283 NDIS_DbgPrint(MIN_TRACE
, ("Can't allocate memory for driver key name.\n"));
2284 return STATUS_INSUFFICIENT_RESOURCES
;
2287 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
2288 DriverKeyLength
, LinkageKeyBuffer
+
2289 (sizeof(ClassKeyName
) / sizeof(WCHAR
)),
2291 if (!NT_SUCCESS(Status
))
2293 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport driver key.\n"));
2294 ExFreePool(LinkageKeyBuffer
);
2298 /* Compose the linkage key name. */
2299 RtlCopyMemory(LinkageKeyBuffer
, ClassKeyName
, sizeof(ClassKeyName
));
2300 RtlCopyMemory(LinkageKeyBuffer
+ ((sizeof(ClassKeyName
) + DriverKeyLength
) /
2301 sizeof(WCHAR
)) - 1, LinkageKeyName
, sizeof(LinkageKeyName
));
2303 NDIS_DbgPrint(DEBUG_MINIPORT
, ("LinkageKey: %S.\n", LinkageKeyBuffer
));
2306 * Now open the linkage key and read the "Export" and "RootDevice" values
2307 * which contains device name and root service respectively.
2310 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
2311 RtlInitUnicodeString(&ExportName
, NULL
);
2312 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
| RTL_QUERY_REGISTRY_DIRECT
;
2313 QueryTable
[0].Name
= L
"Export";
2314 QueryTable
[0].EntryContext
= &ExportName
;
2316 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
, LinkageKeyBuffer
,
2317 QueryTable
, NULL
, NULL
);
2318 ExFreePool(LinkageKeyBuffer
);
2319 if (!NT_SUCCESS(Status
))
2321 NDIS_DbgPrint(MIN_TRACE
, ("Can't get miniport device name. (%x)\n", Status
));
2326 * Create the device object.
2329 NDIS_DbgPrint(MAX_TRACE
, ("creating device %wZ\n", &ExportName
));
2331 Status
= IoCreateDevice(Miniport
->DriverObject
, sizeof(LOGICAL_ADAPTER
),
2332 &ExportName
, FILE_DEVICE_PHYSICAL_NETCARD
,
2333 0, FALSE
, &DeviceObject
);
2334 if (!NT_SUCCESS(Status
))
2336 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device object.\n"));
2337 RtlFreeUnicodeString(&ExportName
);
2342 * Initialize the adapter structure.
2345 Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
2346 KeInitializeSpinLock(&Adapter
->NdisMiniportBlock
.Lock
);
2347 InitializeListHead(&Adapter
->ProtocolListHead
);
2349 Status
= IoRegisterDeviceInterface(PhysicalDeviceObject
,
2350 &GUID_DEVINTERFACE_NET
,
2352 &Adapter
->NdisMiniportBlock
.SymbolicLinkName
);
2354 if (!NT_SUCCESS(Status
))
2356 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device interface.\n"));
2357 IoDeleteDevice(DeviceObject
);
2358 RtlFreeUnicodeString(&ExportName
);
2362 Adapter
->NdisMiniportBlock
.DriverHandle
= Miniport
;
2363 Adapter
->NdisMiniportBlock
.MiniportName
= ExportName
;
2364 Adapter
->NdisMiniportBlock
.DeviceObject
= DeviceObject
;
2365 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
= PhysicalDeviceObject
;
2366 Adapter
->NdisMiniportBlock
.NextDeviceObject
=
2367 IoAttachDeviceToDeviceStack(Adapter
->NdisMiniportBlock
.DeviceObject
,
2368 PhysicalDeviceObject
);
2370 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= 0;
2371 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceAdded
;
2373 KeInitializeTimer(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Timer
);
2374 KeInitializeDpc(&Adapter
->NdisMiniportBlock
.WakeUpDpcTimer
.Dpc
, MiniportHangDpc
, Adapter
);
2376 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
2378 return STATUS_SUCCESS
;
2387 NdisMRegisterMiniport(
2388 IN NDIS_HANDLE NdisWrapperHandle
,
2389 IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics
,
2390 IN UINT CharacteristicsLength
)
2392 * FUNCTION: Registers a miniport's MiniportXxx entry points with the NDIS library
2394 * NdisWrapperHandle = Pointer to handle returned by NdisMInitializeWrapper
2395 * MiniportCharacteristics = Pointer to a buffer with miniport characteristics
2396 * CharacteristicsLength = Number of bytes in characteristics buffer
2398 * Status of operation
2402 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2403 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
2406 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2408 switch (MiniportCharacteristics
->MajorNdisVersion
)
2411 MinSize
= sizeof(NDIS30_MINIPORT_CHARACTERISTICS
);
2415 MinSize
= sizeof(NDIS40_MINIPORT_CHARACTERISTICS
);
2419 MinSize
= sizeof(NDIS50_MINIPORT_CHARACTERISTICS
);
2423 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics version.\n"));
2424 return NDIS_STATUS_BAD_VERSION
;
2427 NDIS_DbgPrint(MIN_TRACE
, ("Initializing an NDIS %u.%u miniport\n",
2428 MiniportCharacteristics
->MajorNdisVersion
,
2429 MiniportCharacteristics
->MinorNdisVersion
));
2431 if (CharacteristicsLength
< MinSize
)
2433 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics length.\n"));
2434 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2437 /* Check if mandatory MiniportXxx functions are specified */
2438 if ((!MiniportCharacteristics
->HaltHandler
) ||
2439 (!MiniportCharacteristics
->InitializeHandler
)||
2440 (!MiniportCharacteristics
->ResetHandler
))
2442 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics.\n"));
2443 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2446 if (MiniportCharacteristics
->MajorNdisVersion
< 0x05)
2448 if ((!MiniportCharacteristics
->QueryInformationHandler
) ||
2449 (!MiniportCharacteristics
->SetInformationHandler
))
2451 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (Set/Query)\n"));
2452 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2457 if (((!MiniportCharacteristics
->QueryInformationHandler
) ||
2458 (!MiniportCharacteristics
->SetInformationHandler
)) &&
2459 (!MiniportCharacteristics
->CoRequestHandler
))
2461 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (Set/Query)\n"));
2462 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2466 if (MiniportCharacteristics
->MajorNdisVersion
== 0x03)
2468 if (!MiniportCharacteristics
->SendHandler
)
2470 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 3.0)\n"));
2471 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2474 else if (MiniportCharacteristics
->MajorNdisVersion
== 0x04)
2477 if ((!MiniportCharacteristics
->SendHandler
) &&
2478 (!MiniportCharacteristics
->SendPacketsHandler
))
2480 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 4.0)\n"));
2481 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2484 else if (MiniportCharacteristics
->MajorNdisVersion
== 0x05)
2486 /* TODO: Add more checks here */
2488 if ((!MiniportCharacteristics
->SendHandler
) &&
2489 (!MiniportCharacteristics
->SendPacketsHandler
) &&
2490 (!MiniportCharacteristics
->CoSendPacketsHandler
))
2492 NDIS_DbgPrint(MIN_TRACE
, ("Bad miniport characteristics. (NDIS 5.0)\n"));
2493 return NDIS_STATUS_BAD_CHARACTERISTICS
;
2497 /* TODO: verify NDIS5 and NDIS5.1 */
2499 RtlCopyMemory(&Miniport
->MiniportCharacteristics
, MiniportCharacteristics
, MinSize
);
2502 * NOTE: This is VERY unoptimal! Should we store the NDIS_M_DRIVER_BLOCK
2503 * structure in the driver extension or what?
2506 Status
= IoAllocateDriverObjectExtension(Miniport
->DriverObject
, (PVOID
)'NMID',
2507 sizeof(PNDIS_M_DRIVER_BLOCK
), (PVOID
*)&MiniportPtr
);
2508 if (!NT_SUCCESS(Status
))
2510 NDIS_DbgPrint(MIN_TRACE
, ("Can't allocate driver object extension.\n"));
2511 return NDIS_STATUS_RESOURCES
;
2514 *MiniportPtr
= Miniport
;
2516 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = NdisICreateClose
;
2517 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = NdisICreateClose
;
2518 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_PNP
] = NdisIDispatchPnp
;
2519 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_SHUTDOWN
] = NdisIShutdown
;
2520 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_DEVICE_CONTROL
] = NdisIDeviceIoControl
;
2521 Miniport
->DriverObject
->DriverExtension
->AddDevice
= NdisIAddDevice
;
2523 return NDIS_STATUS_SUCCESS
;
2530 #undef NdisMResetComplete
2534 IN NDIS_HANDLE MiniportAdapterHandle
,
2535 IN NDIS_STATUS Status
,
2536 IN BOOLEAN AddressingReset
)
2538 MiniResetComplete(MiniportAdapterHandle
, Status
, AddressingReset
);
2545 #undef NdisMSendComplete
2549 IN NDIS_HANDLE MiniportAdapterHandle
,
2550 IN PNDIS_PACKET Packet
,
2551 IN NDIS_STATUS Status
)
2553 * FUNCTION: Forwards a message to the initiating protocol saying
2554 * that a packet was handled
2556 * NdisAdapterHandle = Handle input to MiniportInitialize
2557 * Packet = Pointer to NDIS packet that was sent
2558 * Status = Status of send operation
2561 MiniSendComplete(MiniportAdapterHandle
, Packet
, Status
);
2568 #undef NdisMSendResourcesAvailable
2571 NdisMSendResourcesAvailable(
2572 IN NDIS_HANDLE MiniportAdapterHandle
)
2574 MiniSendResourcesAvailable(MiniportAdapterHandle
);
2581 #undef NdisMTransferDataComplete
2584 NdisMTransferDataComplete(
2585 IN NDIS_HANDLE MiniportAdapterHandle
,
2586 IN PNDIS_PACKET Packet
,
2587 IN NDIS_STATUS Status
,
2588 IN UINT BytesTransferred
)
2590 MiniTransferDataComplete(MiniportAdapterHandle
, Packet
, Status
, BytesTransferred
);
2597 #undef NdisMSetAttributes
2601 IN NDIS_HANDLE MiniportAdapterHandle
,
2602 IN NDIS_HANDLE MiniportAdapterContext
,
2603 IN BOOLEAN BusMaster
,
2604 IN NDIS_INTERFACE_TYPE AdapterType
)
2606 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2608 * MiniportAdapterHandle = Handle input to MiniportInitialize
2609 * MiniportAdapterContext = Pointer to context information
2610 * BusMaster = Specifies TRUE if the caller's NIC is a busmaster DMA device
2611 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2614 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2615 NdisMSetAttributesEx(MiniportAdapterHandle
, MiniportAdapterContext
, 0,
2616 BusMaster
? NDIS_ATTRIBUTE_BUS_MASTER
: 0,
2626 NdisMSetAttributesEx(
2627 IN NDIS_HANDLE MiniportAdapterHandle
,
2628 IN NDIS_HANDLE MiniportAdapterContext
,
2629 IN UINT CheckForHangTimeInSeconds OPTIONAL
,
2630 IN ULONG AttributeFlags
,
2631 IN NDIS_INTERFACE_TYPE AdapterType
)
2633 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2635 * MiniportAdapterHandle = Handle input to MiniportInitialize
2636 * MiniportAdapterContext = Pointer to context information
2637 * CheckForHangTimeInSeconds = Specifies interval in seconds at which
2638 * MiniportCheckForHang should be called
2639 * AttributeFlags = Bitmask that indicates specific attributes
2640 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2643 PLOGICAL_ADAPTER Adapter
= GET_LOGICAL_ADAPTER(MiniportAdapterHandle
);
2645 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2647 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
= MiniportAdapterContext
;
2648 Adapter
->NdisMiniportBlock
.Flags
= AttributeFlags
;
2649 Adapter
->NdisMiniportBlock
.AdapterType
= AdapterType
;
2650 if (CheckForHangTimeInSeconds
> 0)
2651 Adapter
->NdisMiniportBlock
.CheckForHangSeconds
= CheckForHangTimeInSeconds
;
2652 if (AttributeFlags
& NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER
)
2653 NDIS_DbgPrint(MAX_TRACE
, ("Intermediate drivers not supported yet.\n"));
2656 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.AdapterShutdownHandler
)
2658 NDIS_DbgPrint(MAX_TRACE
, ("Miniport set AdapterShutdownHandler in MiniportCharacteristics\n"));
2659 NdisMRegisterAdapterShutdownHandler(Adapter
,
2660 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
2661 Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.AdapterShutdownHandler
);
2672 IN ULONG MicrosecondsToSleep
)
2674 * FUNCTION: delay the thread's execution for MicrosecondsToSleep
2676 * MicrosecondsToSleep: duh...
2678 * - Because this is a blocking call, current IRQL must be < DISPATCH_LEVEL
2682 LARGE_INTEGER DueTime
;
2686 DueTime
.QuadPart
= (-1) * 10 * MicrosecondsToSleep
;
2688 KeInitializeTimer(&Timer
);
2689 KeSetTimer(&Timer
, DueTime
, 0);
2690 KeWaitForSingleObject(&Timer
, Executive
, KernelMode
, FALSE
, 0);
2699 NdisMSynchronizeWithInterrupt(
2700 IN PNDIS_MINIPORT_INTERRUPT Interrupt
,
2701 IN PVOID SynchronizeFunction
,
2702 IN PVOID SynchronizeContext
)
2704 return(KeSynchronizeExecution(Interrupt
->InterruptObject
,
2705 (PKSYNCHRONIZE_ROUTINE
)SynchronizeFunction
,
2706 SynchronizeContext
));
2716 IN NDIS_HANDLE LogHandle
,
2718 IN UINT LogBufferSize
)
2720 PUCHAR Buffer
= LogBuffer
;
2724 for (i
= 0; i
< LogBufferSize
; i
+= 16)
2726 DbgPrint("%08x |", i
);
2727 for (j
= 0; j
< 16; j
++)
2730 if (idx
< LogBufferSize
)
2731 DbgPrint(" %02x", Buffer
[idx
]);
2736 for (j
= 0; j
< 16; j
++)
2739 if (idx
== LogBufferSize
)
2741 if (Buffer
[idx
] >= ' ') /* FIXME: not portable! replace by if (isprint(Buffer[idx])) ? */
2742 DbgPrint("%c", Buffer
[idx
]);
2749 return NDIS_STATUS_FAILURE
;
2758 NdisTerminateWrapper(
2759 IN NDIS_HANDLE NdisWrapperHandle
,
2760 IN PVOID SystemSpecific
)
2762 * FUNCTION: Releases resources allocated by a call to NdisInitializeWrapper
2764 * NdisWrapperHandle = Handle returned by NdisInitializeWrapper (NDIS_M_DRIVER_BLOCK)
2765 * SystemSpecific = Always NULL
2768 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2770 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2772 ExFreePool(Miniport
->RegistryPath
->Buffer
);
2773 ExFreePool(Miniport
->RegistryPath
);
2774 ExInterlockedRemoveEntryList(&Miniport
->ListEntry
, &MiniportListLock
);
2775 ExFreePool(Miniport
);
2784 NdisMQueryAdapterInstanceName(
2785 OUT PNDIS_STRING AdapterInstanceName
,
2786 IN NDIS_HANDLE MiniportAdapterHandle
)
2794 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportAdapterHandle
;
2795 UNICODE_STRING AdapterName
;
2797 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2799 AdapterName
.Length
= 0;
2800 AdapterName
.MaximumLength
= Adapter
->NdisMiniportBlock
.MiniportName
.MaximumLength
;
2801 AdapterName
.Buffer
= ExAllocatePool(PagedPool
, AdapterName
.MaximumLength
);
2802 if (!AdapterName
.Buffer
) {
2803 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
2804 return NDIS_STATUS_RESOURCES
;
2807 RtlCopyUnicodeString(&AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
);
2809 *AdapterInstanceName
= AdapterName
;
2811 return NDIS_STATUS_SUCCESS
;
2819 NdisDeregisterAdapterShutdownHandler(
2820 IN NDIS_HANDLE NdisAdapterHandle
)
2828 NdisMDeregisterAdapterShutdownHandler(NdisAdapterHandle
);
2837 NdisRegisterAdapterShutdownHandler(
2838 IN NDIS_HANDLE NdisAdapterHandle
,
2839 IN PVOID ShutdownContext
,
2840 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
2848 NdisMRegisterAdapterShutdownHandler(NdisAdapterHandle
,
2858 NdisMGetDeviceProperty(
2859 IN NDIS_HANDLE MiniportAdapterHandle
,
2860 IN OUT PDEVICE_OBJECT
*PhysicalDeviceObject OPTIONAL
,
2861 IN OUT PDEVICE_OBJECT
*FunctionalDeviceObject OPTIONAL
,
2862 IN OUT PDEVICE_OBJECT
*NextDeviceObject OPTIONAL
,
2863 IN OUT PCM_RESOURCE_LIST
*AllocatedResources OPTIONAL
,
2864 IN OUT PCM_RESOURCE_LIST
*AllocatedResourcesTranslated OPTIONAL
)
2872 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
2874 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
2876 if (PhysicalDeviceObject
!= NULL
)
2877 *PhysicalDeviceObject
= Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
;
2879 if (FunctionalDeviceObject
!= NULL
)
2880 *FunctionalDeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
2882 if (NextDeviceObject
!= NULL
)
2883 *NextDeviceObject
= Adapter
->NdisMiniportBlock
.NextDeviceObject
;
2885 if (AllocatedResources
!= NULL
)
2886 *AllocatedResources
= Adapter
->NdisMiniportBlock
.AllocatedResources
;
2888 if (AllocatedResourcesTranslated
!= NULL
)
2889 *AllocatedResourcesTranslated
= Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
;
2897 NdisMRegisterUnloadHandler(
2898 IN NDIS_HANDLE NdisWrapperHandle
,
2899 IN PDRIVER_UNLOAD UnloadHandler
)
2907 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
2909 NDIS_DbgPrint(MAX_TRACE
, ("Miniport registered unload handler\n"));
2911 DriverBlock
->DriverObject
->DriverUnload
= UnloadHandler
;
2919 NdisMRegisterDevice(
2920 IN NDIS_HANDLE NdisWrapperHandle
,
2921 IN PNDIS_STRING DeviceName
,
2922 IN PNDIS_STRING SymbolicName
,
2923 IN PDRIVER_DISPATCH MajorFunctions
[],
2924 OUT PDEVICE_OBJECT
*pDeviceObject
,
2925 OUT NDIS_HANDLE
*NdisDeviceHandle
)
2933 PNDIS_M_DRIVER_BLOCK DriverBlock
= NdisWrapperHandle
;
2934 PNDIS_M_DEVICE_BLOCK DeviceBlock
;
2935 PDEVICE_OBJECT DeviceObject
;
2939 NDIS_DbgPrint(MAX_TRACE
, ("Called\n"));
2941 Status
= IoCreateDevice(DriverBlock
->DriverObject
,
2942 0, /* This space is reserved for us. Should we use it? */
2944 FILE_DEVICE_NETWORK
,
2949 if (!NT_SUCCESS(Status
))
2951 NDIS_DbgPrint(MIN_TRACE
, ("IoCreateDevice failed (%x)\n", Status
));
2955 Status
= IoCreateSymbolicLink(SymbolicName
, DeviceName
);
2957 if (!NT_SUCCESS(Status
))
2959 NDIS_DbgPrint(MIN_TRACE
, ("IoCreateSymbolicLink failed (%x)\n", Status
));
2960 IoDeleteDevice(DeviceObject
);
2964 DeviceBlock
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DEVICE_BLOCK
));
2968 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources\n"));
2969 IoDeleteDevice(DeviceObject
);
2970 IoDeleteSymbolicLink(SymbolicName
);
2971 return NDIS_STATUS_RESOURCES
;
2974 for (i
= 0; i
<= IRP_MJ_MAXIMUM_FUNCTION
; i
++)
2975 DriverBlock
->DriverObject
->MajorFunction
[i
] = MajorFunctions
[i
];
2977 DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_PNP
] = NdisIDispatchPnp
;
2979 if (!DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_CREATE
])
2980 DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_CREATE
] = NdisICreateClose
;
2982 if (!DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_CLOSE
])
2983 DriverBlock
->DriverObject
->MajorFunction
[IRP_MJ_CLOSE
] = NdisICreateClose
;
2985 DeviceBlock
->DeviceObject
= DeviceObject
;
2986 DeviceBlock
->SymbolicName
= SymbolicName
;
2988 *pDeviceObject
= DeviceObject
;
2989 *NdisDeviceHandle
= DeviceBlock
;
2991 return NDIS_STATUS_SUCCESS
;
2999 NdisMDeregisterDevice(
3000 IN NDIS_HANDLE NdisDeviceHandle
)
3008 PNDIS_M_DEVICE_BLOCK DeviceBlock
= NdisDeviceHandle
;
3010 IoDeleteDevice(DeviceBlock
->DeviceObject
);
3012 IoDeleteSymbolicLink(DeviceBlock
->SymbolicName
);
3014 ExFreePool(DeviceBlock
);
3016 return NDIS_STATUS_SUCCESS
;
3024 NdisQueryAdapterInstanceName(
3025 OUT PNDIS_STRING AdapterInstanceName
,
3026 IN NDIS_HANDLE NdisBindingHandle
)
3034 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3035 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3037 return NdisMQueryAdapterInstanceName(AdapterInstanceName
,
3046 NdisCompletePnPEvent(
3047 IN NDIS_STATUS Status
,
3048 IN NDIS_HANDLE NdisBindingHandle
,
3049 IN PNET_PNP_EVENT NetPnPEvent
)
3057 PIRP Irp
= (PIRP
)NetPnPEvent
->NdisReserved
[0];
3058 PLIST_ENTRY CurrentEntry
= (PLIST_ENTRY
)NetPnPEvent
->NdisReserved
[1];
3059 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3060 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3061 NDIS_STATUS NdisStatus
;
3063 if (Status
!= NDIS_STATUS_SUCCESS
)
3065 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3066 ExFreePool(NetPnPEvent
);
3067 Irp
->IoStatus
.Status
= Status
;
3068 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3072 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
3074 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
3076 NdisStatus
= (*AdapterBinding
->ProtocolBinding
->Chars
.PnPEventHandler
)(
3077 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
3080 if (NdisStatus
== NDIS_STATUS_PENDING
)
3082 NetPnPEvent
->NdisReserved
[1] = (ULONG_PTR
)CurrentEntry
->Flink
;
3085 else if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
3087 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3088 ExFreePool(NetPnPEvent
);
3089 Irp
->IoStatus
.Status
= NdisStatus
;
3090 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3094 CurrentEntry
= CurrentEntry
->Flink
;
3097 if (NetPnPEvent
->Buffer
) ExFreePool(NetPnPEvent
->Buffer
);
3098 ExFreePool(NetPnPEvent
);
3100 Irp
->IoStatus
.Status
= NDIS_STATUS_SUCCESS
;
3101 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
3109 NdisCancelSendPackets(
3110 IN NDIS_HANDLE NdisBindingHandle
,
3113 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3114 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3116 NDIS_DbgPrint(MAX_TRACE
, ("Called for ID %x.\n", CancelId
));
3118 if (Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CancelSendPacketsHandler
)
3120 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.CancelSendPacketsHandler
)(
3121 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
3132 NdisIMGetBindingContext(
3133 IN NDIS_HANDLE NdisBindingHandle
)
3141 PADAPTER_BINDING AdapterBinding
= NdisBindingHandle
;
3142 PLOGICAL_ADAPTER Adapter
= AdapterBinding
->Adapter
;
3144 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3146 return Adapter
->NdisMiniportBlock
.DeviceContext
;
3155 NdisIMGetDeviceContext(
3156 IN NDIS_HANDLE MiniportAdapterHandle
)
3164 PLOGICAL_ADAPTER Adapter
= MiniportAdapterHandle
;
3166 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
3168 return Adapter
->NdisMiniportBlock
.DeviceContext
;