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