This repo is obsolete, please see git://git.code.sf.net/p/dummynet/code@master
[ipfw.git] / original_passthru / miniport.c
1 /*++\r
2 \r
3 Copyright (c) 1992-2000  Microsoft Corporation\r
4 \r
5 Module Name:\r
6 \r
7     miniport.c\r
8 \r
9 Abstract:\r
10 \r
11     Ndis Intermediate Miniport driver sample. This is a passthru driver.\r
12 \r
13 Author:\r
14 \r
15 Environment:\r
16 \r
17 \r
18 Revision History:\r
19 \r
20 \r
21 --*/\r
22 \r
23 #include "precomp.h"\r
24 #pragma hdrstop\r
25 \r
26 \r
27 \r
28 NDIS_STATUS\r
29 MPInitialize(\r
30     OUT PNDIS_STATUS             OpenErrorStatus,\r
31     OUT PUINT                    SelectedMediumIndex,\r
32     IN  PNDIS_MEDIUM             MediumArray,\r
33     IN  UINT                     MediumArraySize,\r
34     IN  NDIS_HANDLE              MiniportAdapterHandle,\r
35     IN  NDIS_HANDLE              WrapperConfigurationContext\r
36     )\r
37 /*++\r
38 \r
39 Routine Description:\r
40 \r
41     This is the initialize handler which gets called as a result of\r
42     the BindAdapter handler calling NdisIMInitializeDeviceInstanceEx.\r
43     The context parameter which we pass there is the adapter structure\r
44     which we retrieve here.\r
45 \r
46     Arguments:\r
47 \r
48     OpenErrorStatus            Not used by us.\r
49     SelectedMediumIndex        Place-holder for what media we are using\r
50     MediumArray                Array of ndis media passed down to us to pick from\r
51     MediumArraySize            Size of the array\r
52     MiniportAdapterHandle    The handle NDIS uses to refer to us\r
53     WrapperConfigurationContext    For use by NdisOpenConfiguration\r
54 \r
55 Return Value:\r
56 \r
57     NDIS_STATUS_SUCCESS unless something goes wrong\r
58 \r
59 --*/\r
60 {\r
61     UINT            i;\r
62     PADAPT          pAdapt;\r
63     NDIS_STATUS     Status = NDIS_STATUS_FAILURE;\r
64     NDIS_MEDIUM     Medium;\r
65 \r
66     UNREFERENCED_PARAMETER(WrapperConfigurationContext);\r
67     \r
68     do\r
69     {\r
70         //\r
71         // Start off by retrieving our adapter context and storing\r
72         // the Miniport handle in it.\r
73         //\r
74         pAdapt = NdisIMGetDeviceContext(MiniportAdapterHandle);\r
75         pAdapt->MiniportIsHalted = FALSE;\r
76 \r
77         DBGPRINT(("==> Miniport Initialize: Adapt %p\n", pAdapt));\r
78 \r
79         //\r
80         // Usually we export the medium type of the adapter below as our\r
81         // virtual miniport's medium type. However if the adapter below us\r
82         // is a WAN device, then we claim to be of medium type 802.3.\r
83         //\r
84         Medium = pAdapt->Medium;\r
85 \r
86         if (Medium == NdisMediumWan)\r
87         {\r
88             Medium = NdisMedium802_3;\r
89         }\r
90 \r
91         for (i = 0; i < MediumArraySize; i++)\r
92         {\r
93             if (MediumArray[i] == Medium)\r
94             {\r
95                 *SelectedMediumIndex = i;\r
96                 break;\r
97             }\r
98         }\r
99 \r
100         if (i == MediumArraySize)\r
101         {\r
102             Status = NDIS_STATUS_UNSUPPORTED_MEDIA;\r
103             break;\r
104         }\r
105 \r
106 \r
107         //\r
108         // Set the attributes now. NDIS_ATTRIBUTE_DESERIALIZE enables us\r
109         // to make up-calls to NDIS without having to call NdisIMSwitchToMiniport\r
110         // or NdisIMQueueCallBack. This also forces us to protect our data using\r
111         // spinlocks where appropriate. Also in this case NDIS does not queue\r
112         // packets on our behalf. Since this is a very simple pass-thru\r
113         // miniport, we do not have a need to protect anything. However in\r
114         // a general case there will be a need to use per-adapter spin-locks\r
115         // for the packet queues at the very least.\r
116         //\r
117         NdisMSetAttributesEx(MiniportAdapterHandle,\r
118                              pAdapt,\r
119                              0,                                        // CheckForHangTimeInSeconds\r
120                              NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT    |\r
121                                 NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT|\r
122                                 NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER |\r
123                                 NDIS_ATTRIBUTE_DESERIALIZE |\r
124                                 NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND,\r
125                              0);\r
126 \r
127         pAdapt->MiniportHandle = MiniportAdapterHandle;\r
128         //\r
129         // Initialize LastIndicatedStatus to be NDIS_STATUS_MEDIA_CONNECT\r
130         //\r
131         pAdapt->LastIndicatedStatus = NDIS_STATUS_MEDIA_CONNECT;\r
132         \r
133         //\r
134         // Initialize the power states for both the lower binding (PTDeviceState)\r
135         // and our miniport edge to Powered On.\r
136         //\r
137         pAdapt->MPDeviceState = NdisDeviceStateD0;\r
138         pAdapt->PTDeviceState = NdisDeviceStateD0;\r
139 \r
140         //\r
141         // Add this adapter to the global pAdapt List\r
142         //\r
143         NdisAcquireSpinLock(&GlobalLock);\r
144 \r
145         pAdapt->Next = pAdaptList;\r
146         pAdaptList = pAdapt;\r
147 \r
148         NdisReleaseSpinLock(&GlobalLock);\r
149         \r
150         //\r
151         // Create an ioctl interface\r
152         //\r
153         (VOID)PtRegisterDevice();\r
154 \r
155         Status = NDIS_STATUS_SUCCESS;\r
156     }\r
157     while (FALSE);\r
158 \r
159     //\r
160     // If we had received an UnbindAdapter notification on the underlying\r
161     // adapter, we would have blocked that thread waiting for the IM Init\r
162     // process to complete. Wake up any such thread.\r
163     //\r
164     ASSERT(pAdapt->MiniportInitPending == TRUE);\r
165     pAdapt->MiniportInitPending = FALSE;\r
166     NdisSetEvent(&pAdapt->MiniportInitEvent);\r
167 \r
168     if (Status == NDIS_STATUS_SUCCESS)\r
169     {\r
170         PtReferenceAdapt(pAdapt);\r
171     }\r
172 \r
173     DBGPRINT(("<== Miniport Initialize: Adapt %p, Status %x\n", pAdapt, Status));\r
174 \r
175     *OpenErrorStatus = Status;\r
176 \r
177     \r
178     return Status;\r
179 }\r
180 \r
181 \r
182 NDIS_STATUS\r
183 MPSend(\r
184     IN NDIS_HANDLE             MiniportAdapterContext,\r
185     IN PNDIS_PACKET            Packet,\r
186     IN UINT                    Flags\r
187     )\r
188 /*++\r
189 \r
190 Routine Description:\r
191 \r
192     Send Packet handler. Either this or our SendPackets (array) handler is called\r
193     based on which one is enabled in our Miniport Characteristics.\r
194 \r
195 Arguments:\r
196 \r
197     MiniportAdapterContext    Pointer to the adapter\r
198     Packet                    Packet to send\r
199     Flags                     Unused, passed down below\r
200 \r
201 Return Value:\r
202 \r
203     Return code from NdisSend\r
204 \r
205 --*/\r
206 {\r
207     PADAPT              pAdapt = (PADAPT)MiniportAdapterContext;\r
208     NDIS_STATUS         Status;\r
209     PNDIS_PACKET        MyPacket;\r
210     PVOID               MediaSpecificInfo = NULL;\r
211     ULONG               MediaSpecificInfoSize = 0;\r
212 \r
213     //\r
214     // The driver should fail the send if the virtual miniport is in low \r
215     // power state\r
216     //\r
217     if (pAdapt->MPDeviceState > NdisDeviceStateD0)\r
218     {\r
219          return NDIS_STATUS_FAILURE;\r
220     }\r
221 \r
222 #ifdef NDIS51\r
223     //\r
224     // Use NDIS 5.1 packet stacking:\r
225     //\r
226     {\r
227         PNDIS_PACKET_STACK        pStack;\r
228         BOOLEAN                   Remaining;\r
229 \r
230         //\r
231         // Packet stacks: Check if we can use the same packet for sending down.\r
232         //\r
233 \r
234         pStack = NdisIMGetCurrentPacketStack(Packet, &Remaining);\r
235         if (Remaining)\r
236         {\r
237             //\r
238             // We can reuse "Packet".\r
239             //\r
240             // NOTE: if we needed to keep per-packet information in packets\r
241             // sent down, we can use pStack->IMReserved[].\r
242             //\r
243             ASSERT(pStack);\r
244             //\r
245             // If the below miniport is going to low power state, stop sending down any packet.\r
246             //\r
247             NdisAcquireSpinLock(&pAdapt->Lock);\r
248             if (pAdapt->PTDeviceState > NdisDeviceStateD0)\r
249             {\r
250                 NdisReleaseSpinLock(&pAdapt->Lock);\r
251                 return NDIS_STATUS_FAILURE;\r
252             }\r
253             pAdapt->OutstandingSends++;\r
254             NdisReleaseSpinLock(&pAdapt->Lock);\r
255             NdisSend(&Status,\r
256                      pAdapt->BindingHandle,\r
257                      Packet);\r
258 \r
259             if (Status != NDIS_STATUS_PENDING)\r
260             {\r
261                 ADAPT_DECR_PENDING_SENDS(pAdapt);\r
262             }\r
263 \r
264             return(Status);\r
265         }\r
266     }\r
267 #endif // NDIS51\r
268 \r
269     //\r
270     // We are either not using packet stacks, or there isn't stack space\r
271     // in the original packet passed down to us. Allocate a new packet\r
272     // to wrap the data with.\r
273     //\r
274     //\r
275     // If the below miniport is going to low power state, stop sending down any packet.\r
276     //\r
277     NdisAcquireSpinLock(&pAdapt->Lock);\r
278     if (pAdapt->PTDeviceState > NdisDeviceStateD0)\r
279     {\r
280         NdisReleaseSpinLock(&pAdapt->Lock);\r
281         return NDIS_STATUS_FAILURE;\r
282     \r
283     }\r
284     pAdapt->OutstandingSends++;\r
285     NdisReleaseSpinLock(&pAdapt->Lock);\r
286     \r
287     NdisAllocatePacket(&Status,\r
288                        &MyPacket,\r
289                        pAdapt->SendPacketPoolHandle);\r
290 \r
291     if (Status == NDIS_STATUS_SUCCESS)\r
292     {\r
293         PSEND_RSVD            SendRsvd;\r
294 \r
295         //\r
296         // Save a pointer to the original packet in our reserved\r
297         // area in the new packet. This is needed so that we can\r
298         // get back to the original packet when the new packet's send\r
299         // is completed.\r
300         //\r
301         SendRsvd = (PSEND_RSVD)(MyPacket->ProtocolReserved);\r
302         SendRsvd->OriginalPkt = Packet;\r
303 \r
304         NdisGetPacketFlags(MyPacket) = Flags;\r
305 \r
306         //\r
307         // Set up the new packet so that it describes the same\r
308         // data as the original packet.\r
309         //\r
310         NDIS_PACKET_FIRST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(Packet);\r
311         NDIS_PACKET_LAST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(Packet);\r
312 #ifdef WIN9X\r
313         //\r
314         // Work around the fact that NDIS does not initialize this\r
315         // to FALSE on Win9x.\r
316         //\r
317         NDIS_PACKET_VALID_COUNTS(MyPacket) = FALSE;\r
318 #endif\r
319 \r
320         //\r
321         // Copy the OOB Offset from the original packet to the new\r
322         // packet.\r
323         //\r
324         NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(MyPacket),\r
325                        NDIS_OOB_DATA_FROM_PACKET(Packet),\r
326                        sizeof(NDIS_PACKET_OOB_DATA));\r
327 \r
328 #ifndef WIN9X\r
329         //\r
330         // Copy the right parts of per packet info into the new packet.\r
331         // This API is not available on Win9x since task offload is\r
332         // not supported on that platform.\r
333         //\r
334         NdisIMCopySendPerPacketInfo(MyPacket, Packet);\r
335 #endif\r
336         \r
337         //\r
338         // Copy the Media specific information\r
339         //\r
340         NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(Packet,\r
341                                             &MediaSpecificInfo,\r
342                                             &MediaSpecificInfoSize);\r
343 \r
344         if (MediaSpecificInfo || MediaSpecificInfoSize)\r
345         {\r
346             NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(MyPacket,\r
347                                                 MediaSpecificInfo,\r
348                                                 MediaSpecificInfoSize);\r
349         }\r
350 \r
351         NdisSend(&Status,\r
352                  pAdapt->BindingHandle,\r
353                  MyPacket);\r
354 \r
355 \r
356         if (Status != NDIS_STATUS_PENDING)\r
357         {\r
358 #ifndef WIN9X\r
359             NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket);\r
360 #endif\r
361             NdisFreePacket(MyPacket);\r
362             ADAPT_DECR_PENDING_SENDS(pAdapt);\r
363         }\r
364     }\r
365     else\r
366     {\r
367         ADAPT_DECR_PENDING_SENDS(pAdapt);\r
368         //\r
369         // We are out of packets. Silently drop it. Alternatively we can deal with it:\r
370         //    - By keeping separate send and receive pools\r
371         //    - Dynamically allocate more pools as needed and free them when not needed\r
372         //\r
373     }\r
374 \r
375     return(Status);\r
376 }\r
377 \r
378 \r
379 VOID\r
380 MPSendPackets(\r
381     IN NDIS_HANDLE             MiniportAdapterContext,\r
382     IN PPNDIS_PACKET           PacketArray,\r
383     IN UINT                    NumberOfPackets\r
384     )\r
385 /*++\r
386 \r
387 Routine Description:\r
388 \r
389     Send Packet Array handler. Either this or our SendPacket handler is called\r
390     based on which one is enabled in our Miniport Characteristics.\r
391 \r
392 Arguments:\r
393 \r
394     MiniportAdapterContext     Pointer to our adapter\r
395     PacketArray                Set of packets to send\r
396     NumberOfPackets            Self-explanatory\r
397 \r
398 Return Value:\r
399 \r
400     None\r
401 \r
402 --*/\r
403 {\r
404     PADAPT              pAdapt = (PADAPT)MiniportAdapterContext;\r
405     NDIS_STATUS         Status;\r
406     UINT                i;\r
407     PVOID               MediaSpecificInfo = NULL;\r
408     UINT                MediaSpecificInfoSize = 0;\r
409     \r
410 \r
411     for (i = 0; i < NumberOfPackets; i++)\r
412     {\r
413         PNDIS_PACKET    Packet, MyPacket;\r
414 \r
415         Packet = PacketArray[i];\r
416         //\r
417         // The driver should fail the send if the virtual miniport is in low \r
418         // power state\r
419         //\r
420         if (pAdapt->MPDeviceState > NdisDeviceStateD0)\r
421         {\r
422             NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),\r
423                             Packet,\r
424                             NDIS_STATUS_FAILURE);\r
425             continue;\r
426         }\r
427 \r
428 #ifdef NDIS51\r
429 \r
430         //\r
431         // Use NDIS 5.1 packet stacking:\r
432         //\r
433         {\r
434             PNDIS_PACKET_STACK        pStack;\r
435             BOOLEAN                   Remaining;\r
436 \r
437             //\r
438             // Packet stacks: Check if we can use the same packet for sending down.\r
439             //\r
440             pStack = NdisIMGetCurrentPacketStack(Packet, &Remaining);\r
441             if (Remaining)\r
442             {\r
443                 //\r
444                 // We can reuse "Packet".\r
445                 //\r
446                 // NOTE: if we needed to keep per-packet information in packets\r
447                 // sent down, we can use pStack->IMReserved[].\r
448                 //\r
449                 ASSERT(pStack);\r
450                 //\r
451                 // If the below miniport is going to low power state, stop sending down any packet.\r
452                 //\r
453                 NdisAcquireSpinLock(&pAdapt->Lock);\r
454                 if (pAdapt->PTDeviceState > NdisDeviceStateD0)\r
455                 {\r
456                     NdisReleaseSpinLock(&pAdapt->Lock);\r
457                     NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),\r
458                                         Packet,\r
459                                         NDIS_STATUS_FAILURE);\r
460                 }\r
461                 else\r
462                 {\r
463                     pAdapt->OutstandingSends++;\r
464                     NdisReleaseSpinLock(&pAdapt->Lock);\r
465                 \r
466                     NdisSend(&Status,\r
467                               pAdapt->BindingHandle,\r
468                               Packet);\r
469         \r
470                     if (Status != NDIS_STATUS_PENDING)\r
471                     {\r
472                         NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),\r
473                                             Packet,\r
474                                             Status);\r
475                    \r
476                         ADAPT_DECR_PENDING_SENDS(pAdapt);\r
477                     }\r
478                 }\r
479                 continue;\r
480             }\r
481         }\r
482 #endif\r
483         do \r
484         {\r
485             NdisAcquireSpinLock(&pAdapt->Lock);\r
486             //\r
487             // If the below miniport is going to low power state, stop sending down any packet.\r
488             //\r
489             if (pAdapt->PTDeviceState > NdisDeviceStateD0)\r
490             {\r
491                 NdisReleaseSpinLock(&pAdapt->Lock);\r
492                 Status = NDIS_STATUS_FAILURE;\r
493                 break;\r
494             }\r
495             pAdapt->OutstandingSends++;\r
496             NdisReleaseSpinLock(&pAdapt->Lock);\r
497             \r
498             NdisAllocatePacket(&Status,\r
499                                &MyPacket,\r
500                                pAdapt->SendPacketPoolHandle);\r
501 \r
502             if (Status == NDIS_STATUS_SUCCESS)\r
503             {\r
504                 PSEND_RSVD        SendRsvd;\r
505 \r
506                 SendRsvd = (PSEND_RSVD)(MyPacket->ProtocolReserved);\r
507                 SendRsvd->OriginalPkt = Packet;\r
508 \r
509                 NdisGetPacketFlags(MyPacket) = NdisGetPacketFlags(Packet);\r
510 \r
511                 NDIS_PACKET_FIRST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_FIRST_NDIS_BUFFER(Packet);\r
512                 NDIS_PACKET_LAST_NDIS_BUFFER(MyPacket) = NDIS_PACKET_LAST_NDIS_BUFFER(Packet);\r
513 #ifdef WIN9X\r
514                 //\r
515                 // Work around the fact that NDIS does not initialize this\r
516                 // to FALSE on Win9x.\r
517                 //\r
518                 NDIS_PACKET_VALID_COUNTS(MyPacket) = FALSE;\r
519 #endif // WIN9X\r
520 \r
521                 //\r
522                 // Copy the OOB data from the original packet to the new\r
523                 // packet.\r
524                 //\r
525                 NdisMoveMemory(NDIS_OOB_DATA_FROM_PACKET(MyPacket),\r
526                             NDIS_OOB_DATA_FROM_PACKET(Packet),\r
527                             sizeof(NDIS_PACKET_OOB_DATA));\r
528                 //\r
529                 // Copy relevant parts of the per packet info into the new packet\r
530                 //\r
531 #ifndef WIN9X\r
532                 NdisIMCopySendPerPacketInfo(MyPacket, Packet);\r
533 #endif\r
534 \r
535                 //\r
536                 // Copy the Media specific information\r
537                 //\r
538                 NDIS_GET_PACKET_MEDIA_SPECIFIC_INFO(Packet,\r
539                                                     &MediaSpecificInfo,\r
540                                                     &MediaSpecificInfoSize);\r
541 \r
542                 if (MediaSpecificInfo || MediaSpecificInfoSize)\r
543                 {\r
544                     NDIS_SET_PACKET_MEDIA_SPECIFIC_INFO(MyPacket,\r
545                                                         MediaSpecificInfo,\r
546                                                         MediaSpecificInfoSize);\r
547                 }\r
548 \r
549                 NdisSend(&Status,\r
550                          pAdapt->BindingHandle,\r
551                          MyPacket);\r
552 \r
553                 if (Status != NDIS_STATUS_PENDING)\r
554                 {\r
555 #ifndef WIN9X\r
556                     NdisIMCopySendCompletePerPacketInfo (Packet, MyPacket);\r
557 #endif\r
558                     NdisFreePacket(MyPacket);\r
559                     ADAPT_DECR_PENDING_SENDS(pAdapt);\r
560                 }\r
561             }\r
562             else\r
563             {\r
564                 //\r
565                 // The driver cannot allocate a packet.\r
566                 // \r
567                 ADAPT_DECR_PENDING_SENDS(pAdapt);\r
568             }\r
569         }\r
570         while (FALSE);\r
571 \r
572         if (Status != NDIS_STATUS_PENDING)\r
573         {\r
574             NdisMSendComplete(ADAPT_MINIPORT_HANDLE(pAdapt),\r
575                               Packet,\r
576                               Status);\r
577         }\r
578     }\r
579 }\r
580 \r
581 \r
582 NDIS_STATUS\r
583 MPQueryInformation(\r
584     IN NDIS_HANDLE                MiniportAdapterContext,\r
585     IN NDIS_OID                   Oid,\r
586     IN PVOID                      InformationBuffer,\r
587     IN ULONG                      InformationBufferLength,\r
588     OUT PULONG                    BytesWritten,\r
589     OUT PULONG                    BytesNeeded\r
590     )\r
591 /*++\r
592 \r
593 Routine Description:\r
594 \r
595     Entry point called by NDIS to query for the value of the specified OID.\r
596     Typical processing is to forward the query down to the underlying miniport.\r
597 \r
598     The following OIDs are filtered here:\r
599 \r
600     OID_PNP_QUERY_POWER - return success right here\r
601 \r
602     OID_GEN_SUPPORTED_GUIDS - do not forward, otherwise we will show up\r
603     multiple instances of private GUIDs supported by the underlying miniport.\r
604 \r
605     OID_PNP_CAPABILITIES - we do send this down to the lower miniport, but\r
606     the values returned are postprocessed before we complete this request;\r
607     see PtRequestComplete.\r
608 \r
609     NOTE on OID_TCP_TASK_OFFLOAD - if this IM driver modifies the contents\r
610     of data it passes through such that a lower miniport may not be able\r
611     to perform TCP task offload, then it should not forward this OID down,\r
612     but fail it here with the status NDIS_STATUS_NOT_SUPPORTED. This is to\r
613     avoid performing incorrect transformations on data.\r
614 \r
615     If our miniport edge (upper edge) is at a low-power state, fail the request.\r
616 \r
617     If our protocol edge (lower edge) has been notified of a low-power state,\r
618     we pend this request until the miniport below has been set to D0. Since\r
619     requests to miniports are serialized always, at most a single request will\r
620     be pended.\r
621 \r
622 Arguments:\r
623 \r
624     MiniportAdapterContext    Pointer to the adapter structure\r
625     Oid                       Oid for this query\r
626     InformationBuffer         Buffer for information\r
627     InformationBufferLength   Size of this buffer\r
628     BytesWritten              Specifies how much info is written\r
629     BytesNeeded               In case the buffer is smaller than what we need, tell them how much is needed\r
630 \r
631 \r
632 Return Value:\r
633 \r
634     Return code from the NdisRequest below.\r
635 \r
636 --*/\r
637 {\r
638     PADAPT        pAdapt = (PADAPT)MiniportAdapterContext;\r
639     NDIS_STATUS   Status = NDIS_STATUS_FAILURE;\r
640 \r
641     do\r
642     {\r
643         if (Oid == OID_PNP_QUERY_POWER)\r
644         {\r
645             //\r
646             //  Do not forward this.\r
647             //\r
648             Status = NDIS_STATUS_SUCCESS;\r
649             break;\r
650         }\r
651 \r
652         if (Oid == OID_GEN_SUPPORTED_GUIDS)\r
653         {\r
654             //\r
655             //  Do not forward this, otherwise we will end up with multiple\r
656             //  instances of private GUIDs that the underlying miniport\r
657             //  supports.\r
658             //\r
659             Status = NDIS_STATUS_NOT_SUPPORTED;\r
660             break;\r
661         }\r
662 \r
663         if (Oid == OID_TCP_TASK_OFFLOAD)\r
664         {\r
665             //\r
666             // Fail this -if- this driver performs data transformations\r
667             // that can interfere with a lower driver's ability to offload\r
668             // TCP tasks.\r
669             //\r
670             // Status = NDIS_STATUS_NOT_SUPPORTED;\r
671             // break;\r
672             //\r
673         }\r
674         //\r
675         // If the miniport below is unbinding, just fail any request\r
676         //\r
677         NdisAcquireSpinLock(&pAdapt->Lock);\r
678         if (pAdapt->UnbindingInProcess == TRUE)\r
679         {\r
680             NdisReleaseSpinLock(&pAdapt->Lock);\r
681             Status = NDIS_STATUS_FAILURE;\r
682             break;\r
683         }\r
684         NdisReleaseSpinLock(&pAdapt->Lock);\r
685         //\r
686         // All other queries are failed, if the miniport is not at D0,\r
687         //\r
688         if (pAdapt->MPDeviceState > NdisDeviceStateD0) \r
689         {\r
690             Status = NDIS_STATUS_FAILURE;\r
691             break;\r
692         }\r
693 \r
694         pAdapt->Request.RequestType = NdisRequestQueryInformation;\r
695         pAdapt->Request.DATA.QUERY_INFORMATION.Oid = Oid;\r
696         pAdapt->Request.DATA.QUERY_INFORMATION.InformationBuffer = InformationBuffer;\r
697         pAdapt->Request.DATA.QUERY_INFORMATION.InformationBufferLength = InformationBufferLength;\r
698         pAdapt->BytesNeeded = BytesNeeded;\r
699         pAdapt->BytesReadOrWritten = BytesWritten;\r
700 \r
701         //\r
702         // If the miniport below is binding, fail the request\r
703         //\r
704         NdisAcquireSpinLock(&pAdapt->Lock);\r
705             \r
706         if (pAdapt->UnbindingInProcess == TRUE)\r
707         {\r
708             NdisReleaseSpinLock(&pAdapt->Lock);\r
709             Status = NDIS_STATUS_FAILURE;\r
710             break;\r
711         }\r
712         //\r
713         // If the Protocol device state is OFF, mark this request as being \r
714         // pended. We queue this until the device state is back to D0. \r
715         //\r
716         if ((pAdapt->PTDeviceState > NdisDeviceStateD0) \r
717                 && (pAdapt->StandingBy == FALSE))\r
718         {\r
719             pAdapt->QueuedRequest = TRUE;\r
720             NdisReleaseSpinLock(&pAdapt->Lock);\r
721             Status = NDIS_STATUS_PENDING;\r
722             break;\r
723         }\r
724         //\r
725         // This is in the process of powering down the system, always fail the request\r
726         // \r
727         if (pAdapt->StandingBy == TRUE)\r
728         {\r
729             NdisReleaseSpinLock(&pAdapt->Lock);\r
730             Status = NDIS_STATUS_FAILURE;\r
731             break;\r
732         }\r
733         pAdapt->OutstandingRequests = TRUE;\r
734         \r
735         NdisReleaseSpinLock(&pAdapt->Lock);\r
736 \r
737         //\r
738         // default case, most requests will be passed to the miniport below\r
739         //\r
740         NdisRequest(&Status,\r
741                     pAdapt->BindingHandle,\r
742                     &pAdapt->Request);\r
743 \r
744 \r
745         if (Status != NDIS_STATUS_PENDING)\r
746         {\r
747             PtRequestComplete(pAdapt, &pAdapt->Request, Status);\r
748             Status = NDIS_STATUS_PENDING;\r
749         }\r
750 \r
751     } while (FALSE);\r
752 \r
753     return(Status);\r
754 \r
755 }\r
756 \r
757 \r
758 VOID\r
759 MPQueryPNPCapabilities(\r
760     IN OUT PADAPT            pAdapt,\r
761     OUT PNDIS_STATUS         pStatus\r
762     )\r
763 /*++\r
764 \r
765 Routine Description:\r
766 \r
767     Postprocess a request for OID_PNP_CAPABILITIES that was forwarded\r
768     down to the underlying miniport, and has been completed by it.\r
769 \r
770 Arguments:\r
771 \r
772     pAdapt - Pointer to the adapter structure\r
773     pStatus - Place to return final status\r
774 \r
775 Return Value:\r
776 \r
777     None.\r
778 \r
779 --*/\r
780 \r
781 {\r
782     PNDIS_PNP_CAPABILITIES           pPNPCapabilities;\r
783     PNDIS_PM_WAKE_UP_CAPABILITIES    pPMstruct;\r
784 \r
785     if (pAdapt->Request.DATA.QUERY_INFORMATION.InformationBufferLength >= sizeof(NDIS_PNP_CAPABILITIES))\r
786     {\r
787         pPNPCapabilities = (PNDIS_PNP_CAPABILITIES)(pAdapt->Request.DATA.QUERY_INFORMATION.InformationBuffer);\r
788 \r
789         //\r
790         // The following fields must be overwritten by an IM driver.\r
791         //\r
792         pPMstruct= & pPNPCapabilities->WakeUpCapabilities;\r
793         pPMstruct->MinMagicPacketWakeUp = NdisDeviceStateUnspecified;\r
794         pPMstruct->MinPatternWakeUp = NdisDeviceStateUnspecified;\r
795         pPMstruct->MinLinkChangeWakeUp = NdisDeviceStateUnspecified;\r
796         *pAdapt->BytesReadOrWritten = sizeof(NDIS_PNP_CAPABILITIES);\r
797         *pAdapt->BytesNeeded = 0;\r
798 \r
799 \r
800         //\r
801         // Setting our internal flags\r
802         // Default, device is ON\r
803         //\r
804         pAdapt->MPDeviceState = NdisDeviceStateD0;\r
805         pAdapt->PTDeviceState = NdisDeviceStateD0;\r
806 \r
807         *pStatus = NDIS_STATUS_SUCCESS;\r
808     }\r
809     else\r
810     {\r
811         *pAdapt->BytesNeeded= sizeof(NDIS_PNP_CAPABILITIES);\r
812         *pStatus = NDIS_STATUS_RESOURCES;\r
813     }\r
814 }\r
815 \r
816 \r
817 NDIS_STATUS\r
818 MPSetInformation(\r
819     IN NDIS_HANDLE                                  MiniportAdapterContext,\r
820     IN NDIS_OID                                     Oid,\r
821     __in_bcount(InformationBufferLength) IN PVOID   InformationBuffer,\r
822     IN ULONG                                        InformationBufferLength,\r
823     OUT PULONG                                      BytesRead,\r
824     OUT PULONG                                      BytesNeeded\r
825     )\r
826 /*++\r
827 \r
828 Routine Description:\r
829 \r
830     Miniport SetInfo handler.\r
831 \r
832     In the case of OID_PNP_SET_POWER, record the power state and return the OID.    \r
833     Do not pass below\r
834     If the device is suspended, do not block the SET_POWER_OID \r
835     as it is used to reactivate the Passthru miniport\r
836 \r
837     \r
838     PM- If the MP is not ON (DeviceState > D0) return immediately  (except for 'query power' and 'set power')\r
839          If MP is ON, but the PT is not at D0, then queue the queue the request for later processing\r
840 \r
841     Requests to miniports are always serialized\r
842 \r
843 \r
844 Arguments:\r
845 \r
846     MiniportAdapterContext    Pointer to the adapter structure\r
847     Oid                       Oid for this query\r
848     InformationBuffer         Buffer for information\r
849     InformationBufferLength   Size of this buffer\r
850     BytesRead                 Specifies how much info is read\r
851     BytesNeeded               In case the buffer is smaller than what we need, tell them how much is needed\r
852 \r
853 Return Value:\r
854 \r
855     Return code from the NdisRequest below.\r
856 \r
857 --*/\r
858 {\r
859     PADAPT        pAdapt = (PADAPT)MiniportAdapterContext;\r
860     NDIS_STATUS   Status;\r
861 \r
862     Status = NDIS_STATUS_FAILURE;\r
863 \r
864     do\r
865     {\r
866         //\r
867         // The Set Power should not be sent to the miniport below the Passthru, but is handled internally\r
868         //\r
869         if (Oid == OID_PNP_SET_POWER)\r
870         {\r
871             MPProcessSetPowerOid(&Status, \r
872                                  pAdapt, \r
873                                  InformationBuffer, \r
874                                  InformationBufferLength, \r
875                                  BytesRead, \r
876                                  BytesNeeded);\r
877             break;\r
878 \r
879         }\r
880 \r
881         //\r
882         // If the miniport below is unbinding, fail the request\r
883         //\r
884         NdisAcquireSpinLock(&pAdapt->Lock);     \r
885         if (pAdapt->UnbindingInProcess == TRUE)\r
886         {\r
887             NdisReleaseSpinLock(&pAdapt->Lock);\r
888             Status = NDIS_STATUS_FAILURE;\r
889             break;\r
890         }\r
891         NdisReleaseSpinLock(&pAdapt->Lock);\r
892         //\r
893         // All other Set Information requests are failed, if the miniport is\r
894         // not at D0 or is transitioning to a device state greater than D0.\r
895         //\r
896         if (pAdapt->MPDeviceState > NdisDeviceStateD0)\r
897         {\r
898             Status = NDIS_STATUS_FAILURE;\r
899             break;\r
900         }\r
901 \r
902         // Set up the Request and return the result\r
903         pAdapt->Request.RequestType = NdisRequestSetInformation;\r
904         pAdapt->Request.DATA.SET_INFORMATION.Oid = Oid;\r
905         pAdapt->Request.DATA.SET_INFORMATION.InformationBuffer = InformationBuffer;\r
906         pAdapt->Request.DATA.SET_INFORMATION.InformationBufferLength = InformationBufferLength;\r
907         pAdapt->BytesNeeded = BytesNeeded;\r
908         pAdapt->BytesReadOrWritten = BytesRead;\r
909 \r
910         //\r
911         // If the miniport below is unbinding, fail the request\r
912         //\r
913         NdisAcquireSpinLock(&pAdapt->Lock);     \r
914         if (pAdapt->UnbindingInProcess == TRUE)\r
915         {\r
916             NdisReleaseSpinLock(&pAdapt->Lock);\r
917             Status = NDIS_STATUS_FAILURE;\r
918             break;\r
919         }\r
920             \r
921         //\r
922         // If the device below is at a low power state, we cannot send it the\r
923         // request now, and must pend it.\r
924         //\r
925         if ((pAdapt->PTDeviceState > NdisDeviceStateD0) \r
926                 && (pAdapt->StandingBy == FALSE))\r
927         {\r
928             pAdapt->QueuedRequest = TRUE;\r
929             NdisReleaseSpinLock(&pAdapt->Lock);\r
930             Status = NDIS_STATUS_PENDING;\r
931             break;\r
932         }\r
933         //\r
934         // This is in the process of powering down the system, always fail the request\r
935         // \r
936         if (pAdapt->StandingBy == TRUE)\r
937         {\r
938             NdisReleaseSpinLock(&pAdapt->Lock);\r
939             Status = NDIS_STATUS_FAILURE;\r
940             break;\r
941         }\r
942         pAdapt->OutstandingRequests = TRUE;\r
943         \r
944         NdisReleaseSpinLock(&pAdapt->Lock);\r
945         //\r
946         // Forward the request to the device below.\r
947         //\r
948         NdisRequest(&Status,\r
949                     pAdapt->BindingHandle,\r
950                     &pAdapt->Request);\r
951 \r
952         if (Status != NDIS_STATUS_PENDING)\r
953         {\r
954             *BytesRead = pAdapt->Request.DATA.SET_INFORMATION.BytesRead;\r
955             *BytesNeeded = pAdapt->Request.DATA.SET_INFORMATION.BytesNeeded;\r
956             pAdapt->OutstandingRequests = FALSE;\r
957         }\r
958 \r
959     } while (FALSE);\r
960 \r
961     return(Status);\r
962 }\r
963 \r
964 \r
965 VOID\r
966 MPProcessSetPowerOid(\r
967     IN OUT PNDIS_STATUS                             pNdisStatus,\r
968     IN PADAPT                                       pAdapt,\r
969     __in_bcount(InformationBufferLength) IN PVOID   InformationBuffer,\r
970     IN ULONG                                        InformationBufferLength,\r
971     OUT PULONG                                      BytesRead,\r
972     OUT PULONG                                      BytesNeeded\r
973     )\r
974 /*++\r
975 \r
976 Routine Description:\r
977     This routine does all the procssing for a request with a SetPower Oid\r
978     The miniport shoud accept  the Set Power and transition to the new state\r
979 \r
980     The Set Power should not be passed to the miniport below\r
981 \r
982     If the IM miniport is going into a low power state, then there is no guarantee if it will ever\r
983     be asked go back to D0, before getting halted. No requests should be pended or queued.\r
984 \r
985     \r
986 Arguments:\r
987     pNdisStatus           - Status of the operation\r
988     pAdapt                - The Adapter structure\r
989     InformationBuffer     - The New DeviceState\r
990     InformationBufferLength\r
991     BytesRead             - No of bytes read\r
992     BytesNeeded           -  No of bytes needed\r
993 \r
994 \r
995 Return Value:\r
996     Status  - NDIS_STATUS_SUCCESS if all the wait events succeed.\r
997 \r
998 --*/\r
999 {\r
1000 \r
1001     \r
1002     NDIS_DEVICE_POWER_STATE NewDeviceState;\r
1003 \r
1004     DBGPRINT(("==>MPProcessSetPowerOid: Adapt %p\n", pAdapt)); \r
1005 \r
1006     ASSERT (InformationBuffer != NULL);\r
1007 \r
1008     *pNdisStatus = NDIS_STATUS_FAILURE;\r
1009 \r
1010     do \r
1011     {\r
1012         //\r
1013         // Check for invalid length\r
1014         //\r
1015         if (InformationBufferLength < sizeof(NDIS_DEVICE_POWER_STATE))\r
1016         {\r
1017             *pNdisStatus = NDIS_STATUS_INVALID_LENGTH;\r
1018             break;\r
1019         }\r
1020 \r
1021         NewDeviceState = (*(PNDIS_DEVICE_POWER_STATE)InformationBuffer);\r
1022 \r
1023         //\r
1024         // Check for invalid device state\r
1025         //\r
1026         if ((pAdapt->MPDeviceState > NdisDeviceStateD0) && (NewDeviceState != NdisDeviceStateD0))\r
1027         {\r
1028             //\r
1029             // If the miniport is in a non-D0 state, the miniport can only receive a Set Power to D0\r
1030             //\r
1031             ASSERT (!(pAdapt->MPDeviceState > NdisDeviceStateD0) && (NewDeviceState != NdisDeviceStateD0));\r
1032 \r
1033             *pNdisStatus = NDIS_STATUS_FAILURE;\r
1034             break;\r
1035         }    \r
1036 \r
1037         //\r
1038         // Is the miniport transitioning from an On (D0) state to an Low Power State (>D0)\r
1039         // If so, then set the StandingBy Flag - (Block all incoming requests)\r
1040         //\r
1041         if (pAdapt->MPDeviceState == NdisDeviceStateD0 && NewDeviceState > NdisDeviceStateD0)\r
1042         {\r
1043             pAdapt->StandingBy = TRUE;\r
1044         }\r
1045 \r
1046         //\r
1047         // If the miniport is transitioning from a low power state to ON (D0), then clear the StandingBy flag\r
1048         // All incoming requests will be pended until the physical miniport turns ON.\r
1049         //\r
1050         if (pAdapt->MPDeviceState > NdisDeviceStateD0 &&  NewDeviceState == NdisDeviceStateD0)\r
1051         {\r
1052             pAdapt->StandingBy = FALSE;\r
1053         }\r
1054         \r
1055         //\r
1056         // Now update the state in the pAdapt structure;\r
1057         //\r
1058         pAdapt->MPDeviceState = NewDeviceState;\r
1059         \r
1060         *pNdisStatus = NDIS_STATUS_SUCCESS;\r
1061     \r
1062 \r
1063     } while (FALSE);    \r
1064         \r
1065     if (*pNdisStatus == NDIS_STATUS_SUCCESS)\r
1066     {\r
1067         //\r
1068         // The miniport resume from low power state\r
1069         // \r
1070         if (pAdapt->StandingBy == FALSE)\r
1071         {\r
1072             //\r
1073             // If we need to indicate the media connect state\r
1074             // \r
1075             if (pAdapt->LastIndicatedStatus != pAdapt->LatestUnIndicateStatus)\r
1076             {\r
1077                if (pAdapt->MiniportHandle != NULL)\r
1078                {\r
1079                    NdisMIndicateStatus(pAdapt->MiniportHandle,\r
1080                                             pAdapt->LatestUnIndicateStatus,\r
1081                                             (PVOID)NULL,\r
1082                                             0);\r
1083                    NdisMIndicateStatusComplete(pAdapt->MiniportHandle);\r
1084                    pAdapt->LastIndicatedStatus = pAdapt->LatestUnIndicateStatus;\r
1085                }\r
1086             }\r
1087         }\r
1088         else\r
1089         {\r
1090             //\r
1091             // Initialize LatestUnIndicatedStatus\r
1092             //\r
1093             pAdapt->LatestUnIndicateStatus = pAdapt->LastIndicatedStatus;\r
1094         }\r
1095         *BytesRead = sizeof(NDIS_DEVICE_POWER_STATE);\r
1096         *BytesNeeded = 0;\r
1097     }\r
1098     else\r
1099     {\r
1100         *BytesRead = 0;\r
1101         *BytesNeeded = sizeof (NDIS_DEVICE_POWER_STATE);\r
1102     }\r
1103 \r
1104     DBGPRINT(("<==MPProcessSetPowerOid: Adapt %p\n", pAdapt)); \r
1105 }\r
1106 \r
1107 \r
1108 VOID\r
1109 MPReturnPacket(\r
1110     IN NDIS_HANDLE             MiniportAdapterContext,\r
1111     IN PNDIS_PACKET            Packet\r
1112     )\r
1113 /*++\r
1114 \r
1115 Routine Description:\r
1116 \r
1117     NDIS Miniport entry point called whenever protocols are done with\r
1118     a packet that we had indicated up and they had queued up for returning\r
1119     later.\r
1120 \r
1121 Arguments:\r
1122 \r
1123     MiniportAdapterContext    - pointer to ADAPT structure\r
1124     Packet    - packet being returned.\r
1125 \r
1126 Return Value:\r
1127 \r
1128     None.\r
1129 \r
1130 --*/\r
1131 {\r
1132     PADAPT            pAdapt = (PADAPT)MiniportAdapterContext;\r
1133 \r
1134 #ifdef NDIS51\r
1135     //\r
1136     // Packet stacking: Check if this packet belongs to us.\r
1137     //\r
1138     if (NdisGetPoolFromPacket(Packet) != pAdapt->RecvPacketPoolHandle)\r
1139     {\r
1140         //\r
1141         // We reused the original packet in a receive indication.\r
1142         // Simply return it to the miniport below us.\r
1143         //\r
1144         NdisReturnPackets(&Packet, 1);\r
1145     }\r
1146     else\r
1147 #endif // NDIS51\r
1148     {\r
1149         //\r
1150         // This is a packet allocated from this IM's receive packet pool.\r
1151         // Reclaim our packet, and return the original to the driver below.\r
1152         //\r
1153 \r
1154         PNDIS_PACKET    MyPacket;\r
1155         PRECV_RSVD      RecvRsvd;\r
1156     \r
1157         RecvRsvd = (PRECV_RSVD)(Packet->MiniportReserved);\r
1158         MyPacket = RecvRsvd->OriginalPkt;\r
1159     \r
1160         NdisFreePacket(Packet);\r
1161         NdisReturnPackets(&MyPacket, 1);\r
1162     }\r
1163 }\r
1164 \r
1165 \r
1166 NDIS_STATUS\r
1167 MPTransferData(\r
1168     OUT PNDIS_PACKET            Packet,\r
1169     OUT PUINT                   BytesTransferred,\r
1170     IN NDIS_HANDLE              MiniportAdapterContext,\r
1171     IN NDIS_HANDLE              MiniportReceiveContext,\r
1172     IN UINT                     ByteOffset,\r
1173     IN UINT                     BytesToTransfer\r
1174     )\r
1175 /*++\r
1176 \r
1177 Routine Description:\r
1178 \r
1179     Miniport's transfer data handler.\r
1180 \r
1181 Arguments:\r
1182 \r
1183     Packet                    Destination packet\r
1184     BytesTransferred          Place-holder for how much data was copied\r
1185     MiniportAdapterContext    Pointer to the adapter structure\r
1186     MiniportReceiveContext    Context\r
1187     ByteOffset                Offset into the packet for copying data\r
1188     BytesToTransfer           How much to copy.\r
1189 \r
1190 Return Value:\r
1191 \r
1192     Status of transfer\r
1193 \r
1194 --*/\r
1195 {\r
1196     PADAPT        pAdapt = (PADAPT)MiniportAdapterContext;\r
1197     NDIS_STATUS   Status;\r
1198 \r
1199     //\r
1200     // Return, if the device is OFF\r
1201     //\r
1202 \r
1203     if (IsIMDeviceStateOn(pAdapt) == FALSE)\r
1204     {\r
1205         return NDIS_STATUS_FAILURE;\r
1206     }\r
1207 \r
1208     NdisTransferData(&Status,\r
1209                      pAdapt->BindingHandle,\r
1210                      MiniportReceiveContext,\r
1211                      ByteOffset,\r
1212                      BytesToTransfer,\r
1213                      Packet,\r
1214                      BytesTransferred);\r
1215 \r
1216     return(Status);\r
1217 }\r
1218 \r
1219 VOID\r
1220 MPHalt(\r
1221     IN NDIS_HANDLE                MiniportAdapterContext\r
1222     )\r
1223 /*++\r
1224 \r
1225 Routine Description:\r
1226 \r
1227     Halt handler. All the hard-work for clean-up is done here.\r
1228 \r
1229 Arguments:\r
1230 \r
1231     MiniportAdapterContext    Pointer to the Adapter\r
1232 \r
1233 Return Value:\r
1234 \r
1235     None.\r
1236 \r
1237 --*/\r
1238 {\r
1239     PADAPT             pAdapt = (PADAPT)MiniportAdapterContext;\r
1240     NDIS_STATUS        Status;\r
1241     PADAPT            *ppCursor;\r
1242 \r
1243     DBGPRINT(("==>MiniportHalt: Adapt %p\n", pAdapt));\r
1244 \r
1245     pAdapt->MiniportHandle = NULL;\r
1246     pAdapt->MiniportIsHalted = TRUE;\r
1247 \r
1248     //\r
1249     // Remove this adapter from the global list\r
1250     //\r
1251     NdisAcquireSpinLock(&GlobalLock);\r
1252 \r
1253     for (ppCursor = &pAdaptList; *ppCursor != NULL; ppCursor = &(*ppCursor)->Next)\r
1254     {\r
1255         if (*ppCursor == pAdapt)\r
1256         {\r
1257             *ppCursor = pAdapt->Next;\r
1258             break;\r
1259         }\r
1260     }\r
1261 \r
1262     NdisReleaseSpinLock(&GlobalLock);\r
1263 \r
1264     //\r
1265     // Delete the ioctl interface that was created when the miniport\r
1266     // was created.\r
1267     //\r
1268     (VOID)PtDeregisterDevice();\r
1269 \r
1270     //\r
1271     // If we have a valid bind, close the miniport below the protocol\r
1272     //\r
1273 #pragma prefast(suppress: __WARNING_DEREF_NULL_PTR, "pAdapt cannot be NULL")\r
1274     if (pAdapt->BindingHandle != NULL)\r
1275     {\r
1276         //\r
1277         // Close the binding below. and wait for it to complete\r
1278         //\r
1279         NdisResetEvent(&pAdapt->Event);\r
1280 \r
1281         NdisCloseAdapter(&Status, pAdapt->BindingHandle);\r
1282 \r
1283         if (Status == NDIS_STATUS_PENDING)\r
1284         {\r
1285             NdisWaitEvent(&pAdapt->Event, 0);\r
1286             Status = pAdapt->Status;\r
1287         }\r
1288 \r
1289         ASSERT (Status == NDIS_STATUS_SUCCESS);\r
1290 \r
1291         pAdapt->BindingHandle = NULL;\r
1292         \r
1293         PtDereferenceAdapt(pAdapt);\r
1294     }\r
1295 \r
1296     if (PtDereferenceAdapt(pAdapt))\r
1297     {\r
1298         pAdapt = NULL;\r
1299     }\r
1300         \r
1301     \r
1302     DBGPRINT(("<== MiniportHalt: pAdapt %p\n", pAdapt));\r
1303 }\r
1304 \r
1305 \r
1306 #ifdef NDIS51_MINIPORT\r
1307 \r
1308 VOID\r
1309 MPCancelSendPackets(\r
1310     IN NDIS_HANDLE            MiniportAdapterContext,\r
1311     IN PVOID                  CancelId\r
1312     )\r
1313 /*++\r
1314 \r
1315 Routine Description:\r
1316 \r
1317     The miniport entry point to handle cancellation of all send packets\r
1318     that match the given CancelId. If we have queued any packets that match\r
1319     this, then we should dequeue them and call NdisMSendComplete for all\r
1320     such packets, with a status of NDIS_STATUS_REQUEST_ABORTED.\r
1321 \r
1322     We should also call NdisCancelSendPackets in turn, on each lower binding\r
1323     that this adapter corresponds to. This is to let miniports below cancel\r
1324     any matching packets.\r
1325 \r
1326 Arguments:\r
1327 \r
1328     MiniportAdapterContext    - pointer to ADAPT structure\r
1329     CancelId    - ID of packets to be cancelled.\r
1330 \r
1331 Return Value:\r
1332 \r
1333     None\r
1334 \r
1335 --*/\r
1336 {\r
1337     PADAPT    pAdapt = (PADAPT)MiniportAdapterContext;\r
1338 \r
1339     //\r
1340     // If we queue packets on our adapter structure, this would be \r
1341     // the place to acquire a spinlock to it, unlink any packets whose\r
1342     // Id matches CancelId, release the spinlock and call NdisMSendComplete\r
1343     // with NDIS_STATUS_REQUEST_ABORTED for all unlinked packets.\r
1344     //\r
1345 \r
1346     //\r
1347     // Next, pass this down so that we let the miniport(s) below cancel\r
1348     // any packets that they might have queued.\r
1349     //\r
1350     NdisCancelSendPackets(pAdapt->BindingHandle, CancelId);\r
1351 \r
1352     return;\r
1353 }\r
1354 \r
1355 VOID\r
1356 MPDevicePnPEvent(\r
1357     IN NDIS_HANDLE              MiniportAdapterContext,\r
1358     IN NDIS_DEVICE_PNP_EVENT    DevicePnPEvent,\r
1359     IN PVOID                    InformationBuffer,\r
1360     IN ULONG                    InformationBufferLength\r
1361     )\r
1362 /*++\r
1363 \r
1364 Routine Description:\r
1365 \r
1366     This handler is called to notify us of PnP events directed to\r
1367     our miniport device object.\r
1368 \r
1369 Arguments:\r
1370 \r
1371     MiniportAdapterContext    - pointer to ADAPT structure\r
1372     DevicePnPEvent - the event\r
1373     InformationBuffer - Points to additional event-specific information\r
1374     InformationBufferLength - length of above\r
1375 \r
1376 Return Value:\r
1377 \r
1378     None\r
1379 --*/\r
1380 {\r
1381     // TBD - add code/comments about processing this.\r
1382 \r
1383     UNREFERENCED_PARAMETER(MiniportAdapterContext);\r
1384     UNREFERENCED_PARAMETER(DevicePnPEvent);\r
1385     UNREFERENCED_PARAMETER(InformationBuffer);\r
1386     UNREFERENCED_PARAMETER(InformationBufferLength);\r
1387     \r
1388     return;\r
1389 }\r
1390 \r
1391 VOID\r
1392 MPAdapterShutdown(\r
1393     IN NDIS_HANDLE                MiniportAdapterContext\r
1394     )\r
1395 /*++\r
1396 \r
1397 Routine Description:\r
1398 \r
1399     This handler is called to notify us of an impending system shutdown.\r
1400 \r
1401 Arguments:\r
1402 \r
1403     MiniportAdapterContext    - pointer to ADAPT structure\r
1404 \r
1405 Return Value:\r
1406 \r
1407     None\r
1408 --*/\r
1409 {\r
1410     UNREFERENCED_PARAMETER(MiniportAdapterContext);\r
1411     \r
1412     return;\r
1413 }\r
1414 \r
1415 #endif\r
1416 \r
1417 \r
1418 VOID\r
1419 MPFreeAllPacketPools(\r
1420     IN PADAPT                    pAdapt\r
1421     )\r
1422 /*++\r
1423 \r
1424 Routine Description:\r
1425 \r
1426     Free all packet pools on the specified adapter.\r
1427     \r
1428 Arguments:\r
1429 \r
1430     pAdapt    - pointer to ADAPT structure\r
1431 \r
1432 Return Value:\r
1433 \r
1434     None\r
1435 \r
1436 --*/\r
1437 {\r
1438     if (pAdapt->RecvPacketPoolHandle != NULL)\r
1439     {\r
1440         //\r
1441         // Free the packet pool that is used to indicate receives\r
1442         //\r
1443         NdisFreePacketPool(pAdapt->RecvPacketPoolHandle);\r
1444 \r
1445         pAdapt->RecvPacketPoolHandle = NULL;\r
1446     }\r
1447 \r
1448     if (pAdapt->SendPacketPoolHandle != NULL)\r
1449     {\r
1450 \r
1451         //\r
1452         //  Free the packet pool that is used to send packets below\r
1453         //\r
1454 \r
1455         NdisFreePacketPool(pAdapt->SendPacketPoolHandle);\r
1456 \r
1457         pAdapt->SendPacketPoolHandle = NULL;\r
1458 \r
1459     }\r
1460 }\r
1461 \r