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
21 #undef NdisMSendComplete
25 IN NDIS_HANDLE MiniportAdapterHandle
,
26 IN PNDIS_PACKET Packet
,
27 IN NDIS_STATUS Status
);
29 /* Root of the scm database */
30 #define SERVICES_ROOT L"\\Registry\\Machine\\System\\CurrentControlSet\\Services\\"
33 * Define to 1 to get a debugger breakpoint at the end of NdisInitializeWrapper
34 * for each new miniport starting up
36 #define BREAK_ON_MINIPORT_INIT 0
39 * This has to be big enough to hold the results of querying the Route value
40 * from the Linkage key. Please re-code me to determine this dynamically.
42 #define ROUTE_DATA_SIZE 256
44 /* Number of media we know */
45 #define MEDIA_ARRAY_SIZE 15
47 static NDIS_MEDIUM MediaArray
[MEDIA_ARRAY_SIZE
] =
56 NdisMediumArcnet878_2
,
58 NdisMediumWirelessWan
,
66 /* global list and lock of Miniports NDIS has registered */
67 LIST_ENTRY MiniportListHead
;
68 KSPIN_LOCK MiniportListLock
;
70 /* global list and lock of adapters NDIS has registered */
71 LIST_ENTRY AdapterListHead
;
72 KSPIN_LOCK AdapterListLock
;
81 if ((DebugTraceLevel
& DEBUG_PACKET
) > 0) {
82 Length
= CopyPacketToBuffer(
88 DbgPrint("*** PACKET START ***");
90 for (i
= 0; i
< Length
; i
++) {
92 DbgPrint("\n%04X ", i
);
93 DbgPrint("%02X ", Buffer
[i
]);
96 DbgPrint("*** PACKET STOP ***\n");
104 UINT HeaderBufferSize
,
105 PVOID LookaheadBuffer
,
106 UINT LookaheadBufferSize
)
109 if ((DebugTraceLevel
& DEBUG_PACKET
) > 0) {
113 DbgPrint("*** RECEIVE PACKET START ***\n");
116 for (i
= 0; i
< HeaderBufferSize
; i
++) {
118 DbgPrint("\n%04X ", i
);
119 DbgPrint("%02X ", *p
++);
122 DbgPrint("\nFRAME:");
125 Length
= (LookaheadBufferSize
< 64)? LookaheadBufferSize
: 64;
126 for (i
= 0; i
< Length
; i
++) {
128 DbgPrint("\n%04X ", i
);
129 DbgPrint("%02X ", *p
++);
132 DbgPrint("\n*** RECEIVE PACKET STOP ***\n");
140 PLOGICAL_ADAPTER Adapter
,
141 NDIS_HANDLE MacReceiveContext
,
143 UINT HeaderBufferSize
,
144 PVOID LookaheadBuffer
,
145 UINT LookaheadBufferSize
,
148 * FUNCTION: Indicate received data to bound protocols
150 * Adapter = Pointer to logical adapter
151 * MacReceiveContext = MAC receive context handle
152 * HeaderBuffer = Pointer to header buffer
153 * HeaderBufferSize = Size of header buffer
154 * LookaheadBuffer = Pointer to lookahead buffer
155 * LookaheadBufferSize = Size of lookahead buffer
156 * PacketSize = Total size of received packet
160 PLIST_ENTRY CurrentEntry
;
161 PADAPTER_BINDING AdapterBinding
;
163 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called. Adapter (0x%X) HeaderBuffer (0x%X) "
164 "HeaderBufferSize (0x%X) LookaheadBuffer (0x%X) LookaheadBufferSize (0x%X).\n",
165 Adapter
, HeaderBuffer
, HeaderBufferSize
, LookaheadBuffer
, LookaheadBufferSize
));
167 MiniDisplayPacket2(HeaderBuffer
, HeaderBufferSize
, LookaheadBuffer
, LookaheadBufferSize
);
169 NDIS_DbgPrint(MAX_TRACE
, ("acquiring miniport block lock\n"));
170 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
172 CurrentEntry
= Adapter
->ProtocolListHead
.Flink
;
173 NDIS_DbgPrint(DEBUG_MINIPORT
, ("CurrentEntry = %x\n", CurrentEntry
));
175 if (CurrentEntry
== &Adapter
->ProtocolListHead
)
177 NDIS_DbgPrint(DEBUG_MINIPORT
, ("WARNING: No upper protocol layer.\n"));
180 while (CurrentEntry
!= &Adapter
->ProtocolListHead
)
182 AdapterBinding
= CONTAINING_RECORD(CurrentEntry
, ADAPTER_BINDING
, AdapterListEntry
);
183 NDIS_DbgPrint(DEBUG_MINIPORT
, ("AdapterBinding = %x\n", AdapterBinding
));
185 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
190 NDIS_DbgPrint(MIN_TRACE
, ("AdapterBinding was null\n"));
194 if(!AdapterBinding
->ProtocolBinding
)
196 NDIS_DbgPrint(MIN_TRACE
, ("AdapterBinding->ProtocolBinding was null\n"));
200 if(!AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
)
202 NDIS_DbgPrint(MIN_TRACE
, ("AdapterBinding->ProtocolBinding->Chars.ReceiveHandler was null\n"));
209 ("XXX (%x) %x %x %x %x %x %x %x XXX\n",
210 *AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
,
211 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
219 /* call the receive handler */
220 (*AdapterBinding
->ProtocolBinding
->Chars
.ReceiveHandler
)(
221 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
229 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
231 CurrentEntry
= CurrentEntry
->Flink
;
234 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
236 NDIS_DbgPrint(MAX_TRACE
, ("Leaving.\n"));
241 MiniIndicateReceivePacket(
242 IN NDIS_HANDLE Miniport
,
243 IN PPNDIS_PACKET PacketArray
,
244 IN UINT NumberOfPackets
)
246 * FUNCTION: receives miniport packet array indications
248 * Miniport: Miniport handle for the adapter
249 * PacketArray: pointer to a list of packet pointers to indicate
250 * NumberOfPackets: number of packets to indicate
252 * - This currently is a big temporary hack. In the future this should
253 * call ProtocolReceivePacket() on each bound protocol if it exists.
254 * For now it just mimics NdisMEthIndicateReceive.
259 for(i
= 0; i
< NumberOfPackets
; i
++)
261 PCHAR PacketBuffer
= 0;
262 UINT PacketLength
= 0;
263 PNDIS_BUFFER NdisBuffer
= 0;
265 #define PACKET_TAG (('k' << 24) + ('P' << 16) + ('D' << 8) + 'N')
267 NdisAllocateMemoryWithTag((PVOID
)&PacketBuffer
, 1518, PACKET_TAG
);
270 NDIS_DbgPrint(MIN_TRACE
, ("insufficient resources\n"));
274 NdisQueryPacket(PacketArray
[i
], NULL
, NULL
, &NdisBuffer
, NULL
);
278 PNDIS_BUFFER CurrentBuffer
;
282 NdisQueryBuffer(NdisBuffer
, &BufferVa
, &BufferLen
);
283 memcpy(PacketBuffer
+ PacketLength
, BufferVa
, BufferLen
);
284 PacketLength
+= BufferLen
;
286 CurrentBuffer
= NdisBuffer
;
287 NdisGetNextBuffer(CurrentBuffer
, &NdisBuffer
);
290 NDIS_DbgPrint(MID_TRACE
, ("indicating a %d-byte packet\n", PacketLength
));
292 MiniIndicateData(Miniport
, NULL
, PacketBuffer
, 14, PacketBuffer
+14, PacketLength
-14, PacketLength
-14);
294 NdisFreeMemory(PacketBuffer
, 0, 0);
301 IN NDIS_HANDLE MiniportAdapterHandle
,
302 IN NDIS_STATUS Status
,
303 IN BOOLEAN AddressingReset
)
312 IN PNDIS_MINIPORT_BLOCK Adapter
,
313 IN PNDIS_REQUEST Request
,
314 IN NDIS_STATUS Status
)
316 PNDIS_REQUEST_MAC_BLOCK MacBlock
= (PNDIS_REQUEST_MAC_BLOCK
)Request
->MacReserved
;
319 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
321 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
322 if( MacBlock
->Binding
->RequestCompleteHandler
) {
323 (*MacBlock
->Binding
->RequestCompleteHandler
)(
324 MacBlock
->Binding
->ProtocolBindingContext
,
328 KeLowerIrql(OldIrql
);
333 IN NDIS_HANDLE MiniportAdapterHandle
,
334 IN PNDIS_PACKET Packet
,
335 IN NDIS_STATUS Status
)
337 * FUNCTION: Forwards a message to the initiating protocol saying
338 * that a packet was handled
340 * NdisAdapterHandle = Handle input to MiniportInitialize
341 * Packet = Pointer to NDIS packet that was sent
342 * Status = Status of send operation
345 PADAPTER_BINDING AdapterBinding
;
348 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
350 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[0];
352 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
353 (*AdapterBinding
->ProtocolBinding
->Chars
.SendCompleteHandler
)(
354 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
357 KeLowerIrql(OldIrql
);
362 MiniSendResourcesAvailable(
363 IN NDIS_HANDLE MiniportAdapterHandle
)
372 MiniTransferDataComplete(
373 IN NDIS_HANDLE MiniportAdapterHandle
,
374 IN PNDIS_PACKET Packet
,
375 IN NDIS_STATUS Status
,
376 IN UINT BytesTransferred
)
378 PADAPTER_BINDING AdapterBinding
;
381 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
383 AdapterBinding
= (PADAPTER_BINDING
)Packet
->Reserved
[0];
385 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
386 (*AdapterBinding
->ProtocolBinding
->Chars
.SendCompleteHandler
)(
387 AdapterBinding
->NdisOpenBlock
.ProtocolBindingContext
,
390 KeLowerIrql(OldIrql
);
395 MiniAdapterHasAddress(
396 PLOGICAL_ADAPTER Adapter
,
399 * FUNCTION: Determines whether a packet has the same destination address as an adapter
401 * Adapter = Pointer to logical adapter object
402 * Packet = Pointer to NDIS packet
404 * TRUE if the destination address is that of the adapter, FALSE if not
410 PNDIS_BUFFER NdisBuffer
;
413 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
418 NDIS_DbgPrint(MID_TRACE
, ("Adapter object was null\n"));
424 NDIS_DbgPrint(MID_TRACE
, ("Packet was null\n"));
429 NdisQueryPacket(Packet
, NULL
, NULL
, &NdisBuffer
, NULL
);
433 NDIS_DbgPrint(MID_TRACE
, ("Packet contains no buffers.\n"));
437 NdisQueryBuffer(NdisBuffer
, (PVOID
)&Start2
, &BufferLength
);
439 /* FIXME: Should handle fragmented packets */
441 switch (Adapter
->NdisMiniportBlock
.MediaType
)
443 case NdisMedium802_3
:
444 Length
= ETH_LENGTH_OF_ADDRESS
;
445 /* Destination address is the first field */
449 NDIS_DbgPrint(MIN_TRACE
, ("Adapter has unsupported media type (0x%X).\n", Adapter
->NdisMiniportBlock
.MediaType
));
453 if (BufferLength
< Length
)
455 NDIS_DbgPrint(MID_TRACE
, ("Buffer is too small.\n"));
459 Start1
= (PUCHAR
)&Adapter
->Address
;
460 NDIS_DbgPrint(MAX_TRACE
, ("packet address: %x:%x:%x:%x:%x:%x adapter address: %x:%x:%x:%x:%x:%x\n",
461 *((char *)Start1
), *(((char *)Start1
)+1), *(((char *)Start1
)+2), *(((char *)Start1
)+3), *(((char *)Start1
)+4), *(((char *)Start1
)+5),
462 *((char *)Start2
), *(((char *)Start2
)+1), *(((char *)Start2
)+2), *(((char *)Start2
)+3), *(((char *)Start2
)+4), *(((char *)Start2
)+5))
465 return (RtlCompareMemory((PVOID
)Start1
, (PVOID
)Start2
, Length
) == Length
);
471 PNDIS_STRING AdapterName
)
473 * FUNCTION: Finds an adapter object by name
475 * AdapterName = Pointer to name of adapter
477 * Pointer to logical adapter object, or NULL if none was found.
478 * If found, the adapter is referenced for the caller. The caller
479 * is responsible for dereferencing after use
483 PLIST_ENTRY CurrentEntry
;
484 PLOGICAL_ADAPTER Adapter
= 0;
488 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
490 if(IsListEmpty(&AdapterListHead
))
492 NDIS_DbgPrint(DEBUG_MINIPORT
, ("No registered miniports for protocol to bind to\n"));
496 KeAcquireSpinLock(&AdapterListLock
, &OldIrql
);
498 CurrentEntry
= AdapterListHead
.Flink
;
500 while (CurrentEntry
!= &AdapterListHead
)
502 Adapter
= CONTAINING_RECORD(CurrentEntry
, LOGICAL_ADAPTER
, ListEntry
);
506 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Examining adapter 0x%lx\n", Adapter
));
507 NDIS_DbgPrint(DEBUG_MINIPORT
, ("AdapterName = %wZ\n", AdapterName
));
508 NDIS_DbgPrint(DEBUG_MINIPORT
, ("DeviceName = %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
510 if (RtlCompareUnicodeString(AdapterName
, &Adapter
->NdisMiniportBlock
.MiniportName
, TRUE
) == 0)
516 CurrentEntry
= CurrentEntry
->Flink
;
519 KeReleaseSpinLock(&AdapterListLock
, OldIrql
);
523 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Leaving. Adapter found at 0x%x\n", Adapter
));
527 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Leaving (adapter not found).\n"));
535 MiniQueryInformation(
536 PLOGICAL_ADAPTER Adapter
,
542 * FUNCTION: Queries a logical adapter for properties
544 * Adapter = Pointer to the logical adapter object to query
545 * Oid = Specifies the Object ID to query for
546 * Size = Size of the passed buffer
547 * Buffer = Buffer for the output
548 * BytesWritten = Address of buffer to place number of bytes written
550 * If the specified buffer is too small, a new buffer is allocated,
551 * and the query is attempted again
553 * Status of operation
555 * Is there any way to use the buffer provided by the protocol?
558 NDIS_STATUS NdisStatus
;
562 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
564 /* call the miniport's queryinfo handler */
565 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
566 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.QueryInformationHandler
)(
567 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
,
573 KeLowerIrql(OldIrql
);
575 /* FIXME: Wait in pending case! */
584 PLOGICAL_ADAPTER Adapter
,
585 NDIS_WORK_ITEM_TYPE WorkItemType
,
586 PVOID WorkItemContext
)
588 * FUNCTION: Queues a work item for execution at a later time
590 * Adapter = Pointer to the logical adapter object to queue work item on
591 * WorkItemType = Type of work item to queue
592 * WorkItemContext = Pointer to context information for work item
594 * Adapter lock must be held when called
596 * Status of operation
599 PNDIS_MINIPORT_WORK_ITEM Item
;
601 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
604 ASSERT(KeGetCurrentIrql() >= DISPATCH_LEVEL
);
606 Item
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_MINIPORT_WORK_ITEM
));
609 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
610 return NDIS_STATUS_RESOURCES
;
613 Item
->WorkItemType
= WorkItemType
;
614 Item
->WorkItemContext
= WorkItemContext
;
616 /* safe due to adapter lock held */
617 Item
->Link
.Next
= NULL
;
618 if (!Adapter
->WorkQueueHead
)
620 Adapter
->WorkQueueHead
= Item
;
621 Adapter
->WorkQueueTail
= Item
;
625 Adapter
->WorkQueueTail
->Link
.Next
= (PSINGLE_LIST_ENTRY
)Item
;
626 Adapter
->WorkQueueTail
= Item
;
629 KeInsertQueueDpc(&Adapter
->NdisMiniportBlock
.DeferredDpc
, NULL
, NULL
);
631 return NDIS_STATUS_SUCCESS
;
638 PLOGICAL_ADAPTER Adapter
,
639 NDIS_WORK_ITEM_TYPE
*WorkItemType
,
640 PVOID
*WorkItemContext
)
642 * FUNCTION: Dequeues a work item from the work queue of a logical adapter
644 * Adapter = Pointer to the logical adapter object to dequeue work item from
645 * AdapterBinding = Address of buffer for adapter binding for this request
646 * WorkItemType = Address of buffer for work item type
647 * WorkItemContext = Address of buffer for pointer to context information
649 * Adapter lock must be held when called
651 * Status of operation
654 PNDIS_MINIPORT_WORK_ITEM Item
;
656 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
658 Item
= Adapter
->WorkQueueHead
;
662 /* safe due to adapter lock held */
663 Adapter
->WorkQueueHead
= (PNDIS_MINIPORT_WORK_ITEM
)Item
->Link
.Next
;
665 if (Item
== Adapter
->WorkQueueTail
)
666 Adapter
->WorkQueueTail
= NULL
;
668 *WorkItemType
= Item
->WorkItemType
;
669 *WorkItemContext
= Item
->WorkItemContext
;
673 return NDIS_STATUS_SUCCESS
;
676 return NDIS_STATUS_FAILURE
;
682 PNDIS_MINIPORT_BLOCK Adapter
,
683 PNDIS_REQUEST NdisRequest
)
685 * FUNCTION: Sends a request to a miniport
687 * AdapterBinding = Pointer to binding used in the request
688 * NdisRequest = Pointer to NDIS request structure describing request
690 * Status of operation
695 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
697 Adapter
->MediaRequest
= NdisRequest
;
699 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
700 switch (NdisRequest
->RequestType
)
702 case NdisRequestQueryInformation
:
703 Status
= (*Adapter
->DriverHandle
->MiniportCharacteristics
.QueryInformationHandler
)(
704 Adapter
->MiniportAdapterContext
,
705 NdisRequest
->DATA
.QUERY_INFORMATION
.Oid
,
706 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBuffer
,
707 NdisRequest
->DATA
.QUERY_INFORMATION
.InformationBufferLength
,
708 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesWritten
,
709 (PULONG
)&NdisRequest
->DATA
.QUERY_INFORMATION
.BytesNeeded
);
712 case NdisRequestSetInformation
:
713 Status
= (*Adapter
->DriverHandle
->MiniportCharacteristics
.SetInformationHandler
)(
714 Adapter
->MiniportAdapterContext
,
715 NdisRequest
->DATA
.SET_INFORMATION
.Oid
,
716 NdisRequest
->DATA
.SET_INFORMATION
.InformationBuffer
,
717 NdisRequest
->DATA
.SET_INFORMATION
.InformationBufferLength
,
718 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesRead
,
719 (PULONG
)&NdisRequest
->DATA
.SET_INFORMATION
.BytesNeeded
);
723 Status
= NDIS_STATUS_FAILURE
;
726 KeLowerIrql(OldIrql
);
734 #undef NdisMQueryInformationComplete
737 NdisMQueryInformationComplete(
738 IN NDIS_HANDLE MiniportAdapterHandle
,
739 IN NDIS_STATUS Status
)
741 PNDIS_MINIPORT_BLOCK MiniportBlock
=
742 (PNDIS_MINIPORT_BLOCK
)MiniportAdapterHandle
;
744 ASSERT(MiniportBlock
);
745 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
746 if( MiniportBlock
->QueryCompleteHandler
)
747 (MiniportBlock
->QueryCompleteHandler
)(MiniportAdapterHandle
, Status
);
748 KeLowerIrql(OldIrql
);
751 VOID NTAPI
MiniportWorker(IN PVOID WorkItem
)
753 PNDIS_WORK_ITEM NdisWorkItem
= WorkItem
;
754 PLOGICAL_ADAPTER Adapter
= GET_LOGICAL_ADAPTER(NdisWorkItem
->Context
);
755 KIRQL OldIrql
, RaiseOldIrql
;
756 NDIS_STATUS NdisStatus
;
757 PVOID WorkItemContext
;
758 NDIS_WORK_ITEM_TYPE WorkItemType
;
760 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, &OldIrql
);
764 (Adapter
, &WorkItemType
, &WorkItemContext
);
766 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.Lock
, OldIrql
);
768 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
770 switch (WorkItemType
)
772 case NdisWorkItemSend
:
774 * called by ProSend when protocols want to send packets to the miniport
777 MiniDisplayPacket((PNDIS_PACKET
)WorkItemContext
);
779 if(Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)
781 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
783 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
784 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
785 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
789 /* SendPackets is called at DISPATCH_LEVEL for all serialized miniports */
790 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
792 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's SendPackets handler\n"));
793 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendPacketsHandler
)(
794 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PPNDIS_PACKET
)&WorkItemContext
, 1);
796 KeLowerIrql(RaiseOldIrql
);
799 NdisStatus
= NDIS_GET_PACKET_STATUS((PNDIS_PACKET
)WorkItemContext
);
803 if(Adapter
->NdisMiniportBlock
.Flags
& NDIS_ATTRIBUTE_DESERIALIZE
)
805 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
806 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
807 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
, 0);
808 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
812 /* Send is called at DISPATCH_LEVEL for all serialized miniports */
813 KeRaiseIrql(DISPATCH_LEVEL
, &RaiseOldIrql
);
814 NDIS_DbgPrint(MAX_TRACE
, ("Calling miniport's Send handler\n"));
815 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.SendHandler
)(
816 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
, (PNDIS_PACKET
)WorkItemContext
, 0);
817 NDIS_DbgPrint(MAX_TRACE
, ("back from miniport's send handler\n"));
818 KeLowerIrql(RaiseOldIrql
);
822 if( NdisStatus
== NDIS_STATUS_RESOURCES
)
823 MiniQueueWorkItem(Adapter
, WorkItemType
, WorkItemContext
);
824 else if( NdisStatus
!= NDIS_STATUS_PENDING
) {
826 ( Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
827 Adapter
->MiniportBusy
= FALSE
;
831 case NdisWorkItemSendLoopback
:
833 * called by ProSend when protocols want to send loopback packets
835 /* XXX atm ProIndicatePacket sends a packet up via the loopback adapter only */
836 NdisStatus
= ProIndicatePacket(Adapter
, (PNDIS_PACKET
)WorkItemContext
);
837 MiniSendComplete((NDIS_HANDLE
)Adapter
, (PNDIS_PACKET
)WorkItemContext
, NdisStatus
);
840 case NdisWorkItemReturnPackets
:
843 case NdisWorkItemResetRequested
:
846 case NdisWorkItemResetInProgress
:
849 case NdisWorkItemMiniportCallback
:
852 case NdisWorkItemRequest
:
853 NdisStatus
= MiniDoRequest(&Adapter
->NdisMiniportBlock
, (PNDIS_REQUEST
)WorkItemContext
);
855 if (NdisStatus
== NDIS_STATUS_PENDING
)
858 switch (((PNDIS_REQUEST
)WorkItemContext
)->RequestType
)
860 case NdisRequestQueryInformation
:
861 NdisMQueryInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
862 MiniRequestComplete( &Adapter
->NdisMiniportBlock
, (PNDIS_REQUEST
)WorkItemContext
, NdisStatus
);
865 case NdisRequestSetInformation
:
866 NdisMSetInformationComplete((NDIS_HANDLE
)Adapter
, NdisStatus
);
867 MiniRequestComplete( &Adapter
->NdisMiniportBlock
, (PNDIS_REQUEST
)WorkItemContext
, NdisStatus
);
871 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS request type.\n"));
877 NDIS_DbgPrint(MIN_TRACE
, ("Unknown NDIS work item type (%d).\n", WorkItemType
));
882 ExFreePool(WorkItem
);
887 VOID NTAPI
MiniportDpc(
889 IN PVOID DeferredContext
,
890 IN PVOID SystemArgument1
,
891 IN PVOID SystemArgument2
)
893 * FUNCTION: Deferred routine to handle serialization
895 * Dpc = Pointer to DPC object
896 * DeferredContext = Pointer to context information (LOGICAL_ADAPTER)
897 * SystemArgument1 = Unused
898 * SystemArgument2 = Unused
901 PNDIS_WORK_ITEM NdisWorkItem
;
902 PWORK_QUEUE_ITEM WorkItem
;
904 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
906 NdisWorkItem
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_WORK_ITEM
));
908 WorkItem
= (PWORK_QUEUE_ITEM
)NdisWorkItem
->WrapperReserved
;
910 NdisWorkItem
->Context
= DeferredContext
;
912 ExInitializeWorkItem(WorkItem
, MiniportWorker
, NdisWorkItem
);
914 ExQueueWorkItem(WorkItem
, CriticalWorkQueue
);
921 IN NDIS_HANDLE MiniportHandle
,
922 IN NDIS_STATUS GeneralStatus
,
923 IN PVOID StatusBuffer
,
924 IN UINT StatusBufferSize
)
933 IN NDIS_HANDLE MiniportAdapterHandle
)
945 IN NDIS_HANDLE LogHandle
)
957 IN NDIS_HANDLE MiniportAdapterHandle
,
959 OUT PNDIS_HANDLE LogHandle
)
963 return NDIS_STATUS_FAILURE
;
972 NdisMDeregisterAdapterShutdownHandler(
973 IN NDIS_HANDLE MiniportHandle
)
975 * FUNCTION: de-registers a shutdown handler
976 * ARGUMENTS: MiniportHandle: Handle passed into MiniportInitialize
979 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
981 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
983 if(Adapter
->BugcheckContext
->ShutdownHandler
)
984 KeDeregisterBugCheckCallback(Adapter
->BugcheckContext
->CallbackRecord
);
994 IN NDIS_HANDLE LogHandle
)
1002 #undef NdisMIndicateStatus
1005 NdisMIndicateStatus(
1006 IN NDIS_HANDLE MiniportAdapterHandle
,
1007 IN NDIS_STATUS GeneralStatus
,
1008 IN PVOID StatusBuffer
,
1009 IN UINT StatusBufferSize
)
1017 #undef NdisMIndicateStatusComplete
1020 NdisMIndicateStatusComplete(
1021 IN NDIS_HANDLE MiniportAdapterHandle
)
1032 NdisInitializeWrapper(
1033 OUT PNDIS_HANDLE NdisWrapperHandle
,
1034 IN PVOID SystemSpecific1
,
1035 IN PVOID SystemSpecific2
,
1036 IN PVOID SystemSpecific3
)
1038 * FUNCTION: Notifies the NDIS library that a new miniport is initializing
1040 * NdisWrapperHandle = Address of buffer to place NDIS wrapper handle
1041 * SystemSpecific1 = Pointer to the driver's driver object
1042 * SystemSpecific2 = Pointer to the driver's registry path
1043 * SystemSpecific3 = Always NULL
1045 * - SystemSpecific2 goes invalid so we copy it
1048 PNDIS_M_DRIVER_BLOCK Miniport
;
1049 PUNICODE_STRING RegistryPath
;
1050 WCHAR
*RegistryBuffer
;
1052 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1054 ASSERT(NdisWrapperHandle
);
1056 *NdisWrapperHandle
= NULL
;
1058 #if BREAK_ON_MINIPORT_INIT
1059 __asm__ ("int $3\n");
1062 Miniport
= ExAllocatePool(NonPagedPool
, sizeof(NDIS_M_DRIVER_BLOCK
));
1066 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1070 RtlZeroMemory(Miniport
, sizeof(NDIS_M_DRIVER_BLOCK
));
1072 KeInitializeSpinLock(&Miniport
->Lock
);
1074 Miniport
->DriverObject
= (PDRIVER_OBJECT
)SystemSpecific1
;
1076 /* set the miniport's driver registry path */
1077 RegistryPath
= ExAllocatePool(PagedPool
, sizeof(UNICODE_STRING
));
1080 ExFreePool(Miniport
);
1081 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1085 RegistryPath
->Length
= ((PUNICODE_STRING
)SystemSpecific2
)->Length
;
1086 RegistryPath
->MaximumLength
= RegistryPath
->Length
+ sizeof(WCHAR
); /* room for 0-term */
1088 RegistryBuffer
= ExAllocatePool(PagedPool
, RegistryPath
->MaximumLength
);
1091 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1092 ExFreePool(Miniport
);
1093 ExFreePool(RegistryPath
);
1097 RtlCopyMemory(RegistryBuffer
, ((PUNICODE_STRING
)SystemSpecific2
)->Buffer
, RegistryPath
->Length
);
1098 RegistryBuffer
[RegistryPath
->Length
/sizeof(WCHAR
)] = 0;
1100 RegistryPath
->Buffer
= RegistryBuffer
;
1101 Miniport
->RegistryPath
= RegistryPath
;
1103 InitializeListHead(&Miniport
->DeviceList
);
1105 /* Put miniport in global miniport list */
1106 ExInterlockedInsertTailList(&MiniportListHead
, &Miniport
->ListEntry
, &MiniportListLock
);
1108 *NdisWrapperHandle
= Miniport
;
1112 VOID NTAPI
NdisIBugcheckCallback(
1116 * FUNCTION: Internal callback for handling bugchecks - calls adapter's shutdown handler
1118 * Buffer: Pointer to a bugcheck callback context
1122 PMINIPORT_BUGCHECK_CONTEXT Context
= (PMINIPORT_BUGCHECK_CONTEXT
)Buffer
;
1123 ADAPTER_SHUTDOWN_HANDLER sh
= (ADAPTER_SHUTDOWN_HANDLER
)Context
->ShutdownHandler
;
1125 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1128 sh(Context
->DriverContext
);
1137 NdisMRegisterAdapterShutdownHandler(
1138 IN NDIS_HANDLE MiniportHandle
,
1139 IN PVOID ShutdownContext
,
1140 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler
)
1142 * FUNCTION: Register a shutdown handler for an adapter
1144 * MiniportHandle: Handle originally passed into MiniportInitialize
1145 * ShutdownContext: Pre-initialized bugcheck context
1146 * ShutdownHandler: Function to call to handle the bugcheck
1148 * - I'm not sure about ShutdownContext
1151 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)MiniportHandle
;
1152 PMINIPORT_BUGCHECK_CONTEXT BugcheckContext
= Adapter
->BugcheckContext
;
1154 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Called.\n"));
1159 BugcheckContext
= ExAllocatePool(NonPagedPool
, sizeof(MINIPORT_BUGCHECK_CONTEXT
));
1160 if(!BugcheckContext
)
1162 NDIS_DbgPrint(MIN_TRACE
, ("Insufficient resources.\n"));
1166 BugcheckContext
->ShutdownHandler
= ShutdownHandler
;
1167 BugcheckContext
->DriverContext
= ShutdownContext
;
1169 BugcheckContext
->CallbackRecord
= ExAllocatePool(NonPagedPool
, sizeof(KBUGCHECK_CALLBACK_RECORD
));
1171 KeInitializeCallbackRecord(BugcheckContext
->CallbackRecord
);
1173 KeRegisterBugCheckCallback(BugcheckContext
->CallbackRecord
, NdisIBugcheckCallback
,
1174 BugcheckContext
, sizeof(BugcheckContext
), (PUCHAR
)"Ndis Miniport");
1180 PLOGICAL_ADAPTER Adapter
,
1181 NDIS_OID AddressOID
)
1183 * FUNCTION: Queries miniport for information
1185 * Adapter = Pointer to logical adapter
1186 * AddressOID = OID to use to query for current address
1188 * Status of operation
1192 NDIS_STATUS NdisStatus
;
1194 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1196 /* Get MAC options for adapter */
1197 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAC_OPTIONS
, sizeof(UINT
),
1198 &Adapter
->NdisMiniportBlock
.MacOptions
,
1201 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1203 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAC_OPTIONS failed. NdisStatus (0x%X).\n", NdisStatus
));
1207 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MacOptions (0x%X).\n", Adapter
->NdisMiniportBlock
.MacOptions
));
1209 /* Get current hardware address of adapter */
1210 NdisStatus
= MiniQueryInformation(Adapter
, AddressOID
, Adapter
->AddressLength
,
1211 &Adapter
->Address
, &BytesWritten
);
1213 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1215 NDIS_DbgPrint(MIN_TRACE
, ("Address OID (0x%X) failed. NdisStatus (0x%X).\n", AddressOID
, NdisStatus
));
1223 PUCHAR A
= (PUCHAR
)&Adapter
->Address
.Type
.Medium802_3
;
1225 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]));
1229 /* Get maximum lookahead buffer size of adapter */
1230 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_LOOKAHEAD
, sizeof(ULONG
),
1231 &Adapter
->NdisMiniportBlock
.MaximumLookahead
, &BytesWritten
);
1233 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1235 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1239 NDIS_DbgPrint(DEBUG_MINIPORT
, ("MaxLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.MaximumLookahead
));
1241 /* Get current lookahead buffer size of adapter */
1242 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_CURRENT_LOOKAHEAD
, sizeof(ULONG
),
1243 &Adapter
->NdisMiniportBlock
.CurrentLookahead
, &BytesWritten
);
1245 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1247 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_CURRENT_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus
));
1251 NdisStatus
= MiniQueryInformation(Adapter
, OID_GEN_MAXIMUM_SEND_PACKETS
, sizeof(ULONG
),
1252 &Adapter
->NdisMiniportBlock
.MaxSendPackets
, &BytesWritten
);
1254 if (NdisStatus
!= NDIS_STATUS_SUCCESS
)
1256 NDIS_DbgPrint(MIN_TRACE
, ("OID_GEN_MAXIMUM_SEND_PACKETS failed. NdisStatus (0x%X).\n", NdisStatus
));
1258 /* Set it to 1 if it fails because some drivers don't support this (?)*/
1259 Adapter
->NdisMiniportBlock
.MaxSendPackets
= 1;
1262 NDIS_DbgPrint(DEBUG_MINIPORT
, ("CurLookaheadLength (0x%X).\n", Adapter
->NdisMiniportBlock
.CurrentLookahead
));
1264 if (Adapter
->NdisMiniportBlock
.MaximumLookahead
!= 0)
1266 Adapter
->LookaheadLength
= Adapter
->NdisMiniportBlock
.MaximumLookahead
+ Adapter
->MediumHeaderSize
;
1267 Adapter
->LookaheadBuffer
= ExAllocatePool(NonPagedPool
, Adapter
->LookaheadLength
);
1269 if (!Adapter
->LookaheadBuffer
)
1270 return NDIS_STATUS_RESOURCES
;
1273 return STATUS_SUCCESS
;
1279 NdisIForwardIrpAndWaitCompletionRoutine(
1284 PKEVENT Event
= Context
;
1286 if (Irp
->PendingReturned
)
1287 KeSetEvent(Event
, IO_NO_INCREMENT
, FALSE
);
1289 return STATUS_MORE_PROCESSING_REQUIRED
;
1295 NdisIForwardIrpAndWait(PLOGICAL_ADAPTER Adapter
, PIRP Irp
)
1300 KeInitializeEvent(&Event
, NotificationEvent
, FALSE
);
1301 IoCopyCurrentIrpStackLocationToNext(Irp
);
1302 IoSetCompletionRoutine(Irp
, NdisIForwardIrpAndWaitCompletionRoutine
, &Event
,
1304 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
1305 if (Status
== STATUS_PENDING
)
1307 KeWaitForSingleObject(&Event
, Executive
, KernelMode
, FALSE
, NULL
);
1308 Status
= Irp
->IoStatus
.Status
;
1316 NdisIPnPStartDevice(
1317 IN PDEVICE_OBJECT DeviceObject
,
1320 * FUNCTION: Handle the PnP start device event
1322 * DeviceObejct = Functional Device Object
1323 * Irp = IRP_MN_START_DEVICE I/O request packet
1325 * Status of operation
1328 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
1329 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1330 NDIS_WRAPPER_CONTEXT WrapperContext
;
1331 NDIS_STATUS NdisStatus
;
1332 NDIS_STATUS OpenErrorStatus
;
1334 UINT SelectedMediumIndex
= 0;
1335 NDIS_OID AddressOID
;
1336 BOOLEAN Success
= FALSE
;
1337 ULONG ResourceCount
;
1338 ULONG ResourceListSize
;
1339 UNICODE_STRING ParamName
;
1340 PNDIS_CONFIGURATION_PARAMETER ConfigParam
;
1341 NDIS_HANDLE ConfigHandle
;
1343 /* FIXME - KIRQL OldIrql; */
1346 * Prepare wrapper context used by HW and configuration routines.
1349 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Start Device %wZ\n", &Adapter
->NdisMiniportBlock
.MiniportName
));
1351 NDIS_DbgPrint(MAX_TRACE
, ("Inserting adapter 0x%x into adapter list\n", Adapter
));
1353 /* Put adapter in global adapter list */
1354 ExInterlockedInsertTailList(&AdapterListHead
, &Adapter
->ListEntry
, &AdapterListLock
);
1356 Status
= IoOpenDeviceRegistryKey(
1357 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
, PLUGPLAY_REGKEY_DRIVER
,
1358 KEY_ALL_ACCESS
, &WrapperContext
.RegistryHandle
);
1359 if (!NT_SUCCESS(Status
))
1361 NDIS_DbgPrint(MIN_TRACE
,("failed to open adapter-specific reg key\n"));
1362 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1366 NDIS_DbgPrint(MAX_TRACE
, ("opened device reg key\n"));
1368 WrapperContext
.DeviceObject
= Adapter
->NdisMiniportBlock
.DeviceObject
;
1371 * Store the adapter resources used by HW routines such as
1372 * NdisMQueryAdapterResources.
1375 if (Stack
->Parameters
.StartDevice
.AllocatedResources
!= NULL
)
1377 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResources
->List
[0].
1378 PartialResourceList
.Count
;
1380 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1381 PartialDescriptors
[ResourceCount
]);
1383 Adapter
->NdisMiniportBlock
.AllocatedResources
=
1384 ExAllocatePool(PagedPool
, ResourceListSize
);
1385 if (Adapter
->NdisMiniportBlock
.AllocatedResources
== NULL
)
1387 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1388 return STATUS_INSUFFICIENT_RESOURCES
;
1391 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResources
,
1392 Stack
->Parameters
.StartDevice
.AllocatedResources
,
1396 if (Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
!= NULL
)
1398 ResourceCount
= Stack
->Parameters
.StartDevice
.AllocatedResources
->List
[0].
1399 PartialResourceList
.Count
;
1401 FIELD_OFFSET(CM_RESOURCE_LIST
, List
[0].PartialResourceList
.
1402 PartialDescriptors
[ResourceCount
]);
1404 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
=
1405 ExAllocatePool(PagedPool
, ResourceListSize
);
1406 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
== NULL
)
1408 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1409 return STATUS_INSUFFICIENT_RESOURCES
;
1412 RtlCopyMemory(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
,
1413 Stack
->Parameters
.StartDevice
.AllocatedResourcesTranslated
,
1418 * Store the Bus Type, Bus Number and Slot information. It's used by
1419 * the hardware routines then.
1422 NdisOpenConfiguration(&NdisStatus
, &ConfigHandle
, (NDIS_HANDLE
)&WrapperContext
);
1424 Size
= sizeof(ULONG
);
1425 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1426 DevicePropertyLegacyBusType
, Size
,
1427 &Adapter
->NdisMiniportBlock
.BusType
, &Size
);
1428 if (!NT_SUCCESS(Status
) || (INTERFACE_TYPE
)Adapter
->NdisMiniportBlock
.BusType
== InterfaceTypeUndefined
)
1430 NdisInitUnicodeString(&ParamName
, L
"BusType");
1431 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1432 &ParamName
, NdisParameterInteger
);
1433 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1434 Adapter
->NdisMiniportBlock
.BusType
= ConfigParam
->ParameterData
.IntegerData
;
1436 Adapter
->NdisMiniportBlock
.BusType
= Isa
;
1439 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1440 DevicePropertyBusNumber
, Size
,
1441 &Adapter
->NdisMiniportBlock
.BusNumber
, &Size
);
1442 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.BusNumber
== 0xFFFFFFF0)
1444 NdisInitUnicodeString(&ParamName
, L
"BusNumber");
1445 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1446 &ParamName
, NdisParameterInteger
);
1447 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1448 Adapter
->NdisMiniportBlock
.BusNumber
= ConfigParam
->ParameterData
.IntegerData
;
1450 Adapter
->NdisMiniportBlock
.BusNumber
= 0;
1452 WrapperContext
.BusNumber
= Adapter
->NdisMiniportBlock
.BusNumber
;
1454 Status
= IoGetDeviceProperty(Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
,
1455 DevicePropertyAddress
, Size
,
1456 &Adapter
->NdisMiniportBlock
.SlotNumber
, &Size
);
1457 if (!NT_SUCCESS(Status
) || Adapter
->NdisMiniportBlock
.SlotNumber
== (NDIS_INTERFACE_TYPE
)-1)
1459 NdisInitUnicodeString(&ParamName
, L
"SlotNumber");
1460 NdisReadConfiguration(&NdisStatus
, &ConfigParam
, ConfigHandle
,
1461 &ParamName
, NdisParameterInteger
);
1462 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1463 Adapter
->NdisMiniportBlock
.SlotNumber
= ConfigParam
->ParameterData
.IntegerData
;
1465 Adapter
->NdisMiniportBlock
.SlotNumber
= 0;
1469 /* Convert slotnumber to PCI_SLOT_NUMBER */
1470 ULONG PciSlotNumber
= Adapter
->NdisMiniportBlock
.SlotNumber
;
1471 PCI_SLOT_NUMBER SlotNumber
;
1473 SlotNumber
.u
.AsULONG
= 0;
1474 SlotNumber
.u
.bits
.DeviceNumber
= (PciSlotNumber
>> 16) & 0xFFFF;
1475 SlotNumber
.u
.bits
.FunctionNumber
= PciSlotNumber
& 0xFFFF;
1477 Adapter
->NdisMiniportBlock
.SlotNumber
= SlotNumber
.u
.AsULONG
;
1479 NdisCloseConfiguration(ConfigHandle
);
1481 /* Set handlers (some NDIS macros require these) */
1482 Adapter
->NdisMiniportBlock
.EthRxCompleteHandler
= EthFilterDprIndicateReceiveComplete
;
1483 Adapter
->NdisMiniportBlock
.EthRxIndicateHandler
= EthFilterDprIndicateReceive
;
1484 Adapter
->NdisMiniportBlock
.SendCompleteHandler
= MiniSendComplete
;
1485 Adapter
->NdisMiniportBlock
.SendResourcesHandler
= MiniSendResourcesAvailable
;
1486 Adapter
->NdisMiniportBlock
.ResetCompleteHandler
= MiniResetComplete
;
1487 Adapter
->NdisMiniportBlock
.TDCompleteHandler
= MiniTransferDataComplete
;
1488 Adapter
->NdisMiniportBlock
.PacketIndicateHandler
= MiniIndicateReceivePacket
;
1489 Adapter
->NdisMiniportBlock
.StatusHandler
= MiniStatus
;
1490 Adapter
->NdisMiniportBlock
.StatusCompleteHandler
= MiniStatusComplete
;
1493 * Call MiniportInitialize.
1496 NDIS_DbgPrint(MID_TRACE
, ("calling MiniportInitialize\n"));
1497 NdisStatus
= (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.InitializeHandler
)(
1498 &OpenErrorStatus
, &SelectedMediumIndex
, &MediaArray
[0],
1499 MEDIA_ARRAY_SIZE
, Adapter
, (NDIS_HANDLE
)&WrapperContext
);
1501 ZwClose(WrapperContext
.RegistryHandle
);
1503 if (NdisStatus
!= NDIS_STATUS_SUCCESS
||
1504 SelectedMediumIndex
>= MEDIA_ARRAY_SIZE
)
1506 NDIS_DbgPrint(MIN_TRACE
, ("MiniportInitialize() failed for an adapter.\n"));
1507 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1508 if (NdisStatus
== NDIS_STATUS_SUCCESS
) NdisStatus
= NDIS_STATUS_FAILURE
;
1509 return (NTSTATUS
)NdisStatus
;
1512 Adapter
->NdisMiniportBlock
.MediaType
= MediaArray
[SelectedMediumIndex
];
1514 switch (Adapter
->NdisMiniportBlock
.MediaType
)
1516 case NdisMedium802_3
:
1517 Adapter
->MediumHeaderSize
= 14; /* XXX figure out what to do about LLC */
1518 AddressOID
= OID_802_3_CURRENT_ADDRESS
;
1519 Adapter
->AddressLength
= ETH_LENGTH_OF_ADDRESS
;
1520 NdisStatus
= DoQueries(Adapter
, AddressOID
);
1521 if (NdisStatus
== NDIS_STATUS_SUCCESS
)
1523 Success
= EthCreateFilter(32, /* FIXME: Query this from miniport. */
1524 Adapter
->Address
.Type
.Medium802_3
,
1525 &Adapter
->NdisMiniportBlock
.EthDB
);
1527 ((PETHI_FILTER
)Adapter
->NdisMiniportBlock
.EthDB
)->Miniport
= (PNDIS_MINIPORT_BLOCK
)Adapter
;
1529 NdisStatus
= NDIS_STATUS_RESOURCES
;
1534 /* FIXME: Support other types of media */
1535 NDIS_DbgPrint(MIN_TRACE
, ("error: unsupported media\n"));
1537 /* FIXME - KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql); */
1538 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1539 return STATUS_UNSUCCESSFUL
;
1542 if (!Success
|| NdisStatus
!= NDIS_STATUS_SUCCESS
)
1544 NDIS_DbgPrint(MAX_TRACE
, ("couldn't create filter (%x)\n", NdisStatus
));
1545 if (Adapter
->LookaheadBuffer
)
1547 ExFreePool(Adapter
->LookaheadBuffer
);
1548 Adapter
->LookaheadBuffer
= NULL
;
1550 ExInterlockedRemoveEntryList( &Adapter
->ListEntry
, &AdapterListLock
);
1551 if (NdisStatus
== NDIS_STATUS_SUCCESS
) NdisStatus
= NDIS_STATUS_FAILURE
;
1552 return (NTSTATUS
)NdisStatus
;
1555 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
1556 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStarted
;
1558 /* Put adapter in adapter list for this miniport */
1559 ExInterlockedInsertTailList(&Adapter
->NdisMiniportBlock
.DriverHandle
->DeviceList
, &Adapter
->MiniportListEntry
, &Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
);
1561 return STATUS_SUCCESS
;
1568 IN PDEVICE_OBJECT DeviceObject
,
1571 * FUNCTION: Handle the PnP stop device event
1573 * DeviceObejct = Functional Device Object
1574 * Irp = IRP_MN_STOP_DEVICE I/O request packet
1576 * Status of operation
1579 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1582 /* Remove adapter from adapter list for this miniport */
1583 KeAcquireSpinLock(&Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
, &OldIrql
);
1584 RemoveEntryList(&Adapter
->MiniportListEntry
);
1585 KeReleaseSpinLock(&Adapter
->NdisMiniportBlock
.DriverHandle
->Lock
, OldIrql
);
1587 /* Remove adapter from global adapter list */
1588 KeAcquireSpinLock(&AdapterListLock
, &OldIrql
);
1589 RemoveEntryList(&Adapter
->ListEntry
);
1590 KeReleaseSpinLock(&AdapterListLock
, OldIrql
);
1592 (*Adapter
->NdisMiniportBlock
.DriverHandle
->MiniportCharacteristics
.HaltHandler
)(Adapter
);
1594 if (Adapter
->LookaheadBuffer
)
1596 ExFreePool(Adapter
->LookaheadBuffer
);
1597 Adapter
->LookaheadBuffer
= NULL
;
1599 if (Adapter
->NdisMiniportBlock
.AllocatedResources
)
1601 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResources
);
1602 Adapter
->NdisMiniportBlock
.AllocatedResources
= NULL
;
1604 if (Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
)
1606 ExFreePool(Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
);
1607 Adapter
->NdisMiniportBlock
.AllocatedResourcesTranslated
= NULL
;
1610 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= Adapter
->NdisMiniportBlock
.PnPDeviceState
;
1611 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceStopped
;
1613 return STATUS_SUCCESS
;
1620 IN PDEVICE_OBJECT DeviceObject
,
1623 PIO_STACK_LOCATION Stack
= IoGetCurrentIrpStackLocation(Irp
);
1624 PLOGICAL_ADAPTER Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1627 switch (Stack
->MinorFunction
)
1629 case IRP_MN_START_DEVICE
:
1630 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
1631 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
1633 Status
= NdisIPnPStartDevice(DeviceObject
, Irp
);
1635 Irp
->IoStatus
.Status
= Status
;
1636 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1639 case IRP_MN_STOP_DEVICE
:
1640 Status
= NdisIForwardIrpAndWait(Adapter
, Irp
);
1641 if (NT_SUCCESS(Status
) && NT_SUCCESS(Irp
->IoStatus
.Status
))
1643 Status
= NdisIPnPStopDevice(DeviceObject
, Irp
);
1645 Irp
->IoStatus
.Status
= Status
;
1646 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1649 case IRP_MN_QUERY_DEVICE_RELATIONS
:
1650 Status
= STATUS_NOT_SUPPORTED
;
1651 Irp
->IoStatus
.Status
= Status
;
1652 IoCompleteRequest(Irp
, IO_NO_INCREMENT
);
1656 IoSkipCurrentIrpStackLocation(Irp
);
1657 Status
= IoCallDriver(Adapter
->NdisMiniportBlock
.NextDeviceObject
, Irp
);
1668 IN PDRIVER_OBJECT DriverObject
,
1669 IN PDEVICE_OBJECT PhysicalDeviceObject
)
1671 * FUNCTION: Create a device for an adapter found using PnP
1673 * DriverObject = Pointer to the miniport driver object
1674 * PhysicalDeviceObject = Pointer to the PDO for our adapter
1677 static const WCHAR ClassKeyName
[] = {'C','l','a','s','s','\\'};
1678 static const WCHAR LinkageKeyName
[] = {'\\','L','i','n','k','a','g','e',0};
1679 PNDIS_M_DRIVER_BLOCK Miniport
;
1680 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
1681 WCHAR
*LinkageKeyBuffer
;
1682 ULONG DriverKeyLength
;
1683 RTL_QUERY_REGISTRY_TABLE QueryTable
[2];
1684 UNICODE_STRING ExportName
;
1685 PDEVICE_OBJECT DeviceObject
;
1686 PLOGICAL_ADAPTER Adapter
;
1690 * Gain the access to the miniport data structure first.
1693 MiniportPtr
= IoGetDriverObjectExtension(DriverObject
, (PVOID
)TAG('D','I','M','N'));
1694 if (MiniportPtr
== NULL
)
1696 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't get driver object extension.\n"));
1697 return STATUS_UNSUCCESSFUL
;
1699 Miniport
= *MiniportPtr
;
1702 * Get name of the Linkage registry key for our adapter. It's located under
1703 * the driver key for our driver and so we have basicly two ways to do it.
1704 * Either we can use IoOpenDriverRegistryKey or compose it using information
1705 * gathered by IoGetDeviceProperty. I choosed the second because
1706 * IoOpenDriverRegistryKey wasn't implemented at the time of writing.
1709 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
1710 0, NULL
, &DriverKeyLength
);
1711 if (Status
!= STATUS_BUFFER_TOO_SMALL
&& Status
!= STATUS_BUFFER_OVERFLOW
&& Status
!= STATUS_SUCCESS
)
1713 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't get miniport driver key length.\n"));
1717 LinkageKeyBuffer
= ExAllocatePool(PagedPool
, DriverKeyLength
+
1718 sizeof(ClassKeyName
) + sizeof(LinkageKeyName
));
1719 if (LinkageKeyBuffer
== NULL
)
1721 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't allocate memory for driver key name.\n"));
1722 return STATUS_INSUFFICIENT_RESOURCES
;
1725 Status
= IoGetDeviceProperty(PhysicalDeviceObject
, DevicePropertyDriverKeyName
,
1726 DriverKeyLength
, LinkageKeyBuffer
+
1727 (sizeof(ClassKeyName
) / sizeof(WCHAR
)),
1729 if (!NT_SUCCESS(Status
))
1731 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't get miniport driver key.\n"));
1732 ExFreePool(LinkageKeyBuffer
);
1736 /* Compose the linkage key name. */
1737 RtlCopyMemory(LinkageKeyBuffer
, ClassKeyName
, sizeof(ClassKeyName
));
1738 RtlCopyMemory(LinkageKeyBuffer
+ ((sizeof(ClassKeyName
) + DriverKeyLength
) /
1739 sizeof(WCHAR
)) - 1, LinkageKeyName
, sizeof(LinkageKeyName
));
1741 NDIS_DbgPrint(DEBUG_MINIPORT
, ("LinkageKey: %S.\n", LinkageKeyBuffer
));
1744 * Now open the linkage key and read the "Export" and "RootDevice" values
1745 * which contains device name and root service respectively.
1748 RtlZeroMemory(QueryTable
, sizeof(QueryTable
));
1749 RtlInitUnicodeString(&ExportName
, NULL
);
1750 QueryTable
[0].Flags
= RTL_QUERY_REGISTRY_REQUIRED
| RTL_QUERY_REGISTRY_DIRECT
;
1751 QueryTable
[0].Name
= L
"Export";
1752 QueryTable
[0].EntryContext
= &ExportName
;
1754 Status
= RtlQueryRegistryValues(RTL_REGISTRY_CONTROL
, LinkageKeyBuffer
,
1755 QueryTable
, NULL
, NULL
);
1756 ExFreePool(LinkageKeyBuffer
);
1757 if (!NT_SUCCESS(Status
))
1759 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't get miniport device name. (%x)\n", Status
));
1764 * Create the device object.
1767 NDIS_DbgPrint(MAX_TRACE
, ("creating device %wZ\n", &ExportName
));
1769 Status
= IoCreateDevice(Miniport
->DriverObject
, sizeof(LOGICAL_ADAPTER
),
1770 &ExportName
, FILE_DEVICE_PHYSICAL_NETCARD
,
1771 0, FALSE
, &DeviceObject
);
1772 if (!NT_SUCCESS(Status
))
1774 NDIS_DbgPrint(MIN_TRACE
, ("Could not create device object.\n"));
1775 RtlFreeUnicodeString(&ExportName
);
1780 * Initialize the adapter structure.
1783 Adapter
= (PLOGICAL_ADAPTER
)DeviceObject
->DeviceExtension
;
1784 KeInitializeSpinLock(&Adapter
->NdisMiniportBlock
.Lock
);
1785 InitializeListHead(&Adapter
->ProtocolListHead
);
1786 Adapter
->NdisMiniportBlock
.DriverHandle
= Miniport
;
1788 Adapter
->NdisMiniportBlock
.MiniportName
= ExportName
;
1790 Adapter
->NdisMiniportBlock
.DeviceObject
= DeviceObject
;
1791 Adapter
->NdisMiniportBlock
.PhysicalDeviceObject
= PhysicalDeviceObject
;
1792 Adapter
->NdisMiniportBlock
.NextDeviceObject
=
1793 IoAttachDeviceToDeviceStack(Adapter
->NdisMiniportBlock
.DeviceObject
,
1794 PhysicalDeviceObject
);
1796 Adapter
->NdisMiniportBlock
.OldPnPDeviceState
= 0;
1797 Adapter
->NdisMiniportBlock
.PnPDeviceState
= NdisPnPDeviceAdded
;
1799 KeInitializeDpc(&Adapter
->NdisMiniportBlock
.DeferredDpc
, MiniportDpc
, (PVOID
)Adapter
);
1801 DeviceObject
->Flags
&= ~DO_DEVICE_INITIALIZING
;
1803 return STATUS_SUCCESS
;
1812 NdisMRegisterMiniport(
1813 IN NDIS_HANDLE NdisWrapperHandle
,
1814 IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics
,
1815 IN UINT CharacteristicsLength
)
1817 * FUNCTION: Registers a miniport's MiniportXxx entry points with the NDIS library
1819 * NdisWrapperHandle = Pointer to handle returned by NdisMInitializeWrapper
1820 * MiniportCharacteristics = Pointer to a buffer with miniport characteristics
1821 * CharacteristicsLength = Number of bytes in characteristics buffer
1823 * Status of operation
1827 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
1828 PNDIS_M_DRIVER_BLOCK
*MiniportPtr
;
1831 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
1833 switch (MiniportCharacteristics
->MajorNdisVersion
)
1836 MinSize
= sizeof(NDIS30_MINIPORT_CHARACTERISTICS
);
1840 MinSize
= sizeof(NDIS40_MINIPORT_CHARACTERISTICS
);
1844 MinSize
= sizeof(NDIS50_MINIPORT_CHARACTERISTICS
);
1848 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Bad miniport characteristics version.\n"));
1849 return NDIS_STATUS_BAD_VERSION
;
1852 if (CharacteristicsLength
< MinSize
)
1854 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Bad miniport characteristics.\n"));
1855 return NDIS_STATUS_BAD_CHARACTERISTICS
;
1858 /* Check if mandatory MiniportXxx functions are specified */
1859 if ((!MiniportCharacteristics
->HaltHandler
) ||
1860 (!MiniportCharacteristics
->InitializeHandler
)||
1861 (!MiniportCharacteristics
->QueryInformationHandler
) ||
1862 (!MiniportCharacteristics
->ResetHandler
) ||
1863 (!MiniportCharacteristics
->SetInformationHandler
))
1865 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Bad miniport characteristics.\n"));
1866 return NDIS_STATUS_BAD_CHARACTERISTICS
;
1869 if (MiniportCharacteristics
->MajorNdisVersion
== 0x03)
1871 if (!MiniportCharacteristics
->SendHandler
)
1873 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Bad miniport characteristics.\n"));
1874 return NDIS_STATUS_BAD_CHARACTERISTICS
;
1877 else if (MiniportCharacteristics
->MajorNdisVersion
>= 0x04)
1880 if ((!MiniportCharacteristics
->SendHandler
) &&
1881 (!MiniportCharacteristics
->SendPacketsHandler
))
1883 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Bad miniport characteristics.\n"));
1884 return NDIS_STATUS_BAD_CHARACTERISTICS
;
1888 /* TODO: verify NDIS5 and NDIS5.1 */
1890 RtlCopyMemory(&Miniport
->MiniportCharacteristics
, MiniportCharacteristics
, MinSize
);
1893 * NOTE: This is VERY unoptimal! Should we store the NDIS_M_DRIVER_BLOCK
1894 * structure in the driver extension or what?
1897 Status
= IoAllocateDriverObjectExtension(Miniport
->DriverObject
, (PVOID
)TAG('D','I','M','N'),
1898 sizeof(PNDIS_M_DRIVER_BLOCK
), (PVOID
*)&MiniportPtr
);
1899 if (!NT_SUCCESS(Status
))
1901 NDIS_DbgPrint(DEBUG_MINIPORT
, ("Can't allocate driver object extension.\n"));
1902 return NDIS_STATUS_RESOURCES
;
1905 *MiniportPtr
= Miniport
;
1907 Miniport
->DriverObject
->MajorFunction
[IRP_MJ_PNP
] = NdisIDispatchPnp
;
1908 Miniport
->DriverObject
->DriverExtension
->AddDevice
= NdisIAddDevice
;
1910 return NDIS_STATUS_SUCCESS
;
1917 #undef NdisMResetComplete
1921 IN NDIS_HANDLE MiniportAdapterHandle
,
1922 IN NDIS_STATUS Status
,
1923 IN BOOLEAN AddressingReset
)
1925 MiniResetComplete(MiniportAdapterHandle
, Status
, AddressingReset
);
1932 #undef NdisMSendComplete
1936 IN NDIS_HANDLE MiniportAdapterHandle
,
1937 IN PNDIS_PACKET Packet
,
1938 IN NDIS_STATUS Status
)
1940 * FUNCTION: Forwards a message to the initiating protocol saying
1941 * that a packet was handled
1943 * NdisAdapterHandle = Handle input to MiniportInitialize
1944 * Packet = Pointer to NDIS packet that was sent
1945 * Status = Status of send operation
1948 MiniSendComplete(MiniportAdapterHandle
, Packet
, Status
);
1955 #undef NdisMSendResourcesAvailable
1958 NdisMSendResourcesAvailable(
1959 IN NDIS_HANDLE MiniportAdapterHandle
)
1961 MiniSendResourcesAvailable(MiniportAdapterHandle
);
1968 #undef NdisMTransferDataComplete
1971 NdisMTransferDataComplete(
1972 IN NDIS_HANDLE MiniportAdapterHandle
,
1973 IN PNDIS_PACKET Packet
,
1974 IN NDIS_STATUS Status
,
1975 IN UINT BytesTransferred
)
1977 MiniTransferDataComplete(MiniportAdapterHandle
, Packet
, Status
, BytesTransferred
);
1984 #undef NdisMSetInformationComplete
1987 NdisMSetInformationComplete(
1988 IN NDIS_HANDLE MiniportAdapterHandle
,
1989 IN NDIS_STATUS Status
)
1992 KeRaiseIrql(DISPATCH_LEVEL
, &OldIrql
);
1993 (*((PNDIS_MINIPORT_BLOCK
)(MiniportAdapterHandle
))->SetCompleteHandler
)(MiniportAdapterHandle
, Status
);
1994 KeLowerIrql(OldIrql
);
2001 #undef NdisMSetAttributes
2005 IN NDIS_HANDLE MiniportAdapterHandle
,
2006 IN NDIS_HANDLE MiniportAdapterContext
,
2007 IN BOOLEAN BusMaster
,
2008 IN NDIS_INTERFACE_TYPE AdapterType
)
2010 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2012 * MiniportAdapterHandle = Handle input to MiniportInitialize
2013 * MiniportAdapterContext = Pointer to context information
2014 * BusMaster = Specifies TRUE if the caller's NIC is a busmaster DMA device
2015 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2018 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2019 NdisMSetAttributesEx(MiniportAdapterHandle
, MiniportAdapterContext
, 0,
2020 BusMaster
? NDIS_ATTRIBUTE_BUS_MASTER
: 0,
2030 NdisMSetAttributesEx(
2031 IN NDIS_HANDLE MiniportAdapterHandle
,
2032 IN NDIS_HANDLE MiniportAdapterContext
,
2033 IN UINT CheckForHangTimeInSeconds OPTIONAL
,
2034 IN ULONG AttributeFlags
,
2035 IN NDIS_INTERFACE_TYPE AdapterType
)
2037 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
2039 * MiniportAdapterHandle = Handle input to MiniportInitialize
2040 * MiniportAdapterContext = Pointer to context information
2041 * CheckForHangTimeInSeconds = Specifies interval in seconds at which
2042 * MiniportCheckForHang should be called
2043 * AttributeFlags = Bitmask that indicates specific attributes
2044 * AdapterType = Specifies the I/O bus interface of the caller's NIC
2047 /* TODO: Take CheckForHandTimeInSeconds into account! */
2049 PLOGICAL_ADAPTER Adapter
= GET_LOGICAL_ADAPTER(MiniportAdapterHandle
);
2051 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2053 Adapter
->NdisMiniportBlock
.MiniportAdapterContext
= MiniportAdapterContext
;
2054 Adapter
->NdisMiniportBlock
.Flags
= AttributeFlags
;
2055 Adapter
->NdisMiniportBlock
.AdapterType
= AdapterType
;
2056 if (AttributeFlags
& NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER
)
2057 NDIS_DbgPrint(MAX_TRACE
, ("Intermediate drivers not supported yet.\n"));
2067 IN ULONG MicrosecondsToSleep
)
2069 * FUNCTION: delay the thread's execution for MicrosecondsToSleep
2071 * MicrosecondsToSleep: duh...
2073 * - Because this is a blocking call, current IRQL must be < DISPATCH_LEVEL
2077 LARGE_INTEGER DueTime
;
2081 DueTime
.QuadPart
= (-1) * 10 * MicrosecondsToSleep
;
2083 KeInitializeTimer(&Timer
);
2084 KeSetTimer(&Timer
, DueTime
, 0);
2085 KeWaitForSingleObject(&Timer
, Executive
, KernelMode
, FALSE
, 0);
2094 NdisMSynchronizeWithInterrupt(
2095 IN PNDIS_MINIPORT_INTERRUPT Interrupt
,
2096 IN PVOID SynchronizeFunction
,
2097 IN PVOID SynchronizeContext
)
2099 return(KeSynchronizeExecution(Interrupt
->InterruptObject
,
2100 (PKSYNCHRONIZE_ROUTINE
)SynchronizeFunction
,
2101 SynchronizeContext
));
2111 IN NDIS_HANDLE LogHandle
,
2113 IN UINT LogBufferSize
)
2115 PUCHAR Buffer
= LogBuffer
;
2119 for (i
= 0; i
< LogBufferSize
; i
+= 16)
2121 DbgPrint("%08x |", i
);
2122 for (j
= 0; j
< 16; j
++)
2125 if (idx
< LogBufferSize
)
2126 DbgPrint(" %02x", Buffer
[idx
]);
2131 for (j
= 0; j
< 16; j
++)
2134 if (idx
== LogBufferSize
)
2136 if (Buffer
[idx
] >= ' ') /* FIXME: not portable! replace by if (isprint(Buffer[idx])) ? */
2137 DbgPrint("%c", Buffer
[idx
]);
2144 return NDIS_STATUS_FAILURE
;
2153 NdisTerminateWrapper(
2154 IN NDIS_HANDLE NdisWrapperHandle
,
2155 IN PVOID SystemSpecific
)
2157 * FUNCTION: Releases resources allocated by a call to NdisInitializeWrapper
2159 * NdisWrapperHandle = Handle returned by NdisInitializeWrapper (NDIS_M_DRIVER_BLOCK)
2160 * SystemSpecific = Always NULL
2163 PNDIS_M_DRIVER_BLOCK Miniport
= GET_MINIPORT_DRIVER(NdisWrapperHandle
);
2165 NDIS_DbgPrint(MAX_TRACE
, ("Called.\n"));
2167 ExFreePool(Miniport
->RegistryPath
->Buffer
);
2168 ExFreePool(Miniport
->RegistryPath
);
2169 ExFreePool(Miniport
);