Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

757 lines
20 KiB

  1. /*++
  2. Copyright (c) 1990-1995 Microsoft Corporation
  3. Module Name:
  4. Miniport.c
  5. Abstract:
  6. This file contains the procedures that makeup most of the NDIS 3.1
  7. Miniport interface.
  8. Author:
  9. Tony Bell (TonyBe) June 06, 1995
  10. Environment:
  11. Kernel Mode
  12. Revision History:
  13. TonyBe 06/06/95 Created
  14. --*/
  15. #include "wan.h"
  16. #define __FILE_SIG__ MINIPORT_FILESIG
  17. //
  18. // Local function prototypes
  19. //
  20. //
  21. // End local function prototypes
  22. //
  23. VOID
  24. MPHalt(
  25. IN NDIS_HANDLE MiniportAdapterContext
  26. )
  27. /*++
  28. Routine Name:
  29. MPHalt
  30. Routine Description:
  31. This routine free's all resources for the adapter.
  32. Arguments:
  33. MiniportAdapterContext - AdapterContext that is given to the wrapper in
  34. NdisMSetAttributes call. Is our MiniportCB.
  35. Return Values:
  36. None
  37. --*/
  38. {
  39. PMINIPORTCB MiniportCB = (PMINIPORTCB)MiniportAdapterContext;
  40. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPHalt: Enter"));
  41. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MiniportCB: 0x%x", MiniportCB));
  42. //
  43. // Make sure that there are no ProtocolCB's
  44. // running over this miniport! If so we
  45. // need to do a linedown to them.
  46. //
  47. NdisAcquireSpinLock(&MiniportCB->Lock);
  48. MiniportCB->Flags |= HALT_IN_PROGRESS;
  49. while (!IsListEmpty(&MiniportCB->ProtocolCBList)) {
  50. PLIST_ENTRY le;
  51. PPROTOCOLCB ProtocolCB;
  52. PBUNDLECB BundleCB;
  53. ProtocolState OldState;
  54. le = MiniportCB->ProtocolCBList.Flink;
  55. ProtocolCB =(PPROTOCOLCB)
  56. CONTAINING_RECORD(le, PROTOCOLCB, MiniportLinkage);
  57. NdisReleaseSpinLock(&MiniportCB->Lock);
  58. BundleCB = ProtocolCB->BundleCB;
  59. AcquireBundleLock(BundleCB);
  60. OldState = ProtocolCB->State;
  61. ProtocolCB->State = PROTOCOL_UNROUTING;
  62. BundleCB->SendMask &= ~ProtocolCB->SendMaskBit;
  63. //
  64. // Flush the protocol packet queues. This could cause us
  65. // to complete frames to ndis out of order. Ndis should
  66. // handle this.
  67. //
  68. FlushProtocolPacketQueue(ProtocolCB);
  69. //
  70. // If the protocols refcount goes to zero
  71. // we need to do a linedown and cleanup
  72. //
  73. if ((--ProtocolCB->RefCount == 0) &&
  74. (OldState == PROTOCOL_ROUTED)) {
  75. DoLineDownToProtocol(ProtocolCB);
  76. //
  77. // Returns with bundlecb->lock released
  78. //
  79. RemoveProtocolCBFromBundle(ProtocolCB);
  80. ReleaseBundleLock(BundleCB);
  81. NdisWanFreeProtocolCB(ProtocolCB);
  82. } else {
  83. ReleaseBundleLock(BundleCB);
  84. NdisWanWaitForSyncEvent(&MiniportCB->HaltEvent);
  85. NdisWanClearSyncEvent(&MiniportCB->HaltEvent);
  86. }
  87. NdisAcquireSpinLock(&MiniportCB->Lock);
  88. }
  89. NdisReleaseSpinLock(&MiniportCB->Lock);
  90. DEREF_MINIPORTCB(MiniportCB);
  91. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPHalt: Exit"));
  92. }
  93. NDIS_STATUS
  94. MPInitialize(
  95. OUT PNDIS_STATUS OpenErrorStatus,
  96. OUT PUINT SelectedMediumIndex,
  97. IN PNDIS_MEDIUM MediumArray,
  98. IN UINT MediumArraySize,
  99. IN NDIS_HANDLE MiniportAdapterHandle,
  100. IN NDIS_HANDLE WrapperConfigurationContext
  101. )
  102. /*++
  103. Routine Name:
  104. MPInitialize
  105. Routine Description:
  106. This routine is called after NdisWan registers itself as a Miniport driver.
  107. It is responsible for installing NdisWan as a Miniport driver, creating
  108. adapter control blocks for each adapter NdisWan exposes (should only be 1),
  109. and initializing all adapter specific variables
  110. Arguments:
  111. OpenErrorStatus - Returns information about the error if this function
  112. returns NDIS_STATUS_OPEN_ERROR. Used for TokenRing.
  113. SelectedMediumIndex - An index into the MediumArray that specifies the
  114. medium type of this driver. Should be WAN or 802.3
  115. MediumArray - An array of medium types supported by the NDIS library
  116. MediumArraySize - Size of the medium array
  117. MiniportAdapterHandle - Handle assigned by the NDIS library that defines
  118. this miniport driver. Used as handle in subsequent
  119. calls to the NDIS library.
  120. WrapperConfigurationContext - Handle used to read configuration information
  121. from the registry
  122. Return Values:
  123. NDIS_STATUS_ADAPTER_NOT_FOUND
  124. NDIS_STATUS_FAILURE
  125. NDIS_STATUS_NOT_ACCEPTED
  126. NDIS_STATUS_OPEN_ERROR
  127. NDIS_STATUS_RESOURCES
  128. NDIS_STATUS_UNSUPPORTED_MEDIA
  129. --*/
  130. {
  131. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  132. PMINIPORTCB MiniportCB;
  133. UINT Index;
  134. NDIS_HANDLE ConfigHandle;
  135. ULONG NetworkAddressLength;
  136. #ifdef NT
  137. LARGE_INTEGER TickCount, SystemTime;
  138. #endif
  139. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPInitialize: Enter"));
  140. //
  141. // We have to be type 802.3 to the ndis wrapper, but the
  142. // wrapper will expose us to the transports as type wan.
  143. //
  144. for (Index = 0; Index < MediumArraySize; Index++) {
  145. if (MediumArray[Index] == NdisMedium802_3) {
  146. break;
  147. }
  148. }
  149. //
  150. // We don't have a match so we are screwed
  151. //
  152. if (Index == MediumArraySize) {
  153. return (NDIS_STATUS_UNSUPPORTED_MEDIA);
  154. }
  155. *SelectedMediumIndex = Index;
  156. //
  157. // Allocate and initialize miniport adapter structure
  158. //
  159. #ifdef MINIPORT_NAME
  160. MiniportCB = NdisWanAllocateMiniportCB(&((PNDIS_MINIPORT_BLOCK)(MiniportAdapterHandle))->MiniportName);
  161. #else
  162. MiniportCB = NdisWanAllocateMiniportCB(NULL);
  163. #endif
  164. if (MiniportCB == NULL) {
  165. NdisWanDbgOut(DBG_CRITICAL_ERROR, DBG_MINIPORT,
  166. ("Error Creating MiniportCB!"));
  167. return (NDIS_STATUS_FAILURE);
  168. }
  169. #ifndef MY_DEVICE_OBJECT
  170. if (NdisWanCB.pDeviceObject == NULL) {
  171. PDRIVER_DISPATCH DispatchTable[IRP_MJ_MAXIMUM_FUNCTION+1];
  172. NDIS_STRING SymbolicName = NDIS_STRING_CONST("\\DosDevices\\NdisWan");
  173. NDIS_STRING Name = NDIS_STRING_CONST("\\Device\\NdisWan");
  174. ULONG i;
  175. NTSTATUS retStatus;
  176. for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) {
  177. DispatchTable[i] = NdisWanIrpStub;
  178. }
  179. DispatchTable[IRP_MJ_CREATE] = NdisWanCreate;
  180. DispatchTable[IRP_MJ_DEVICE_CONTROL] = NdisWanIoctl;
  181. DispatchTable[IRP_MJ_CLEANUP] = NdisWanCleanup;
  182. retStatus =
  183. NdisMRegisterDevice(NdisWanCB.NdisWrapperHandle,
  184. &Name,
  185. &SymbolicName,
  186. DispatchTable,
  187. &NdisWanCB.pDeviceObject,
  188. &NdisWanCB.DeviceHandle);
  189. if (retStatus == STATUS_SUCCESS) {
  190. NdisWanCB.pDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
  191. } else {
  192. NdisWanCB.pDeviceObject = NULL;
  193. }
  194. }
  195. #endif
  196. NdisMSetAttributesEx(MiniportAdapterHandle,
  197. MiniportCB,
  198. (UINT)-1,
  199. //
  200. // KyleB says that the following two defines are redundant if
  201. // the miniport is deserialized.
  202. //
  203. // NDIS_ATTRIBUTE_IGNORE_PACKET_TIMEOUT |
  204. // NDIS_ATTRIBUTE_INTERMEDIATE_DRIVER |
  205. NDIS_ATTRIBUTE_IGNORE_REQUEST_TIMEOUT |
  206. NDIS_ATTRIBUTE_DESERIALIZE |
  207. NDIS_ATTRIBUTE_NO_HALT_ON_SUSPEND,
  208. NdisInterfaceInternal);
  209. MiniportCB->MediumType = MediumArray[Index];
  210. MiniportCB->RefCount = 0;
  211. MiniportCB->MiniportHandle = MiniportAdapterHandle;
  212. //
  213. // Read per miniport instance data
  214. //
  215. NdisOpenConfiguration(&Status,
  216. &ConfigHandle,
  217. WrapperConfigurationContext);
  218. if (Status == NDIS_STATUS_SUCCESS) {
  219. NdisReadNetworkAddress(&Status,
  220. (PVOID*)&(MiniportCB->NetworkAddress),
  221. &NetworkAddressLength,
  222. ConfigHandle);
  223. NdisCloseConfiguration(ConfigHandle);
  224. if (Status != NDIS_STATUS_SUCCESS ||
  225. NetworkAddressLength != ETH_LENGTH_OF_ADDRESS) {
  226. goto BuildAddress;
  227. }
  228. } else {
  229. BuildAddress:
  230. #ifdef NT
  231. KeQueryTickCount(&TickCount);
  232. KeQuerySystemTime(&SystemTime);
  233. MiniportCB->NetworkAddress[0] = (UCHAR)((TickCount.LowPart >> 16) ^
  234. (SystemTime.LowPart >> 16)) &
  235. 0xFE;
  236. MiniportCB->NetworkAddress[1] = (UCHAR)((TickCount.LowPart >> 8) ^
  237. (SystemTime.LowPart >> 8));
  238. //
  239. // The following 4 bytes will be filled in at lineup time
  240. //
  241. MiniportCB->NetworkAddress[2] = ' ';
  242. MiniportCB->NetworkAddress[3] = 'R';
  243. MiniportCB->NetworkAddress[4] = 'A';
  244. MiniportCB->NetworkAddress[5] = 'S';
  245. #endif
  246. }
  247. //
  248. // Register our connection manager address family for this
  249. // miniport
  250. //
  251. {
  252. CO_ADDRESS_FAMILY CoAddressFamily;
  253. NDIS_CALL_MANAGER_CHARACTERISTICS CmCharacteristics;
  254. NdisZeroMemory(&CmCharacteristics,
  255. sizeof(NDIS_CALL_MANAGER_CHARACTERISTICS));
  256. CoAddressFamily.AddressFamily = CO_ADDRESS_FAMILY_PPP;
  257. CoAddressFamily.MajorVersion = NDISWAN_MAJOR_VERSION;
  258. CoAddressFamily.MinorVersion = NDISWAN_MINOR_VERSION;
  259. CmCharacteristics.MajorVersion = NDISWAN_MAJOR_VERSION;
  260. CmCharacteristics.MinorVersion = NDISWAN_MINOR_VERSION;
  261. CmCharacteristics.CmCreateVcHandler = CmCreateVc;
  262. CmCharacteristics.CmDeleteVcHandler = CmDeleteVc;
  263. CmCharacteristics.CmOpenAfHandler = CmOpenAf;
  264. CmCharacteristics.CmCloseAfHandler = CmCloseAf;
  265. CmCharacteristics.CmRegisterSapHandler = CmRegisterSap;
  266. CmCharacteristics.CmDeregisterSapHandler = CmDeregisterSap;
  267. CmCharacteristics.CmMakeCallHandler = CmMakeCall;
  268. CmCharacteristics.CmCloseCallHandler = CmCloseCall;
  269. CmCharacteristics.CmIncomingCallCompleteHandler = CmIncomingCallComplete;
  270. CmCharacteristics.CmAddPartyHandler = NULL;
  271. CmCharacteristics.CmDropPartyHandler = NULL;
  272. CmCharacteristics.CmActivateVcCompleteHandler = CmActivateVcComplete;
  273. CmCharacteristics.CmDeactivateVcCompleteHandler = CmDeactivateVcComplete;
  274. CmCharacteristics.CmModifyCallQoSHandler = CmModifyCallQoS;
  275. CmCharacteristics.CmRequestHandler = CmRequest;
  276. CmCharacteristics.CmRequestCompleteHandler = ProtoCoRequestComplete;
  277. NdisMCmRegisterAddressFamily(MiniportCB->MiniportHandle,
  278. &CoAddressFamily,
  279. &CmCharacteristics,
  280. sizeof(NDIS_CALL_MANAGER_CHARACTERISTICS));
  281. }
  282. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPInitialize: Exit"));
  283. REF_MINIPORTCB(MiniportCB);
  284. return (NDIS_STATUS_SUCCESS);
  285. }
  286. #if 0
  287. NDIS_STATUS
  288. MPQueryInformation(
  289. IN NDIS_HANDLE MiniportAdapterContext,
  290. IN NDIS_OID Oid,
  291. IN PVOID InformationBuffer,
  292. IN ULONG InformationBufferLength,
  293. OUT PULONG BytesWritten,
  294. OUT PULONG BytesNeeded
  295. )
  296. /*++
  297. Routine Name:
  298. Routine Description:
  299. Arguments:
  300. Return Values:
  301. --*/
  302. {
  303. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  304. PMINIPORTCB MiniportCB = (PMINIPORTCB)MiniportAdapterContext;
  305. NDIS_REQUEST NdisRequest;
  306. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPQueryInformation: Enter Oid: 0x%x", Oid));
  307. NdisWanInterlockedInc(&MiniportCB->RefCount);
  308. NdisRequest.RequestType =
  309. NdisRequestQueryInformation;
  310. NdisRequest.DATA.QUERY_INFORMATION.Oid =
  311. Oid;
  312. NdisRequest.DATA.QUERY_INFORMATION.InformationBuffer =
  313. InformationBuffer;
  314. NdisRequest.DATA.QUERY_INFORMATION.InformationBufferLength =
  315. InformationBufferLength;
  316. NdisRequest.DATA.QUERY_INFORMATION.BytesWritten =
  317. *BytesWritten;
  318. NdisRequest.DATA.QUERY_INFORMATION.BytesNeeded =
  319. *BytesNeeded;
  320. Status = NdisWanOidProc(MiniportCB, &NdisRequest);
  321. *BytesWritten = NdisRequest.DATA.QUERY_INFORMATION.BytesWritten;
  322. *BytesNeeded = NdisRequest.DATA.QUERY_INFORMATION.BytesNeeded;
  323. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPQueryInformation: Exit Status: %x", Status));
  324. NdisWanInterlockedDec(&MiniportCB->RefCount);
  325. return (Status);
  326. }
  327. #endif
  328. NDIS_STATUS
  329. MPReconfigure(
  330. OUT PNDIS_STATUS OpenErrorStatus,
  331. IN NDIS_HANDLE MiniportAdapterContext,
  332. IN NDIS_HANDLE WrapperConfigurationContext
  333. )
  334. /*++
  335. Routine Name:
  336. Routine Description:
  337. Arguments:
  338. Return Values:
  339. --*/
  340. {
  341. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  342. PMINIPORTCB MiniportCB = (PMINIPORTCB)MiniportAdapterContext;
  343. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPReconfigure: Enter"));
  344. NdisWanInterlockedInc(&MiniportCB->RefCount);
  345. NdisWanInterlockedDec(&MiniportCB->RefCount);
  346. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPReconfigure: Exit"));
  347. return (Status);
  348. }
  349. NDIS_STATUS
  350. MPReset(
  351. OUT PBOOLEAN AddressingReset,
  352. IN NDIS_HANDLE MiniportAdapterContext
  353. )
  354. /*++
  355. Routine Name:
  356. Routine Description:
  357. Arguments:
  358. Return Values:
  359. --*/
  360. {
  361. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  362. PMINIPORTCB MiniportCB = (PMINIPORTCB)MiniportAdapterContext;
  363. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPReset: Enter"));
  364. *AddressingReset = FALSE;
  365. NdisWanInterlockedInc(&MiniportCB->RefCount);
  366. NdisAcquireSpinLock(&MiniportCB->Lock);
  367. MiniportCB->Flags &= ~ASK_FOR_RESET;
  368. NdisReleaseSpinLock(&MiniportCB->Lock);
  369. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPReset: Exit"));
  370. NdisWanInterlockedDec(&MiniportCB->RefCount);
  371. return (Status);
  372. }
  373. #if 0
  374. NDIS_STATUS
  375. MPSetInformation(
  376. IN NDIS_HANDLE MiniportAdapterContext,
  377. IN NDIS_OID Oid,
  378. IN PVOID InformationBuffer,
  379. IN ULONG InformationBufferLength,
  380. OUT PULONG BytesWritten,
  381. OUT PULONG BytesNeeded
  382. )
  383. /*++
  384. Routine Name:
  385. Routine Description:
  386. Arguments:
  387. Return Values:
  388. --*/
  389. {
  390. NDIS_STATUS Status = NDIS_STATUS_SUCCESS;
  391. PMINIPORTCB MiniportCB = (PMINIPORTCB)MiniportAdapterContext;
  392. NDIS_REQUEST NdisRequest;
  393. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPSetInformation: Enter Oid: 0x%x", Oid));
  394. NdisWanInterlockedInc(&MiniportCB->RefCount);
  395. NdisRequest.RequestType =
  396. NdisRequestSetInformation;
  397. NdisRequest.DATA.SET_INFORMATION.Oid =
  398. Oid;
  399. NdisRequest.DATA.SET_INFORMATION.InformationBuffer =
  400. InformationBuffer;
  401. NdisRequest.DATA.SET_INFORMATION.InformationBufferLength =
  402. InformationBufferLength;
  403. NdisRequest.DATA.SET_INFORMATION.BytesRead =
  404. *BytesWritten;
  405. NdisRequest.DATA.SET_INFORMATION.BytesNeeded =
  406. *BytesNeeded;
  407. Status = NdisWanOidProc(MiniportCB, &NdisRequest);
  408. *BytesWritten = NdisRequest.DATA.SET_INFORMATION.BytesRead;
  409. *BytesNeeded = NdisRequest.DATA.SET_INFORMATION.BytesNeeded;
  410. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPSetInformation: Exit"));
  411. NdisWanInterlockedDec(&MiniportCB->RefCount);
  412. return (Status);
  413. }
  414. #endif
  415. VOID
  416. MPReturnPacket(
  417. IN NDIS_HANDLE MiniportAdapterContext,
  418. IN PNDIS_PACKET Packet
  419. )
  420. {
  421. PNDISWAN_PROTOCOL_RESERVED pres;
  422. PMINIPORTCB MiniportCB;
  423. PNDIS_BUFFER NdisBuffer;
  424. PRECV_DESC RecvDesc;
  425. NdisWanDbgOut(DBG_TRACE, DBG_RECEIVE, ("MPReturnPacket: Enter Packet %p", Packet));
  426. pres = PPROTOCOL_RESERVED_FROM_NDIS(Packet);
  427. MiniportCB = (PMINIPORTCB)MiniportAdapterContext;
  428. RecvDesc = pres->RecvDesc;
  429. REMOVE_DBG_RECV(PacketTypeNdis, MiniportCB, Packet);
  430. NdisWanFreeRecvDesc(RecvDesc);
  431. NdisWanDbgOut(DBG_TRACE, DBG_RECEIVE, ("MPReturnPacket: Exit"));
  432. }
  433. VOID
  434. MPSendPackets(
  435. IN NDIS_HANDLE MiniportAdapterContext,
  436. IN PPNDIS_PACKET PacketArray,
  437. IN UINT NumberOfPackets
  438. )
  439. {
  440. ULONG i;
  441. PMINIPORTCB MiniportCB = (PMINIPORTCB)MiniportAdapterContext;
  442. NdisWanDbgOut(DBG_TRACE, DBG_SEND, ("MPSendPackets: Enter"));
  443. for (i = 0; i < NumberOfPackets; i++) {
  444. PNDIS_PACKET NdisPacket = PacketArray[i];
  445. PMINIPORT_RESERVED_FROM_NDIS(NdisPacket)->CmVcCB = NULL;
  446. NdisWanQueueSend(MiniportCB,
  447. NdisPacket);
  448. }
  449. NdisWanDbgOut(DBG_TRACE, DBG_SEND, ("MPSendPackets: Exit"));
  450. }
  451. NDIS_STATUS
  452. MPCoCreateVc(
  453. IN NDIS_HANDLE MiniportAdapterContext,
  454. IN NDIS_HANDLE NdisVcHandle,
  455. OUT PNDIS_HANDLE MiniportVcContext
  456. )
  457. {
  458. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPCoCreateVc: Enter"));
  459. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPCoCreateVc: Exit"));
  460. return (NDIS_STATUS_SUCCESS);
  461. }
  462. NDIS_STATUS
  463. MPCoDeleteVc(
  464. IN NDIS_HANDLE MiniportVcContext
  465. )
  466. {
  467. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPCoDeleteVc: Enter"));
  468. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPCoDeleteVc: Exit"));
  469. return (NDIS_STATUS_SUCCESS);
  470. }
  471. NDIS_STATUS
  472. MPCoActivateVc(
  473. IN NDIS_HANDLE MiniportVcContext,
  474. IN OUT PCO_CALL_PARAMETERS CallParameters
  475. )
  476. {
  477. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPCoActivateVc: Enter"));
  478. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPCoActivateVc: Exit"));
  479. return (NDIS_STATUS_SUCCESS);
  480. }
  481. NDIS_STATUS
  482. MPCoDeactivateVc(
  483. IN NDIS_HANDLE MiniportVcContext
  484. )
  485. {
  486. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPCoDeactivateVc: Enter"));
  487. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPCoDeactivateVc: Exit"));
  488. return (NDIS_STATUS_SUCCESS);
  489. }
  490. VOID
  491. MPCoSendPackets(
  492. IN NDIS_HANDLE MiniportVcContext,
  493. IN PPNDIS_PACKET PacketArray,
  494. IN UINT NumberOfPackets
  495. )
  496. {
  497. ULONG i;
  498. PCM_VCCB CmVcCB = (PCM_VCCB)MiniportVcContext;
  499. PCM_AFSAPCB AfSapCB = CmVcCB->AfSapCB;
  500. PMINIPORTCB MiniportCB = AfSapCB->MiniportCB;
  501. NdisWanDbgOut(DBG_TRACE, DBG_SEND, ("MPCoSendPackets: Enter"));
  502. if (CmVcCB->State != CMVC_ACTIVE) {
  503. for (i = 0; i < NumberOfPackets; i++) {
  504. PNDIS_PACKET NdisPacket = PacketArray[i];
  505. NdisMCoSendComplete(NDIS_STATUS_FAILURE,
  506. CmVcCB->NdisVcHandle,
  507. NdisPacket);
  508. }
  509. return;
  510. }
  511. for (i = 0; i < NumberOfPackets; i++) {
  512. PNDIS_PACKET NdisPacket = PacketArray[i];
  513. REF_CMVCCB(CmVcCB);
  514. PMINIPORT_RESERVED_FROM_NDIS(NdisPacket)->CmVcCB = CmVcCB;
  515. NdisWanQueueSend(MiniportCB,
  516. NdisPacket);
  517. }
  518. NdisWanDbgOut(DBG_TRACE, DBG_SEND, ("MPCoSendPackets: Exit"));
  519. }
  520. NDIS_STATUS
  521. MPCoRequest(
  522. IN NDIS_HANDLE MiniportAdapterContext,
  523. IN NDIS_HANDLE MiniportVcContext OPTIONAL,
  524. IN OUT PNDIS_REQUEST NdisRequest
  525. )
  526. {
  527. NDIS_STATUS Status;
  528. PCM_VCCB CmVcCB;
  529. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPCoRequest: Enter Oid: 0x%x",
  530. NdisRequest->DATA.QUERY_INFORMATION.Oid));
  531. CmVcCB = (PCM_VCCB)MiniportVcContext;
  532. Status =
  533. NdisWanCoOidProc((PMINIPORTCB)MiniportAdapterContext,
  534. CmVcCB,
  535. NdisRequest);
  536. NdisWanDbgOut(DBG_TRACE, DBG_MINIPORT, ("MPCoRequest: Exit Status: 0x%x", Status));
  537. return (Status);
  538. }