Make NdisMRegisterMiniport() say (MIN_TRACE) about failure of a call to driver's...
[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 /*
725 * @unimplemented
726 */
727 VOID
728 EXPORT
729 NdisMCloseLog(
730 IN NDIS_HANDLE LogHandle)
731 {
732 UNIMPLEMENTED
733 }
734
735
736 /*
737 * @unimplemented
738 */
739 NDIS_STATUS
740 EXPORT
741 NdisMCreateLog(
742 IN NDIS_HANDLE MiniportAdapterHandle,
743 IN UINT Size,
744 OUT PNDIS_HANDLE LogHandle)
745 {
746 UNIMPLEMENTED
747
748 return NDIS_STATUS_FAILURE;
749 }
750
751
752 /*
753 * @unimplemented
754 */
755 VOID
756 EXPORT
757 NdisMDeregisterAdapterShutdownHandler(
758 IN NDIS_HANDLE MiniportHandle)
759 {
760 UNIMPLEMENTED
761 }
762
763
764 /*
765 * @unimplemented
766 */
767 VOID
768 EXPORT
769 NdisMFlushLog(
770 IN NDIS_HANDLE LogHandle)
771 {
772 UNIMPLEMENTED
773 }
774
775
776 /*
777 * @unimplemented
778 */
779 VOID
780 EXPORT
781 NdisMIndicateStatus(
782 IN NDIS_HANDLE MiniportAdapterHandle,
783 IN NDIS_STATUS GeneralStatus,
784 IN PVOID StatusBuffer,
785 IN UINT StatusBufferSize)
786 {
787 UNIMPLEMENTED
788 }
789
790
791 /*
792 * @unimplemented
793 */
794 VOID
795 EXPORT
796 NdisMIndicateStatusComplete(
797 IN NDIS_HANDLE MiniportAdapterHandle)
798 {
799 UNIMPLEMENTED
800 }
801
802
803 /*
804 * @implemented
805 */
806 VOID
807 EXPORT
808 NdisInitializeWrapper(
809 OUT PNDIS_HANDLE NdisWrapperHandle,
810 IN PVOID SystemSpecific1,
811 IN PVOID SystemSpecific2,
812 IN PVOID SystemSpecific3)
813 /*
814 * FUNCTION: Notifies the NDIS library that a new miniport is initializing
815 * ARGUMENTS:
816 * NdisWrapperHandle = Address of buffer to place NDIS wrapper handle
817 * SystemSpecific1 = Pointer to the driver's driver object
818 * SystemSpecific2 = Pointer to the driver's registry path
819 * SystemSpecific3 = Always NULL
820 */
821 {
822 PMINIPORT_DRIVER Miniport;
823
824 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
825
826 Miniport = ExAllocatePool(NonPagedPool, sizeof(MINIPORT_DRIVER));
827 if (!Miniport) {
828 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
829 *NdisWrapperHandle = NULL;
830 return;
831 }
832
833 RtlZeroMemory(Miniport, sizeof(MINIPORT_DRIVER));
834
835 KeInitializeSpinLock(&Miniport->Lock);
836
837 Miniport->RefCount = 1;
838
839 Miniport->DriverObject = (PDRIVER_OBJECT)SystemSpecific1;
840
841 InitializeListHead(&Miniport->AdapterListHead);
842
843 /* Put miniport in global miniport list */
844 ExInterlockedInsertTailList(&MiniportListHead,
845 &Miniport->ListEntry,
846 &MiniportListLock);
847
848 *NdisWrapperHandle = Miniport;
849 }
850
851
852 /*
853 * @implemented
854 */
855 VOID
856 EXPORT
857 NdisMQueryInformationComplete(
858 IN NDIS_HANDLE MiniportAdapterHandle,
859 IN NDIS_STATUS Status)
860 {
861 PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(MiniportAdapterHandle);
862 PADAPTER_BINDING AdapterBinding = (PADAPTER_BINDING)Adapter->MiniportAdapterBinding;
863
864 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
865
866 (*AdapterBinding->ProtocolBinding->Chars.RequestCompleteHandler)(
867 AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
868 Adapter->NdisMiniportBlock.MediaRequest,
869 Status);
870 }
871
872
873 /*
874 * @unimplemented
875 */
876 VOID
877 EXPORT
878 NdisMRegisterAdapterShutdownHandler(
879 IN NDIS_HANDLE MiniportHandle,
880 IN PVOID ShutdownContext,
881 IN ADAPTER_SHUTDOWN_HANDLER ShutdownHandler)
882 {
883 UNIMPLEMENTED
884 }
885
886
887 NDIS_STATUS
888 DoQueries(
889 PLOGICAL_ADAPTER Adapter,
890 NDIS_OID AddressOID)
891 /*
892 * FUNCTION: Queries miniport for information
893 * ARGUMENTS:
894 * Adapter = Pointer to logical adapter
895 * AddressOID = OID to use to query for current address
896 * RETURNS:
897 * Status of operation
898 */
899 {
900 ULONG BytesWritten;
901 NDIS_STATUS NdisStatus;
902
903 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
904
905 /* Get MAC options for adapter */
906 NdisStatus = MiniQueryInformation(Adapter,
907 OID_GEN_MAC_OPTIONS,
908 0,
909 &BytesWritten);
910 if (NdisStatus != NDIS_STATUS_SUCCESS) {
911 NDIS_DbgPrint(MIN_TRACE, ("OID_GEN_MAC_OPTIONS failed. NdisStatus (0x%X).\n", NdisStatus));
912 return NdisStatus;
913 }
914
915 RtlCopyMemory(&Adapter->NdisMiniportBlock.MacOptions, Adapter->QueryBuffer, sizeof(UINT));
916
917 NDIS_DbgPrint(DEBUG_MINIPORT, ("MacOptions (0x%X).\n", Adapter->NdisMiniportBlock.MacOptions));
918
919 /* Get current hardware address of adapter */
920 NdisStatus = MiniQueryInformation(Adapter,
921 AddressOID,
922 0,
923 &BytesWritten);
924 if (NdisStatus != NDIS_STATUS_SUCCESS) {
925 NDIS_DbgPrint(MIN_TRACE, ("Address OID (0x%X) failed. NdisStatus (0x%X).\n",
926 AddressOID, NdisStatus));
927 return NdisStatus;
928 }
929
930 RtlCopyMemory(&Adapter->Address, Adapter->QueryBuffer, Adapter->AddressLength);
931 #ifdef DBG
932 {
933 /* 802.3 only */
934
935 PUCHAR A = (PUCHAR)&Adapter->Address.Type.Medium802_3;
936
937 NDIS_DbgPrint(MAX_TRACE, ("Adapter address is (%02X %02X %02X %02X %02X %02X).\n",
938 A[0], A[1], A[2], A[3], A[4], A[5]));
939 }
940 #endif /* DBG */
941
942 /* Get maximum lookahead buffer size of adapter */
943 NdisStatus = MiniQueryInformation(Adapter,
944 OID_GEN_MAXIMUM_LOOKAHEAD,
945 0,
946 &BytesWritten);
947 if (NdisStatus != NDIS_STATUS_SUCCESS) {
948 NDIS_DbgPrint(MIN_TRACE, ("OID_GEN_MAXIMUM_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus));
949 return NdisStatus;
950 }
951
952 Adapter->MaxLookaheadLength = *((PULONG)Adapter->QueryBuffer);
953
954 NDIS_DbgPrint(DEBUG_MINIPORT, ("MaxLookaheadLength (0x%X).\n", Adapter->MaxLookaheadLength));
955
956 /* Get current lookahead buffer size of adapter */
957 NdisStatus = MiniQueryInformation(Adapter,
958 OID_GEN_CURRENT_LOOKAHEAD,
959 0,
960 &BytesWritten);
961 if (NdisStatus != NDIS_STATUS_SUCCESS) {
962 NDIS_DbgPrint(MIN_TRACE, ("OID_GEN_CURRENT_LOOKAHEAD failed. NdisStatus (0x%X).\n", NdisStatus));
963 return NdisStatus;
964 }
965
966 Adapter->CurLookaheadLength = *((PULONG)Adapter->QueryBuffer);
967
968 NDIS_DbgPrint(DEBUG_MINIPORT, ("CurLookaheadLength (0x%X).\n", Adapter->CurLookaheadLength));
969
970 if (Adapter->MaxLookaheadLength != 0) {
971 Adapter->LookaheadLength = Adapter->MaxLookaheadLength +
972 Adapter->MediumHeaderSize;
973 Adapter->LookaheadBuffer = ExAllocatePool(NonPagedPool,
974 Adapter->LookaheadLength);
975 if (!Adapter->LookaheadBuffer)
976 return NDIS_STATUS_RESOURCES;
977 }
978
979 return STATUS_SUCCESS;
980 }
981
982
983 /*
984 * @implemented
985 */
986 NDIS_STATUS
987 EXPORT
988 NdisMRegisterMiniport(
989 IN NDIS_HANDLE NdisWrapperHandle,
990 IN PNDIS_MINIPORT_CHARACTERISTICS MiniportCharacteristics,
991 IN UINT CharacteristicsLength)
992 /*
993 * FUNCTION: Registers a miniport's MiniportXxx entry points with the NDIS library
994 * ARGUMENTS:
995 * NdisWrapperHandle = Pointer to handle returned by NdisMInitializeWrapper
996 * MiniportCharacteristics = Pointer to a buffer with miniport characteristics
997 * CharacteristicsLength = Number of bytes in characteristics buffer
998 * RETURNS:
999 * Status of operation
1000 */
1001 {
1002 UINT MinSize;
1003 KIRQL OldIrql;
1004 NTSTATUS Status;
1005 NDIS_STATUS NdisStatus;
1006 NDIS_STATUS OpenErrorStatus;
1007 UINT SelectedMediumIndex;
1008 PLOGICAL_ADAPTER Adapter;
1009 NDIS_OID AddressOID;
1010 BOOLEAN MemError = FALSE;
1011 PMINIPORT_DRIVER Miniport = GET_MINIPORT_DRIVER(NdisWrapperHandle);
1012
1013 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
1014
1015 switch (MiniportCharacteristics->MajorNdisVersion) {
1016 case 0x03:
1017 MinSize = sizeof(NDIS30_MINIPORT_CHARACTERISTICS_S);
1018 break;
1019
1020 case 0x04:
1021 MinSize = sizeof(NDIS40_MINIPORT_CHARACTERISTICS_S);
1022 break;
1023
1024 case 0x05:
1025 MinSize = sizeof(NDIS50_MINIPORT_CHARACTERISTICS_S);
1026 break;
1027
1028 default:
1029 NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics version.\n"));
1030 return NDIS_STATUS_BAD_VERSION;
1031 }
1032
1033 if (CharacteristicsLength < MinSize) {
1034 NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
1035 return NDIS_STATUS_BAD_CHARACTERISTICS;
1036 }
1037
1038 /* Check if mandatory MiniportXxx functions are specified */
1039 if ((!MiniportCharacteristics->HaltHandler) ||
1040 (!MiniportCharacteristics->InitializeHandler)||
1041 (!MiniportCharacteristics->QueryInformationHandler) ||
1042 (!MiniportCharacteristics->ResetHandler) ||
1043 (!MiniportCharacteristics->SetInformationHandler)) {
1044 NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
1045 return NDIS_STATUS_BAD_CHARACTERISTICS;
1046 }
1047
1048 if (MiniportCharacteristics->MajorNdisVersion == 0x03) {
1049 if (!MiniportCharacteristics->u1.SendHandler) {
1050 NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
1051 return NDIS_STATUS_BAD_CHARACTERISTICS;
1052 }
1053 } else if (MiniportCharacteristics->MajorNdisVersion >= 0x04) {
1054 /* NDIS 4.0+ */
1055 if ((!MiniportCharacteristics->u1.SendHandler) &&
1056 (!MiniportCharacteristics->SendPacketsHandler)) {
1057 NDIS_DbgPrint(DEBUG_MINIPORT, ("Bad miniport characteristics.\n"));
1058 return NDIS_STATUS_BAD_CHARACTERISTICS;
1059 }
1060 }
1061
1062 RtlCopyMemory(&Miniport->Chars, MiniportCharacteristics, MinSize);
1063
1064 Adapter = ExAllocatePool(NonPagedPool, sizeof(LOGICAL_ADAPTER));
1065 if (!Adapter) {
1066 NDIS_DbgPrint(MIN_TRACE, ("Insufficient resources.\n"));
1067 return NDIS_STATUS_RESOURCES;
1068 }
1069
1070 /* This is very important */
1071 RtlZeroMemory(Adapter, sizeof(LOGICAL_ADAPTER));
1072
1073 /* Create the device object for this adapter */
1074 /* FIXME: Use GUIDs */
1075 RtlInitUnicodeStringFromLiteral(&Adapter->DeviceName, L"\\Device\\ne2000");
1076 Status = IoCreateDevice(Miniport->DriverObject,
1077 0,
1078 &Adapter->DeviceName,
1079 FILE_DEVICE_PHYSICAL_NETCARD,
1080 0,
1081 FALSE,
1082 &Adapter->NdisMiniportBlock.DeviceObject);
1083 if (!NT_SUCCESS(Status)) {
1084 NDIS_DbgPrint(MIN_TRACE, ("Could not create device object.\n"));
1085 ExFreePool(Adapter);
1086 return NDIS_STATUS_FAILURE;
1087 }
1088
1089 /* Initialize adapter object */
1090
1091 KeInitializeSpinLock(&Adapter->NdisMiniportBlock.Lock);
1092
1093 InitializeListHead(&Adapter->ProtocolListHead);
1094
1095 Adapter->RefCount = 1;
1096
1097 Adapter->Miniport = Miniport;
1098
1099 /* Set handlers (some NDIS macros require these) */
1100
1101 Adapter->NdisMiniportBlock.EthRxCompleteHandler = MiniEthReceiveComplete;
1102 Adapter->NdisMiniportBlock.EthRxIndicateHandler = MiniEthReceiveIndication;
1103
1104 Adapter->NdisMiniportBlock.SendCompleteHandler = MiniSendComplete;
1105 Adapter->NdisMiniportBlock.SendResourcesHandler = MiniSendResourcesAvailable;
1106 Adapter->NdisMiniportBlock.ResetCompleteHandler = MiniResetComplete;
1107 Adapter->NdisMiniportBlock.TDCompleteHandler = MiniTransferDataComplete;
1108
1109
1110 KeInitializeDpc(&Adapter->MiniportDpc, MiniportDpc, (PVOID)Adapter);
1111
1112 /* Put adapter in adapter list for this miniport */
1113 ExInterlockedInsertTailList(&Miniport->AdapterListHead,
1114 &Adapter->MiniportListEntry,
1115 &Miniport->Lock);
1116
1117 /* Put adapter in global adapter list */
1118 ExInterlockedInsertTailList(&AdapterListHead,
1119 &Adapter->ListEntry,
1120 &AdapterListLock);
1121
1122 /* Call MiniportInitialize */
1123 NdisStatus = (*Miniport->Chars.InitializeHandler)(
1124 &OpenErrorStatus,
1125 &SelectedMediumIndex,
1126 &MediaArray[0],
1127 MEDIA_ARRAY_SIZE,
1128 Adapter,
1129 NULL /* FIXME: WrapperConfigurationContext */);
1130
1131 if ((NdisStatus == NDIS_STATUS_SUCCESS) &&
1132 (SelectedMediumIndex < MEDIA_ARRAY_SIZE)) {
1133
1134 Adapter->NdisMiniportBlock.MediaType = MediaArray[SelectedMediumIndex];
1135
1136 switch (Adapter->NdisMiniportBlock.MediaType) {
1137 case NdisMedium802_3:
1138 Adapter->MediumHeaderSize = 14;
1139 AddressOID = OID_802_3_CURRENT_ADDRESS;
1140 Adapter->AddressLength = ETH_LENGTH_OF_ADDRESS;
1141
1142 Adapter->NdisMiniportBlock.FilterDbs.u.EthDB = ExAllocatePool(NonPagedPool,
1143 sizeof(ETH_FILTER));
1144 if (Adapter->NdisMiniportBlock.FilterDbs.u.EthDB) {
1145 RtlZeroMemory(Adapter->NdisMiniportBlock.FilterDbs.u.EthDB, sizeof(ETH_FILTER));
1146 Adapter->NdisMiniportBlock.FilterDbs.u.EthDB->Miniport = (PNDIS_MINIPORT_BLOCK)Adapter;
1147 } else
1148 MemError = TRUE;
1149 break;
1150
1151 default:
1152 /* FIXME: Support other types of medias */
1153 ASSERT(FALSE);
1154 return NDIS_STATUS_FAILURE;
1155 }
1156
1157 NdisStatus = DoQueries(Adapter, AddressOID);
1158 }
1159
1160 if ((MemError) ||
1161 (NdisStatus != NDIS_STATUS_SUCCESS) ||
1162 (SelectedMediumIndex >= MEDIA_ARRAY_SIZE)) {
1163
1164 /* Remove adapter from adapter list for this miniport */
1165 KeAcquireSpinLock(&Miniport->Lock, &OldIrql);
1166 RemoveEntryList(&Adapter->MiniportListEntry);
1167 KeReleaseSpinLock(&Miniport->Lock, OldIrql);
1168
1169 /* Remove adapter from global adapter list */
1170 KeAcquireSpinLock(&AdapterListLock, &OldIrql);
1171 RemoveEntryList(&Adapter->ListEntry);
1172 KeReleaseSpinLock(&AdapterListLock, OldIrql);
1173
1174 if (Adapter->LookaheadBuffer)
1175 ExFreePool(Adapter->LookaheadBuffer);
1176
1177 IoDeleteDevice(Adapter->NdisMiniportBlock.DeviceObject);
1178 ExFreePool(Adapter);
1179 NDIS_DbgPrint(MIN_TRACE, ("MiniportInitialize() failed.\n"));
1180 return NDIS_STATUS_FAILURE;
1181 }
1182
1183 return NDIS_STATUS_SUCCESS;
1184 }
1185
1186
1187 /*
1188 * @implemented
1189 */
1190 VOID
1191 EXPORT
1192 NdisMResetComplete(
1193 IN NDIS_HANDLE MiniportAdapterHandle,
1194 IN NDIS_STATUS Status,
1195 IN BOOLEAN AddressingReset)
1196 {
1197 MiniResetComplete(MiniportAdapterHandle,
1198 Status,
1199 AddressingReset);
1200 }
1201
1202
1203 /*
1204 * @implemented
1205 */
1206 VOID
1207 EXPORT
1208 NdisMSendComplete(
1209 IN NDIS_HANDLE MiniportAdapterHandle,
1210 IN PNDIS_PACKET Packet,
1211 IN NDIS_STATUS Status)
1212 /*
1213 * FUNCTION: Forwards a message to the initiating protocol saying
1214 * that a packet was handled
1215 * ARGUMENTS:
1216 * NdisAdapterHandle = Handle input to MiniportInitialize
1217 * Packet = Pointer to NDIS packet that was sent
1218 * Status = Status of send operation
1219 */
1220 {
1221 MiniSendComplete(MiniportAdapterHandle,
1222 Packet,
1223 Status);
1224 }
1225
1226
1227 /*
1228 * @implemented
1229 */
1230 VOID
1231 EXPORT
1232 NdisMSendResourcesAvailable(
1233 IN NDIS_HANDLE MiniportAdapterHandle)
1234 {
1235 MiniSendResourcesAvailable(MiniportAdapterHandle);
1236 }
1237
1238
1239 /*
1240 * @implemented
1241 */
1242 VOID
1243 EXPORT
1244 NdisMTransferDataComplete(
1245 IN NDIS_HANDLE MiniportAdapterHandle,
1246 IN PNDIS_PACKET Packet,
1247 IN NDIS_STATUS Status,
1248 IN UINT BytesTransferred)
1249 {
1250 MiniTransferDataComplete(MiniportAdapterHandle,
1251 Packet,
1252 Status,
1253 BytesTransferred);
1254 }
1255
1256
1257 /*
1258 * @implemented
1259 */
1260 VOID
1261 EXPORT
1262 NdisMSetInformationComplete(
1263 IN NDIS_HANDLE MiniportAdapterHandle,
1264 IN NDIS_STATUS Status)
1265 {
1266 PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(MiniportAdapterHandle);
1267 PADAPTER_BINDING AdapterBinding = (PADAPTER_BINDING)Adapter->MiniportAdapterBinding;
1268
1269 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
1270
1271 (*AdapterBinding->ProtocolBinding->Chars.RequestCompleteHandler)(
1272 AdapterBinding->NdisOpenBlock.ProtocolBindingContext,
1273 Adapter->NdisMiniportBlock.MediaRequest,
1274 Status);
1275 }
1276
1277
1278 /*
1279 * @implemented
1280 */
1281 VOID
1282 EXPORT
1283 NdisMSetAttributes(
1284 IN NDIS_HANDLE MiniportAdapterHandle,
1285 IN NDIS_HANDLE MiniportAdapterContext,
1286 IN BOOLEAN BusMaster,
1287 IN NDIS_INTERFACE_TYPE AdapterType)
1288 /*
1289 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
1290 * ARGUMENTS:
1291 * MiniportAdapterHandle = Handle input to MiniportInitialize
1292 * MiniportAdapterContext = Pointer to context information
1293 * BusMaster = Specifies TRUE if the caller's NIC is a busmaster DMA device
1294 * AdapterType = Specifies the I/O bus interface of the caller's NIC
1295 */
1296 {
1297 PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(MiniportAdapterHandle);
1298
1299 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
1300
1301 Adapter->NdisMiniportBlock.MiniportAdapterContext = MiniportAdapterContext;
1302 Adapter->Attributes = BusMaster? NDIS_ATTRIBUTE_BUS_MASTER : 0;
1303 Adapter->NdisMiniportBlock.AdapterType = AdapterType;
1304 Adapter->AttributesSet = TRUE;
1305 }
1306
1307
1308 /*
1309 * @implemented
1310 */
1311 VOID
1312 EXPORT
1313 NdisMSetAttributesEx(
1314 IN NDIS_HANDLE MiniportAdapterHandle,
1315 IN NDIS_HANDLE MiniportAdapterContext,
1316 IN UINT CheckForHangTimeInSeconds OPTIONAL,
1317 IN ULONG AttributeFlags,
1318 IN NDIS_INTERFACE_TYPE AdapterType)
1319 /*
1320 * FUNCTION: Informs the NDIS library of significant features of the caller's NIC
1321 * ARGUMENTS:
1322 * MiniportAdapterHandle = Handle input to MiniportInitialize
1323 * MiniportAdapterContext = Pointer to context information
1324 * CheckForHangTimeInSeconds = Specifies interval in seconds at which
1325 * MiniportCheckForHang should be called
1326 * AttributeFlags = Bitmask that indicates specific attributes
1327 * AdapterType = Specifies the I/O bus interface of the caller's NIC
1328 */
1329 {
1330 // Currently just like NdisMSetAttributesEx
1331 // TODO: Take CheckForHandTimeInSeconds into account!
1332 PLOGICAL_ADAPTER Adapter = GET_LOGICAL_ADAPTER(MiniportAdapterHandle);
1333
1334 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
1335 NDIS_DbgPrint(MIN_TRACE, ("NdisMSetAttributesEx() is partly-implemented."));
1336
1337 Adapter->NdisMiniportBlock.MiniportAdapterContext = MiniportAdapterContext;
1338 Adapter->Attributes = AttributeFlags & NDIS_ATTRIBUTE_BUS_MASTER;
1339 Adapter->NdisMiniportBlock.AdapterType = AdapterType;
1340 Adapter->AttributesSet = TRUE;
1341 }
1342
1343
1344 /*
1345 * @unimplemented
1346 */
1347 VOID
1348 EXPORT
1349 NdisMSleep(
1350 IN ULONG MicrosecondsToSleep)
1351 {
1352 UNIMPLEMENTED
1353 }
1354
1355
1356 /*
1357 * @unimplemented
1358 */
1359 BOOLEAN
1360 EXPORT
1361 NdisMSynchronizeWithInterrupt(
1362 IN PNDIS_MINIPORT_INTERRUPT Interrupt,
1363 IN PVOID SynchronizeFunction,
1364 IN PVOID SynchronizeContext)
1365 {
1366 UNIMPLEMENTED
1367
1368 return FALSE;
1369 }
1370
1371
1372 /*
1373 * @unimplemented
1374 */
1375 NDIS_STATUS
1376 EXPORT
1377 NdisMWriteLogData(
1378 IN NDIS_HANDLE LogHandle,
1379 IN PVOID LogBuffer,
1380 IN UINT LogBufferSize)
1381 {
1382 UNIMPLEMENTED
1383
1384 return NDIS_STATUS_FAILURE;
1385 }
1386
1387
1388 /*
1389 * @implemented
1390 */
1391 VOID
1392 EXPORT
1393 NdisTerminateWrapper(
1394 IN NDIS_HANDLE NdisWrapperHandle,
1395 IN PVOID SystemSpecific)
1396 /*
1397 * FUNCTION: Releases resources allocated by a call to NdisInitializeWrapper
1398 * ARGUMENTS:
1399 * NdisWrapperHandle = Handle returned by NdisInitializeWrapper (MINIPORT_DRIVER)
1400 * SystemSpecific = Always NULL
1401 */
1402 {
1403 PMINIPORT_DRIVER Miniport = GET_MINIPORT_DRIVER(NdisWrapperHandle);
1404
1405 NDIS_DbgPrint(MAX_TRACE, ("Called.\n"));
1406
1407 ExFreePool(Miniport);
1408 }
1409
1410 /* EOF */