Added calibration of KeStallExecutionProcessor delay
[reactos.git] / reactos / drivers / net / ndis / ndis / miniport.c
1 /*
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 * REVISIONS:
8 * CSH 01/08-2000 Created
9 */
10 #include <miniport.h>
11 #include <protocol.h>
12 #ifdef DBG
13 #include <buffer.h>
14 #endif /* DBG */
15
16
17 /* Number of media we know */
18 #define MEDIA_ARRAY_SIZE 15
19
20 static NDIS_MEDIUM MediaArray[MEDIA_ARRAY_SIZE] = {
21 NdisMedium802_3,
22 NdisMedium802_5,
23 NdisMediumFddi,
24 NdisMediumWan,
25 NdisMediumLocalTalk,
26 NdisMediumDix,
27 NdisMediumArcnetRaw,
28 NdisMediumArcnet878_2,
29 NdisMediumAtm,
30 NdisMediumWirelessWan,
31 NdisMediumIrda,
32 NdisMediumBpc,
33 NdisMediumCoWan,
34 NdisMedium1394,
35 NdisMediumMax
36 };
37
38
39 LIST_ENTRY MiniportListHead;
40 KSPIN_LOCK MiniportListLock;
41 LIST_ENTRY AdapterListHead;
42 KSPIN_LOCK AdapterListLock;
43
44
45 #ifdef DBG
46 VOID
47 MiniDisplayPacket(
48 PNDIS_PACKET Packet)
49 {
50 ULONG i, Length;
51 UCHAR Buffer[64];
52
53 Length = CopyPacketToBuffer(
54 (PUCHAR)&Buffer,
55 Packet,
56 0,
57 64);
58
59 NDIS_DbgPrint(DEBUG_PACKET, ("*** PACKET START ***"));
60
61 for (i = 0; i < Length; i++) {
62 if (i % 12 == 0)
63 DbgPrint("\n%04X ", i);
64 DbgPrint("%02X ", Buffer[i]);
65 }
66
67 NDIS_DbgPrint(DEBUG_PACKET, ("*** PACKET STOP ***\n"));
68 }
69 #endif /* DBG */
70
71
72 VOID
73 MiniIndicateData(
74 PLOGICAL_ADAPTER Adapter,
75 NDIS_HANDLE MacReceiveContext,
76 PVOID HeaderBuffer,
77 UINT HeaderBufferSize,
78 PVOID LookaheadBuffer,
79 UINT LookaheadBufferSize,
80 UINT PacketSize)
81 /*
82 * FUNCTION: Indicate received data to bound protocols
83 * ARGUMENTS:
84 * Adapter = Pointer to logical adapter
85 * MacReceiveContext = MAC receive context handle
86 * HeaderBuffer = Pointer to header buffer
87 * HeaderBufferSize = Size of header buffer
88 * LookaheadBuffer = Pointer to lookahead buffer
89 * LookaheadBufferSize = Size of lookahead buffer
90 * PacketSize = Total size of received packet
91 */
92 {
93 KIRQL OldIrql;
94 PLIST_ENTRY CurrentEntry;
95 PADAPTER_BINDING AdapterBinding;
96
97 NDIS_DbgPrint(DEBUG_MINIPORT, ("Called. Adapter (0x%X) HeaderBuffer (0x%X) "
98 "HeaderBufferSize (0x%X) LookaheadBuffer (0x%X) LookaheadBufferSize (0x%X).\n",
99 Adapter, HeaderBuffer, HeaderBufferSize, LookaheadBuffer, LookaheadBufferSize));
100
101 #ifdef DBG
102 if (DebugTraceLevel | DEBUG_PACKET) {
103 ULONG i, Length;
104 PUCHAR p;
105
106 NDIS_DbgPrint(DEBUG_PACKET, ("*** RECEIVE PACKET START ***\n"));
107 NDIS_DbgPrint(DEBUG_PACKET, ("HEADER:"));
108 p = HeaderBuffer;
109 for (i = 0; i < HeaderBufferSize; i++) {
110 if (i % 12 == 0)
111 DbgPrint("\n%04X ", i);
112 DbgPrint("%02X ", *p);
113 (ULONG_PTR)p += 1;
114 }
115
116 NDIS_DbgPrint(DEBUG_PACKET, ("\nFRAME:"));
117
118 p = LookaheadBuffer;
119 Length = (LookaheadBufferSize < 64)? LookaheadBufferSize : 64;
120 for (i = 0; i < Length; i++) {
121 if (i % 12 == 0)
122 DbgPrint("\n%04X ", i);
123 DbgPrint("%02X ", *p);
124 (ULONG_PTR)p += 1;
125 }
126
127 NDIS_DbgPrint(DEBUG_PACKET, ("*** RECEIVE PACKET STOP ***\n"));
128 }
129 #endif /* DBG */
130
131 KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql);
132 CurrentEntry = Adapter->ProtocolListHead.Flink;
133 while (CurrentEntry != &Adapter->ProtocolListHead) {
134 AdapterBinding = CONTAINING_RECORD(CurrentEntry,
135 ADAPTER_BINDING,
136 AdapterListEntry);
137
138 KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
139
140 (*AdapterBinding->ProtocolBinding->Chars.u4.ReceiveHandler)(
141 AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
142 MacReceiveContext,
143 HeaderBuffer,
144 HeaderBufferSize,
145 LookaheadBuffer,
146 LookaheadBufferSize,
147 PacketSize);
148
149 KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql);
150
151 CurrentEntry = CurrentEntry->Flink;
152 }
153 KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
154 }
155
156
157 VOID
158 MiniEthReceiveComplete(
159 IN PETH_FILTER Filter)
160 /*
161 * FUNCTION: Receive indication complete function for Ethernet devices
162 * ARGUMENTS:
163 * Filter = Pointer to Ethernet filter
164 */
165 {
166 KIRQL OldIrql;
167 PLIST_ENTRY CurrentEntry;
168 PLOGICAL_ADAPTER Adapter;
169 PADAPTER_BINDING AdapterBinding;
170
171 NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
172
173 Adapter = (PLOGICAL_ADAPTER)Filter->Miniport;
174
175 KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql);
176 CurrentEntry = Adapter->ProtocolListHead.Flink;
177 while (CurrentEntry != &Adapter->ProtocolListHead) {
178 AdapterBinding = CONTAINING_RECORD(CurrentEntry,
179 ADAPTER_BINDING,
180 AdapterListEntry);
181
182 KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
183
184 (*AdapterBinding->ProtocolBinding->Chars.ReceiveCompleteHandler)(
185 AdapterBinding->NdisOpenBlock.ProtocolBindingContext);
186
187 KeAcquireSpinLock(&Adapter->NdisMiniportBlock.Lock, &OldIrql);
188
189 CurrentEntry = CurrentEntry->Flink;
190 }
191 KeReleaseSpinLock(&Adapter->NdisMiniportBlock.Lock, OldIrql);
192 }
193
194
195 VOID
196 MiniEthReceiveIndication(
197 IN PETH_FILTER Filter,
198 IN NDIS_HANDLE MacReceiveContext,
199 IN PCHAR Address,
200 IN PVOID HeaderBuffer,
201 IN UINT HeaderBufferSize,
202 IN PVOID LookaheadBuffer,
203 IN UINT LookaheadBufferSize,
204 IN UINT PacketSize)
205 /*
206 * FUNCTION: Receive indication function for Ethernet devices
207 * ARGUMENTS:
208 * Filter = Pointer to Ethernet filter
209 * MacReceiveContext = MAC receive context handle
210 * Address = Pointer to destination Ethernet address
211 * HeaderBuffer = Pointer to Ethernet header buffer
212 * HeaderBufferSize = Size of Ethernet header buffer
213 * LookaheadBuffer = Pointer to lookahead buffer
214 * LookaheadBufferSize = Size of lookahead buffer
215 * PacketSize = Total size of received packet
216 */
217 {
218 MiniIndicateData((PLOGICAL_ADAPTER)Filter->Miniport,
219 MacReceiveContext,
220 HeaderBuffer,
221 HeaderBufferSize,
222 LookaheadBuffer,
223 LookaheadBufferSize,
224 PacketSize);
225 }
226
227
228 VOID
229 MiniResetComplete(
230 IN NDIS_HANDLE MiniportAdapterHandle,
231 IN NDIS_STATUS Status,
232 IN BOOLEAN AddressingReset)
233 {
234 UNIMPLEMENTED
235 }
236
237
238 VOID
239 MiniSendComplete(
240 IN NDIS_HANDLE MiniportAdapterHandle,
241 IN PNDIS_PACKET Packet,
242 IN NDIS_STATUS Status)
243 /*
244 * FUNCTION: Forwards a message to the initiating protocol saying
245 * that a packet was handled
246 * ARGUMENTS:
247 * NdisAdapterHandle = Handle input to MiniportInitialize
248 * Packet = Pointer to NDIS packet that was sent
249 * Status = Status of send operation
250 */
251 {
252 PADAPTER_BINDING AdapterBinding;
253
254 NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
255
256 AdapterBinding = (PADAPTER_BINDING)Packet->Reserved[0];
257
258 (*AdapterBinding->ProtocolBinding->Chars.u2.SendCompleteHandler)(
259 AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
260 Packet,
261 Status);
262 }
263
264
265 VOID
266 MiniSendResourcesAvailable(
267 IN NDIS_HANDLE MiniportAdapterHandle)
268 {
269 UNIMPLEMENTED
270 }
271
272
273 VOID
274 MiniTransferDataComplete(
275 IN NDIS_HANDLE MiniportAdapterHandle,
276 IN PNDIS_PACKET Packet,
277 IN NDIS_STATUS Status,
278 IN UINT BytesTransferred)
279 {
280 PLOGICAL_ADAPTER Adapter = (PLOGICAL_ADAPTER)MiniportAdapterHandle;
281 PADAPTER_BINDING AdapterBinding = Adapter->MiniportAdapterBinding;
282
283 NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
284
285 (*AdapterBinding->ProtocolBinding->Chars.u3.TransferDataCompleteHandler)(
286 AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
287 Packet,
288 Status,
289 BytesTransferred);
290 }
291
292
293 BOOLEAN
294 MiniAdapterHasAddress(
295 PLOGICAL_ADAPTER Adapter,
296 PNDIS_PACKET Packet)
297 /*
298 * FUNCTION: Determines wether a packet has the same destination address as an adapter
299 * ARGUMENTS:
300 * Adapter = Pointer to logical adapter object
301 * Packet = Pointer to NDIS packet
302 * RETURNS:
303 * TRUE if the destination address is that of the adapter, FALSE if not
304 */
305 {
306 UINT Length;
307 PUCHAR Start1;
308 PUCHAR Start2;
309 PNDIS_BUFFER NdisBuffer;
310 UINT BufferLength;
311
312 Start1 = (PUCHAR)&Adapter->Address;
313 NdisQueryPacket(Packet, NULL, NULL, &NdisBuffer, NULL);
314 if (!NdisBuffer) {
315 NDIS_DbgPrint(MID_TRACE, ("Packet contains no buffers.\n"));
316 return FALSE;
317 }
318
319 NdisQueryBuffer(NdisBuffer, (PVOID)&Start2, &BufferLength);
320
321 /* FIXME: Should handle fragmented packets */
322
323 switch (Adapter->NdisMiniportBlock.MediaType) {
324 case NdisMedium802_3:
325 Length = ETH_LENGTH_OF_ADDRESS;
326 /* Destination address is the first field */
327 break;
328
329 default:
330 NDIS_DbgPrint(MIN_TRACE, ("Adapter has unsupported media type (0x%X).\n", Adapter->NdisMiniportBlock.MediaType));
331 return FALSE;
332 }
333
334 if (BufferLength < Length) {
335 NDIS_DbgPrint(MID_TRACE, ("Buffer is too small.\n"));
336 return FALSE;
337 }
338
339 return (RtlCompareMemory((PVOID)Start1, (PVOID)Start2, Length) == Length);
340 }
341
342
343 PLOGICAL_ADAPTER
344 MiniLocateDevice(
345 PNDIS_STRING AdapterName)
346 /*
347 * FUNCTION: Returns the logical adapter object for a specific adapter
348 * ARGUMENTS:
349 * AdapterName = Pointer to name of adapter
350 * RETURNS:
351 * Pointer to logical adapter object, or NULL if none was found.
352 * If found, the adapter is referenced for the caller. The caller
353 * is responsible for dereferencing after use
354 */
355 {
356 KIRQL OldIrql;
357 PLIST_ENTRY CurrentEntry;
358 PLOGICAL_ADAPTER Adapter;
359
360 NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
361
362 KeAcquireSpinLock(&AdapterListLock, &OldIrql);
363 CurrentEntry = AdapterListHead.Flink;
364 while (CurrentEntry != &AdapterListHead) {
365 Adapter = CONTAINING_RECORD(CurrentEntry, LOGICAL_ADAPTER, ListEntry);
366
367 if (RtlCompareUnicodeString(AdapterName, &Adapter->DeviceName, TRUE) == 0) {
368 ReferenceObject(Adapter);
369 KeReleaseSpinLock(&AdapterListLock, OldIrql);
370
371 NDIS_DbgPrint(DEBUG_MINIPORT, ("Leaving. Adapter found at (0x%X).\n", Adapter));
372
373 return Adapter;
374 }
375
376 CurrentEntry = CurrentEntry->Flink;
377 }
378 KeReleaseSpinLock(&AdapterListLock, OldIrql);
379
380 NDIS_DbgPrint(DEBUG_MINIPORT, ("Leaving (adapter not found).\n"));
381
382 return NULL;
383 }
384
385
386 NDIS_STATUS
387 MiniQueryInformation(
388 PLOGICAL_ADAPTER Adapter,
389 NDIS_OID Oid,
390 ULONG Size,
391 PULONG BytesWritten)
392 /*
393 * FUNCTION: Queries a logical adapter for properties
394 * ARGUMENTS:
395 * Adapter = Pointer to the logical adapter object to query
396 * Oid = Specifies the Object ID to query for
397 * Size = If non-zero overrides the length in the adapter object
398 * BytesWritten = Address of buffer to place number of bytes written
399 * NOTES:
400 * If the specified buffer is too small, a new buffer is allocated,
401 * and the query is attempted again
402 * RETURNS:
403 * Status of operation
404 */
405 {
406 NDIS_STATUS NdisStatus;
407 ULONG BytesNeeded;
408
409 if (Adapter->QueryBufferLength == 0) {
410 Adapter->QueryBuffer = ExAllocatePool(NonPagedPool, (Size == 0)? 32 : Size);
411
412 if (!Adapter->QueryBuffer) {
413 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
414 return NDIS_STATUS_RESOURCES;
415 }
416
417 Adapter->QueryBufferLength = (Size == 0)? 32 : Size;
418 }
419
420 BytesNeeded = (Size == 0)? Adapter->QueryBufferLength : Size;
421
422 NdisStatus = (*Adapter->Miniport->Chars.QueryInformationHandler)(
423 Adapter->NdisMiniportBlock.MiniportAdapterContext,
424 Oid,
425 Adapter->QueryBuffer,
426 BytesNeeded,
427 BytesWritten,
428 &BytesNeeded);
429
430 if ((NT_SUCCESS(NdisStatus)) || (NdisStatus == NDIS_STATUS_PENDING)) {
431 NDIS_DbgPrint(DEBUG_MINIPORT, ("Miniport returned status (0x%X).\n", NdisStatus));
432 return NdisStatus;
433 }
434
435 if (NdisStatus == NDIS_STATUS_INVALID_LENGTH) {
436 ExFreePool(Adapter->QueryBuffer);
437
438 Adapter->QueryBufferLength += BytesNeeded;
439 Adapter->QueryBuffer = ExAllocatePool(NonPagedPool,
440 Adapter->QueryBufferLength);
441
442 if (!Adapter->QueryBuffer) {
443 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
444 return NDIS_STATUS_RESOURCES;
445 }
446
447 NdisStatus = (*Adapter->Miniport->Chars.QueryInformationHandler)(
448 Adapter->NdisMiniportBlock.MiniportAdapterContext,
449 Oid,
450 Adapter->QueryBuffer,
451 Size,
452 BytesWritten,
453 &BytesNeeded);
454 }
455
456 return NdisStatus;
457 }
458
459
460 NDIS_STATUS
461 FASTCALL
462 MiniQueueWorkItem(
463 PLOGICAL_ADAPTER Adapter,
464 NDIS_WORK_ITEM_TYPE WorkItemType,
465 PVOID WorkItemContext,
466 NDIS_HANDLE Initiator)
467 /*
468 * FUNCTION: Queues a work item for execution at a later time
469 * ARGUMENTS:
470 * Adapter = Pointer to the logical adapter object to queue work item on
471 * WorkItemType = Type of work item to queue
472 * WorkItemContext = Pointer to context information for work item
473 * Initiator = Pointer to ADAPTER_BINDING structure of initiating protocol
474 * NOTES:
475 * Adapter lock must be held when called
476 * RETURNS:
477 * Status of operation
478 */
479 {
480 PNDIS_MINIPORT_WORK_ITEM Item;
481
482 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
483
484 if (Adapter->WorkQueueLevel < NDIS_MINIPORT_WORK_QUEUE_SIZE - 1) {
485 Item = &Adapter->WorkQueue[Adapter->WorkQueueLevel];
486 Adapter->WorkQueueLevel++;
487 } else {
488 Item = ExAllocatePool(NonPagedPool, sizeof(NDIS_MINIPORT_WORK_ITEM));
489 if (Item) {
490 /* Set flag so we know that the buffer should be freed
491 when work item is dequeued */
492 Item->Allocated = TRUE;
493 } else {
494 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
495 return NDIS_STATUS_RESOURCES;
496 }
497 }
498
499 Item->WorkItemType = WorkItemType;
500 Item->WorkItemContext = WorkItemContext;
501 Item->Initiator = Initiator;
502
503 Item->Link.Next = NULL;
504 if (!Adapter->WorkQueueHead) {
505 Adapter->WorkQueueHead = Item;
506 } else {
507 Adapter->WorkQueueTail->Link.Next = (PSINGLE_LIST_ENTRY)Item;
508 }
509
510 KeInsertQueueDpc(&Adapter->MiniportDpc, NULL, NULL);
511
512 return NDIS_STATUS_SUCCESS;
513 }
514
515
516 NDIS_STATUS
517 FASTCALL
518 MiniDequeueWorkItem(
519 PLOGICAL_ADAPTER Adapter,
520 NDIS_WORK_ITEM_TYPE *WorkItemType,
521 PVOID *WorkItemContext,
522 NDIS_HANDLE *Initiator)
523 /*
524 * FUNCTION: Dequeues a work item from the work queue of a logical adapter
525 * ARGUMENTS:
526 * Adapter = Pointer to the logical adapter object to dequeue work item from
527 * WorkItemType = Address of buffer for work item type
528 * WorkItemContext = Address of buffer for pointer to context information
529 * Initiator = Address of buffer for initiator of the work (ADAPTER_BINDING)
530 * NOTES:
531 * Adapter lock must be held when called
532 * RETURNS:
533 * Status of operation
534 */
535 {
536 PNDIS_MINIPORT_WORK_ITEM Item;
537
538 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
539
540 Item = Adapter->WorkQueueHead;
541 if (Item) {
542 Adapter->WorkQueueHead = (PNDIS_MINIPORT_WORK_ITEM)Item->Link.Next;
543 if (Item == Adapter->WorkQueueTail)
544 Adapter->WorkQueueTail = NULL;
545
546 *WorkItemType = Item->WorkItemType;
547 *WorkItemContext = Item->WorkItemContext;
548 *Initiator = Item->Initiator;
549
550 if (Item->Allocated) {
551 ExFreePool(Item);
552 } else {
553 Adapter->WorkQueueLevel--;
554 #ifdef DBG
555 if (Adapter->WorkQueueLevel < 0) {
556 NDIS_DbgPrint(MIN_TRACE, ("Adapter->WorkQueueLevel is < 0 (should be >= 0).\n"));
557 }
558 #endif
559 }
560
561 return NDIS_STATUS_SUCCESS;
562 }
563
564 return NDIS_STATUS_FAILURE;
565 }
566
567
568 NDIS_STATUS
569 MiniDoRequest(
570 PLOGICAL_ADAPTER Adapter,
571 PNDIS_REQUEST NdisRequest)
572 /*
573 * FUNCTION: Sends a request to a miniport
574 * ARGUMENTS:
575 * Adapter = Pointer to logical adapter object
576 * NdisRequest = Pointer to NDIS request structure describing request
577 * RETURNS:
578 * Status of operation
579 */
580 {
581 Adapter->NdisMiniportBlock.MediaRequest = NdisRequest;
582
583 switch (NdisRequest->RequestType) {
584 case NdisRequestQueryInformation:
585 return (*Adapter->Miniport->Chars.QueryInformationHandler)(
586 Adapter->NdisMiniportBlock.MiniportAdapterContext,
587 NdisRequest->DATA.QUERY_INFORMATION.Oid,
588 NdisRequest->DATA.QUERY_INFORMATION.InformationBuffer,
589 NdisRequest->DATA.QUERY_INFORMATION.InformationBufferLength,
590 (PULONG)&NdisRequest->DATA.QUERY_INFORMATION.BytesWritten,
591 (PULONG)&NdisRequest->DATA.QUERY_INFORMATION.BytesNeeded);
592 break;
593
594 case NdisRequestSetInformation:
595 return (*Adapter->Miniport->Chars.SetInformationHandler)(
596 Adapter->NdisMiniportBlock.MiniportAdapterContext,
597 NdisRequest->DATA.SET_INFORMATION.Oid,
598 NdisRequest->DATA.SET_INFORMATION.InformationBuffer,
599 NdisRequest->DATA.SET_INFORMATION.InformationBufferLength,
600 (PULONG)&NdisRequest->DATA.SET_INFORMATION.BytesRead,
601 (PULONG)&NdisRequest->DATA.SET_INFORMATION.BytesNeeded);
602 break;
603
604 default:
605 return NDIS_STATUS_FAILURE;
606 }
607 }
608
609
610 VOID MiniportDpc(
611 IN PKDPC Dpc,
612 IN PVOID DeferredContext,
613 IN PVOID SystemArgument1,
614 IN PVOID SystemArgument2)
615 /*
616 * FUNCTION: Deferred routine to handle serialization
617 * ARGUMENTS:
618 * Dpc = Pointer to DPC object
619 * DeferredContext = Pointer to context information (LOGICAL_ADAPTER)
620 * SystemArgument1 = Unused
621 * SystemArgument2 = Unused
622 */
623 {
624 NDIS_STATUS NdisStatus;
625 PVOID WorkItemContext;
626 NDIS_WORK_ITEM_TYPE WorkItemType;
627 PADAPTER_BINDING AdapterBinding;
628 PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(DeferredContext);
629
630 NDIS_DbgPrint(DEBUG_MINIPORT, ("Called.\n"));
631
632 NdisStatus = MiniDequeueWorkItem(Adapter,
633 &WorkItemType,
634 &WorkItemContext,
635 (PNDIS_HANDLE)&AdapterBinding);
636 if (NdisStatus == NDIS_STATUS_SUCCESS) {
637 Adapter->MiniportAdapterBinding = AdapterBinding;
638 switch (WorkItemType) {
639 case NdisWorkItemSend:
640 #ifdef DBG
641 MiniDisplayPacket((PNDIS_PACKET)WorkItemContext);
642 #endif
643 NdisStatus = (*Adapter->Miniport->Chars.u1.SendHandler)(
644 Adapter->NdisMiniportBlock.MiniportAdapterContext,
645 (PNDIS_PACKET)WorkItemContext,
646 0);
647 if (NdisStatus != NDIS_STATUS_PENDING) {
648 MiniSendComplete((NDIS_HANDLE)Adapter,
649 (PNDIS_PACKET)WorkItemContext,
650 NdisStatus);
651 }
652 break;
653
654 case NdisWorkItemSendLoopback:
655 NdisStatus = ProIndicatePacket(Adapter,
656 (PNDIS_PACKET)WorkItemContext);
657 MiniSendComplete((NDIS_HANDLE)Adapter,
658 (PNDIS_PACKET)WorkItemContext,
659 NdisStatus);
660 break;
661
662 case NdisWorkItemReturnPackets:
663 break;
664
665 case NdisWorkItemResetRequested:
666 break;
667
668 case NdisWorkItemResetInProgress:
669 break;
670
671 case NdisWorkItemHalt:
672 break;
673
674 case NdisWorkItemMiniportCallback:
675 break;
676
677 case NdisWorkItemRequest:
678 NdisStatus = MiniDoRequest(Adapter, (PNDIS_REQUEST)WorkItemContext);
679
680 if (NdisStatus == NDIS_STATUS_PENDING)
681 break;
682
683 switch (((PNDIS_REQUEST)WorkItemContext)->RequestType) {
684 case NdisRequestQueryInformation:
685 NdisMQueryInformationComplete((NDIS_HANDLE)Adapter, NdisStatus);
686 break;
687
688 case NdisRequestSetInformation:
689 NdisMSetInformationComplete((NDIS_HANDLE)Adapter, NdisStatus);
690 break;
691
692 default:
693 NDIS_DbgPrint(MIN_TRACE, ("Unknown NDIS request type.\n"));
694 break;
695 }
696 break;
697
698 default:
699 NDIS_DbgPrint(MIN_TRACE, ("Unknown NDIS work item type (%d).\n", WorkItemType));
700 break;
701 }
702 }
703 }
704
705
706 VOID
707 EXPORT
708 NdisMCloseLog(
709 IN NDIS_HANDLE LogHandle)
710 {
711 UNIMPLEMENTED
712 }
713
714
715 NDIS_STATUS
716 EXPORT
717 NdisMCreateLog(
718 IN NDIS_HANDLE MiniportAdapterHandle,
719 IN UINT Size,
720 OUT PNDIS_HANDLE LogHandle)
721 {
722 UNIMPLEMENTED
723
724 return NDIS_STATUS_FAILURE;
725 }
726
727
728 VOID
729 EXPORT
730 NdisMDeregisterAdapterShutdownHandler(
731 IN NDIS_HANDLE MiniportHandle)
732 {
733 UNIMPLEMENTED
734 }
735
736
737 VOID
738 EXPORT
739 NdisMFlushLog(
740 IN NDIS_HANDLE LogHandle)
741 {
742 UNIMPLEMENTED
743 }
744
745
746 VOID
747 EXPORT
748 NdisMIndicateStatus(
749 IN NDIS_HANDLE MiniportAdapterHandle,
750 IN NDIS_STATUS GeneralStatus,
751 IN PVOID StatusBuffer,
752 IN UINT StatusBufferSize)
753 {
754 UNIMPLEMENTED
755 }
756
757
758 VOID
759 EXPORT
760 NdisMIndicateStatusComplete(
761 IN NDIS_HANDLE MiniportAdapterHandle)
762 {
763 UNIMPLEMENTED
764 }
765
766
767 VOID
768 EXPORT
769 NdisInitializeWrapper(
770 OUT PNDIS_HANDLE NdisWrapperHandle,
771 IN PVOID SystemSpecific1,
772 IN PVOID SystemSpecific2,
773 IN PVOID SystemSpecific3)
774 /*
775 * FUNCTION: Notifies the NDIS library that a new miniport is initializing
776 * ARGUMENTS:
777 * NdisWrapperHandle = Address of buffer to place NDIS wrapper handle
778 * SystemSpecific1 = Pointer to the driver's driver object
779 * SystemSpecific2 = Pointer to the driver's registry path
780 * SystemSpecific3 = Always NULL
781 */
782 {
783 PMINIPORT_DRIVER Miniport;
784
785 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
786
787 Miniport = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_DRIVER));
788 if (!Miniport) {
789 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
790 *NdisWrapperHandle = NULL;
791 return;
792 }
793
794 RtlZeroMemory(Miniport, sizeof(MINIPORT_DRIVER));
795
796 KeInitializeSpinLock(&Miniport->Lock);
797
798 Miniport->RefCount = 1;
799
800 Miniport->DriverObject = (PDRIVER_OBJECT)SystemSpecific1;
801
802 InitializeListHead(&Miniport->AdapterListHead);
803
804 /* Put miniport in global miniport list */
805 ExInterlockedInsertTailList(&MiniportListHead,
806 &Miniport->ListEntry,
807 &MiniportListLock);
808
809 *NdisWrapperHandle = Miniport;
810 }
811
812
813 VOID
814 EXPORT
815 NdisMQueryInformationComplete(
816 IN NDIS_HANDLE MiniportAdapterHandle,
817 IN NDIS_STATUS Status)
818 {
819 PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(MiniportAdapterHandle);
820 PADAPTER_BINDING AdapterBinding = (PADAPTER_BINDING)Adapter->MiniportAdapterBinding;
821
822 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
823
824 (*AdapterBinding->ProtocolBinding->Chars.RequestCompleteHandler)(
825 AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
826 Adapter->NdisMiniportBlock.MediaRequest,
827 Status);
828 }
829
830
831 VOID
832 EXPORT
833 NdisMRegisterAdapterShutdownHandler(
834 IN NDIS_HANDLE MiniportHandle,
835 IN PVOID ShutdownContext,
836 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler)
837 {
838 UNIMPLEMENTED
839 }
840
841
842 NDIS_STATUS
843 DoQueries(
844 PLOGICAL_ADAPTER Adapter,
845 NDIS_OID AddressOID)
846 /*
847 * FUNCTION: Queries miniport for information
848 * ARGUMENTS:
849 * Adapter = Pointer to logical adapter
850 * AddressOID = OID to use to query for current address
851 * RETURNS:
852 * Status of operation
853 */
854 {
855 ULONG BytesWritten;
856 NDIS_STATUS NdisStatus;
857
858 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
859
860 /* Get MAC options for adapter */
861 NdisStatus = MiniQueryInformation(Adapter,
862 OID_GEN_MAC_OPTIONS,
863 0,
864 &BytesWritten);
865 if (NdisStatus != NDIS_STATUS_SUCCESS) {
866 NDIS_DbgPrint(MIN_TRACE, ("OID_GEN_MAC_OPTIONS failed. NdisStatus (0x%X).\n", NdisStatus));
867 return NdisStatus;
868 }
869
870 RtlCopyMemory(&Adapter->NdisMiniportBlock.MacOptions, Adapter->QueryBuffer, sizeof(UINT));
871
872 NDIS_DbgPrint(DEBUG_MINIPORT, ("MacOptions (0x%X).\n", Adapter->NdisMiniportBlock.MacOptions));
873
874 /* Get current hardware address of adapter */
875 NdisStatus = MiniQueryInformation(Adapter,
876 AddressOID,
877 0,
878 &BytesWritten);
879 if (NdisStatus != NDIS_STATUS_SUCCESS) {
880 NDIS_DbgPrint(MIN_TRACE, ("Address OID (0x%X) failed. NdisStatus (0x%X).\n",
881 AddressOID, NdisStatus));
882 return NdisStatus;
883 }
884
885 RtlCopyMemory(&Adapter->Address, Adapter->QueryBuffer, Adapter->AddressLength);
886 #ifdef DBG
887 {
888 /* 802.3 only */
889
890 PUCHAR A = (PUCHAR)&Adapter->Address.Type.Medium802_3;
891
892 NDIS_DbgPrint(MAX_TRACE, ("Adapter address is (%02X %02X %02X %02X %02X %02X).\n",
893 A[0], A[1], A[2], A[3], A[4], A[5]));
894 }
895 #endif /* DBG */
896
897 /* Get maximum lookahead buffer size of adapter */
898 NdisStatus = MiniQueryInformation(Adapter,
899 OID_GEN_MAXIMUM_LOOKAHEAD,
900 0,
901 &BytesWritten);
902 if (NdisStatus != NDIS_STATUS_SUCCESS) {
903 NDIS_DbgPrint(MIN_TRACE, ("OID_GEN_MAXIMUM_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus));
904 return NdisStatus;
905 }
906
907 Adapter->MaxLookaheadLength = *((PULONG)Adapter->QueryBuffer);
908
909 NDIS_DbgPrint(DEBUG_MINIPORT, ("MaxLookaheadLength (0x%X).\n", Adapter->MaxLookaheadLength));
910
911 /* Get current lookahead buffer size of adapter */
912 NdisStatus = MiniQueryInformation(Adapter,
913 OID_GEN_CURRENT_LOOKAHEAD,
914 0,
915 &BytesWritten);
916 if (NdisStatus != NDIS_STATUS_SUCCESS) {
917 NDIS_DbgPrint(MIN_TRACE, ("OID_GEN_CURRENT_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus));
918 return NdisStatus;
919 }
920
921 Adapter->CurLookaheadLength = *((PULONG)Adapter->QueryBuffer);
922
923 NDIS_DbgPrint(DEBUG_MINIPORT, ("CurLookaheadLength (0x%X).\n", Adapter->CurLookaheadLength));
924
925 if (Adapter->MaxLookaheadLength != 0) {
926 Adapter->LookaheadLength = Adapter->MaxLookaheadLength +
927 Adapter->MediumHeaderSize;
928 Adapter->LookaheadBuffer = ExAllocatePool(NonPagedPool,
929 Adapter->LookaheadLength);
930 if (!Adapter->LookaheadBuffer)
931 return NDIS_STATUS_RESOURCES;
932 }
933
934 return STATUS_SUCCESS;
935 }
936
937
938 NDIS_STATUS
939 EXPORT
940 NdisMRegisterMiniport(
941 IN NDIS_HANDLE NdisWrapperHandle,
942 IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics,
943 IN UINT CharacteristicsLength)
944 /*
945 * FUNCTION: Registers a miniport's MiniportXxx entry points with the NDIS library
946 * ARGUMENTS:
947 * NdisWrapperHandle = Pointer to handle returned by NdisMInitializeWrapper
948 * MiniportCharacteristics = Pointer to a buffer with miniport characteristics
949 * CharacteristicsLength = Number of bytes in characteristics buffer
950 * RETURNS:
951 * Status of operation
952 */
953 {
954 UINT MinSize;
955 KIRQL OldIrql;
956 NTSTATUS Status;
957 NDIS_STATUS NdisStatus;
958 NDIS_STATUS OpenErrorStatus;
959 UINT SelectedMediumIndex;
960 PLOGICAL_ADAPTER Adapter;
961 NDIS_OID AddressOID;
962 BOOLEAN MemError = FALSE;
963 PMINIPORT_DRIVER Miniport = GET_MINIPORT_DRIVER(NdisWrapperHandle);
964
965 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
966
967 switch (MiniportCharacteristics->MajorNdisVersion) {
968 case 0x03:
969 MinSize = sizeof(NDIS30_MINIPORT_CHARACTERISTICS_S);
970 break;
971
972 case 0x04:
973 MinSize = sizeof(NDIS40_MINIPORT_CHARACTERISTICS_S);
974 break;
975
976 case 0x05:
977 MinSize = sizeof(NDIS50_MINIPORT_CHARACTERISTICS_S);
978 break;
979
980 default:
981 NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics version.\n"));
982 return NDIS_STATUS_BAD_VERSION;
983 }
984
985 if (CharacteristicsLength < MinSize) {
986 NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
987 return NDIS_STATUS_BAD_CHARACTERISTICS;
988 }
989
990 /* Check if mandatory MiniportXxx functions are specified */
991 if ((!MiniportCharacteristics->HaltHandler) ||
992 (!MiniportCharacteristics->InitializeHandler)||
993 (!MiniportCharacteristics->QueryInformationHandler) ||
994 (!MiniportCharacteristics->ResetHandler) ||
995 (!MiniportCharacteristics->SetInformationHandler)) {
996 NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
997 return NDIS_STATUS_BAD_CHARACTERISTICS;
998 }
999
1000 if (MiniportCharacteristics->MajorNdisVersion == 0x03) {
1001 if (!MiniportCharacteristics->u1.SendHandler) {
1002 NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
1003 return NDIS_STATUS_BAD_CHARACTERISTICS;
1004 }
1005 } else if (MiniportCharacteristics->MajorNdisVersion >= 0x04) {
1006 /* NDIS 4.0+ */
1007 if ((!MiniportCharacteristics->u1.SendHandler) &&
1008 (!MiniportCharacteristics->SendPacketsHandler)) {
1009 NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
1010 return NDIS_STATUS_BAD_CHARACTERISTICS;
1011 }
1012 }
1013
1014 RtlCopyMemory(&Miniport->Chars, MiniportCharacteristics, MinSize);
1015
1016 Adapter = ExAllocatePool(NonPagedPool, sizeof(LOGICAL_ADAPTER));
1017 if (!Adapter) {
1018 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
1019 return NDIS_STATUS_RESOURCES;
1020 }
1021
1022 /* This is very important */
1023 RtlZeroMemory(Adapter, sizeof(LOGICAL_ADAPTER));
1024
1025 /* Create the device object for this adapter */
1026 /* FIXME: Use GUIDs */
1027 RtlInitUnicodeString(&Adapter->DeviceName, L"\\Device\\ne2000");
1028 Status = IoCreateDevice(Miniport->DriverObject,
1029 0,
1030 &Adapter->DeviceName,
1031 FILE_DEVICE_PHYSICAL_NETCARD,
1032 0,
1033 FALSE,
1034 &Adapter->NdisMiniportBlock.DeviceObject);
1035 if (!NT_SUCCESS(Status)) {
1036 NDIS_DbgPrint(MIN_TRACE, ("Could not create device object.\n"));
1037 ExFreePool(Adapter);
1038 return NDIS_STATUS_FAILURE;
1039 }
1040
1041 /* Initialize adapter object */
1042
1043 KeInitializeSpinLock(&Adapter->NdisMiniportBlock.Lock);
1044
1045 InitializeListHead(&Adapter->ProtocolListHead);
1046
1047 Adapter->RefCount = 1;
1048
1049 Adapter->Miniport = Miniport;
1050
1051 /* Set handlers (some NDIS macros require these) */
1052
1053 Adapter->NdisMiniportBlock.EthRxCompleteHandler = MiniEthReceiveComplete;
1054 Adapter->NdisMiniportBlock.EthRxIndicateHandler = MiniEthReceiveIndication;
1055
1056 Adapter->NdisMiniportBlock.SendCompleteHandler = MiniSendComplete;
1057 Adapter->NdisMiniportBlock.SendResourcesHandler = MiniSendResourcesAvailable;
1058 Adapter->NdisMiniportBlock.ResetCompleteHandler = MiniResetComplete;
1059 Adapter->NdisMiniportBlock.TDCompleteHandler = MiniTransferDataComplete;
1060
1061
1062 KeInitializeDpc(&Adapter->MiniportDpc, MiniportDpc, (PVOID)Adapter);
1063
1064 /* Put adapter in adapter list for this miniport */
1065 ExInterlockedInsertTailList(&Miniport->AdapterListHead,
1066 &Adapter->MiniportListEntry,
1067 &Miniport->Lock);
1068
1069 /* Put adapter in global adapter list */
1070 ExInterlockedInsertTailList(&AdapterListHead,
1071 &Adapter->ListEntry,
1072 &AdapterListLock);
1073
1074 /* Call MiniportInitialize */
1075 NdisStatus = (*Miniport->Chars.InitializeHandler)(
1076 &OpenErrorStatus,
1077 &SelectedMediumIndex,
1078 &MediaArray[0],
1079 MEDIA_ARRAY_SIZE,
1080 Adapter,
1081 NULL /* FIXME: WrapperConfigurationContext */);
1082
1083 if ((NdisStatus == NDIS_STATUS_SUCCESS) &&
1084 (SelectedMediumIndex < MEDIA_ARRAY_SIZE)) {
1085
1086 Adapter->NdisMiniportBlock.MediaType = MediaArray[SelectedMediumIndex];
1087
1088 switch (Adapter->NdisMiniportBlock.MediaType) {
1089 case NdisMedium802_3:
1090 Adapter->MediumHeaderSize = 14;
1091 AddressOID = OID_802_3_CURRENT_ADDRESS;
1092 Adapter->AddressLength = ETH_LENGTH_OF_ADDRESS;
1093
1094 Adapter->NdisMiniportBlock.FilterDbs.u.EthDB = ExAllocatePool(NonPagedPool,
1095 sizeof(ETH_FILTER));
1096 if (Adapter->NdisMiniportBlock.FilterDbs.u.EthDB) {
1097 RtlZeroMemory(Adapter->NdisMiniportBlock.FilterDbs.u.EthDB, sizeof(ETH_FILTER));
1098 Adapter->NdisMiniportBlock.FilterDbs.u.EthDB->Miniport = (PNDIS_MINIPORT_BLOCK)Adapter;
1099 } else
1100 MemError = TRUE;
1101 break;
1102
1103 default:
1104 /* FIXME: Support other types of medias */
1105 ASSERT(FALSE);
1106 return NDIS_STATUS_FAILURE;
1107 }
1108
1109 NdisStatus = DoQueries(Adapter, AddressOID);
1110 }
1111
1112 if ((MemError) ||
1113 (NdisStatus != NDIS_STATUS_SUCCESS) ||
1114 (SelectedMediumIndex >= MEDIA_ARRAY_SIZE)) {
1115
1116 /* Remove adapter from adapter list for this miniport */
1117 KeAcquireSpinLock(&Miniport->Lock, &OldIrql);
1118 RemoveEntryList(&Adapter->MiniportListEntry);
1119 KeReleaseSpinLock(&Miniport->Lock, OldIrql);
1120
1121 /* Remove adapter from global adapter list */
1122 KeAcquireSpinLock(&AdapterListLock, &OldIrql);
1123 RemoveEntryList(&Adapter->ListEntry);
1124 KeReleaseSpinLock(&AdapterListLock, OldIrql);
1125
1126 if (Adapter->LookaheadBuffer)
1127 ExFreePool(Adapter->LookaheadBuffer);
1128
1129 IoDeleteDevice(Adapter->NdisMiniportBlock.DeviceObject);
1130 ExFreePool(Adapter);
1131 return NDIS_STATUS_FAILURE;
1132 }
1133
1134 return NDIS_STATUS_SUCCESS;
1135 }
1136
1137
1138 VOID
1139 EXPORT
1140 NdisMResetComplete(
1141 IN NDIS_HANDLE MiniportAdapterHandle,
1142 IN NDIS_STATUS Status,
1143 IN BOOLEAN AddressingReset)
1144 {
1145 MiniResetComplete(MiniportAdapterHandle,
1146 Status,
1147 AddressingReset);
1148 }
1149
1150
1151 VOID
1152 EXPORT
1153 NdisMSendComplete(
1154 IN NDIS_HANDLE MiniportAdapterHandle,
1155 IN PNDIS_PACKET Packet,
1156 IN NDIS_STATUS Status)
1157 /*
1158 * FUNCTION: Forwards a message to the initiating protocol saying
1159 * that a packet was handled
1160 * ARGUMENTS:
1161 * NdisAdapterHandle = Handle input to MiniportInitialize
1162 * Packet = Pointer to NDIS packet that was sent
1163 * Status = Status of send operation
1164 */
1165 {
1166 MiniSendComplete(MiniportAdapterHandle,
1167 Packet,
1168 Status);
1169 }
1170
1171
1172 VOID
1173 EXPORT
1174 NdisMSendResourcesAvailable(
1175 IN NDIS_HANDLE MiniportAdapterHandle)
1176 {
1177 MiniSendResourcesAvailable(MiniportAdapterHandle);
1178 }
1179
1180
1181 VOID
1182 EXPORT
1183 NdisMTransferDataComplete(
1184 IN NDIS_HANDLE MiniportAdapterHandle,
1185 IN PNDIS_PACKET Packet,
1186 IN NDIS_STATUS Status,
1187 IN UINT BytesTransferred)
1188 {
1189 MiniTransferDataComplete(MiniportAdapterHandle,
1190 Packet,
1191 Status,
1192 BytesTransferred);
1193 }
1194
1195
1196 VOID
1197 EXPORT
1198 NdisMSetInformationComplete(
1199 IN NDIS_HANDLE MiniportAdapterHandle,
1200 IN NDIS_STATUS Status)
1201 {
1202 PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(MiniportAdapterHandle);
1203 PADAPTER_BINDING AdapterBinding = (PADAPTER_BINDING)Adapter->MiniportAdapterBinding;
1204
1205 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
1206
1207 (*AdapterBinding->ProtocolBinding->Chars.RequestCompleteHandler)(
1208 AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
1209 Adapter->NdisMiniportBlock.MediaRequest,
1210 Status);
1211 }
1212
1213
1214 VOID
1215 EXPORT
1216 NdisMSetAttributes(
1217 IN NDIS_HANDLE MiniportAdapterHandle,
1218 IN NDIS_HANDLE MiniportAdapterContext,
1219 IN BOOLEAN BusMaster,
1220 IN NDIS_INTERFACE_TYPE AdapterType)
1221 /*
1222 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
1223 * ARGUMENTS:
1224 * MiniportAdapterHandle = Handle input to MiniportInitialize
1225 * MiniportAdapterContext = Pointer to context information
1226 * BusMaster = Specifies TRUE if the caller's NIC is a busmaster DMA device
1227 * AdapterType = Specifies the I/O bus interface of the caller's NIC
1228 */
1229 {
1230 PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(MiniportAdapterHandle);
1231
1232 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
1233
1234 Adapter->NdisMiniportBlock.MiniportAdapterContext = MiniportAdapterContext;
1235 Adapter->Attributes = BusMaster? NDIS_ATTRIBUTE_BUS_MASTER : 0;
1236 Adapter->NdisMiniportBlock.AdapterType = AdapterType;
1237 Adapter->AttributesSet = TRUE;
1238 }
1239
1240
1241 VOID
1242 EXPORT
1243 NdisMSetAttributesEx(
1244 IN NDIS_HANDLE MiniportAdapterHandle,
1245 IN NDIS_HANDLE MiniportAdapterContext,
1246 IN UINT CheckForHangTimeInSeconds OPTIONAL,
1247 IN ULONG AttributeFlags,
1248 IN NDIS_INTERFACE_TYPE AdapterType)
1249 /*
1250 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
1251 * ARGUMENTS:
1252 * MiniportAdapterHandle = Handle input to MiniportInitialize
1253 * MiniportAdapterContext = Pointer to context information
1254 * CheckForHangTimeInSeconds = Specifies interval in seconds at which
1255 * MiniportCheckForHang should be called
1256 * AttributeFlags = Bitmask that indicates specific attributes
1257 * AdapterType = Specifies the I/O bus interface of the caller's NIC
1258 */
1259 {
1260 UNIMPLEMENTED
1261 }
1262
1263
1264 VOID
1265 EXPORT
1266 NdisMSleep(
1267 IN ULONG MicrosecondsToSleep)
1268 {
1269 UNIMPLEMENTED
1270 }
1271
1272
1273 BOOLEAN
1274 EXPORT
1275 NdisMSynchronizeWithInterrupt(
1276 IN PNDIS_MINIPORT_INTERRUPT Interrupt,
1277 IN PVOID SynchronizeFunction,
1278 IN PVOID SynchronizeContext)
1279 {
1280 UNIMPLEMENTED
1281
1282 return FALSE;
1283 }
1284
1285
1286 NDIS_STATUS
1287 EXPORT
1288 NdisMWriteLogData(
1289 IN NDIS_HANDLE LogHandle,
1290 IN PVOID LogBuffer,
1291 IN UINT LogBufferSize)
1292 {
1293 UNIMPLEMENTED
1294
1295 return NDIS_STATUS_FAILURE;
1296 }
1297
1298
1299 VOID
1300 EXPORT
1301 NdisTerminateWrapper(
1302 IN NDIS_HANDLE NdisWrapperHandle,
1303 IN PVOID SystemSpecific)
1304 /*
1305 * FUNCTION: Releases resources allocated by a call to NdisInitializeWrapper
1306 * ARGUMENTS:
1307 * NdisWrapperHandle = Handle returned by NdisInitializeWrapper (MINIPORT_DRIVER)
1308 * SystemSpecific = Always NULL
1309 */
1310 {
1311 PMINIPORT_DRIVER Miniport = GET_MINIPORT_DRIVER(NdisWrapperHandle);
1312
1313 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
1314
1315 ExFreePool(Miniport);
1316 }
1317
1318 /* EOF */