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